Author: kp
Date: Thu Jun 18 20:57:21 2015
New Revision: 284576
URL: https://svnweb.freebsd.org/changeset/base/284576

Log:
  Merge r281234
  
  Evaluate packet size after the firewall had its chance
  
  Defer the packet size check until after the firewall has had a look at it. 
This
  means that the firewall now has the opportunity to (re-)fragment an oversized
  packet.
  
  Differential Revision:        https://reviews.freebsd.org/D2821
  Reviewed by:  gnn

Modified:
  stable/10/sys/netinet6/ip6_forward.c
Directory Properties:
  stable/10/   (props changed)

Modified: stable/10/sys/netinet6/ip6_forward.c
==============================================================================
--- stable/10/sys/netinet6/ip6_forward.c        Thu Jun 18 20:45:37 2015        
(r284575)
+++ stable/10/sys/netinet6/ip6_forward.c        Thu Jun 18 20:57:21 2015        
(r284576)
@@ -423,46 +423,6 @@ again2:
                goto bad;
        }
 
-       if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
-               in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
-               if (mcopy) {
-                       u_long mtu;
-#ifdef IPSEC
-                       struct secpolicy *sp;
-                       int ipsecerror;
-                       size_t ipsechdrsiz;
-#endif /* IPSEC */
-
-                       mtu = IN6_LINKMTU(rt->rt_ifp);
-#ifdef IPSEC
-                       /*
-                        * When we do IPsec tunnel ingress, we need to play
-                        * with the link value (decrement IPsec header size
-                        * from mtu value).  The code is much simpler than v4
-                        * case, as we have the outgoing interface for
-                        * encapsulated packet as "rt->rt_ifp".
-                        */
-                       sp = ipsec_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND,
-                               IP_FORWARDING, &ipsecerror);
-                       if (sp) {
-                               ipsechdrsiz = ipsec_hdrsiz(mcopy,
-                                       IPSEC_DIR_OUTBOUND, NULL);
-                               if (ipsechdrsiz < mtu)
-                                       mtu -= ipsechdrsiz;
-                       }
-
-                       /*
-                        * if mtu becomes less than minimum MTU,
-                        * tell minimum MTU (and I'll need to fragment it).
-                        */
-                       if (mtu < IPV6_MMTU)
-                               mtu = IPV6_MMTU;
-#endif /* IPSEC */
-                       icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
-               }
-               goto bad;
-       }
-
        if (rt->rt_flags & RTF_GATEWAY)
                dst = (struct sockaddr_in6 *)rt->rt_gateway;
 
@@ -591,6 +551,47 @@ again2:
        }
 
 pass:
+       /* See if the size was changed by the packet filter. */
+       if (m->m_pkthdr.len > IN6_LINKMTU(rt->rt_ifp)) {
+               in6_ifstat_inc(rt->rt_ifp, ifs6_in_toobig);
+               if (mcopy) {
+                       u_long mtu;
+#ifdef IPSEC
+                       struct secpolicy *sp;
+                       int ipsecerror;
+                       size_t ipsechdrsiz;
+#endif /* IPSEC */
+
+                       mtu = IN6_LINKMTU(rt->rt_ifp);
+#ifdef IPSEC
+                       /*
+                        * When we do IPsec tunnel ingress, we need to play
+                        * with the link value (decrement IPsec header size
+                        * from mtu value).  The code is much simpler than v4
+                        * case, as we have the outgoing interface for
+                        * encapsulated packet as "rt->rt_ifp".
+                        */
+                       sp = ipsec_getpolicybyaddr(mcopy, IPSEC_DIR_OUTBOUND,
+                               IP_FORWARDING, &ipsecerror);
+                       if (sp) {
+                               ipsechdrsiz = ipsec_hdrsiz(mcopy,
+                                       IPSEC_DIR_OUTBOUND, NULL);
+                               if (ipsechdrsiz < mtu)
+                                       mtu -= ipsechdrsiz;
+                       }
+
+                       /*
+                        * if mtu becomes less than minimum MTU,
+                        * tell minimum MTU (and I'll need to fragment it).
+                        */
+                       if (mtu < IPV6_MMTU)
+                               mtu = IPV6_MMTU;
+#endif /* IPSEC */
+                       icmp6_error(mcopy, ICMP6_PACKET_TOO_BIG, 0, mtu);
+               }
+               goto bad;
+       }
+
        error = nd6_output(rt->rt_ifp, origifp, m, dst, rt);
        if (error) {
                in6_ifstat_inc(rt->rt_ifp, ifs6_out_discard);
_______________________________________________
svn-src-stable-10@freebsd.org mailing list
https://lists.freebsd.org/mailman/listinfo/svn-src-stable-10
To unsubscribe, send any mail to "svn-src-stable-10-unsubscr...@freebsd.org"

Reply via email to