svn commit: r284576 - stable/10/sys/netinet6

Kristof Provost kp at FreeBSD.org
Thu Jun 18 20:57:22 UTC 2015


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);


More information about the svn-src-all mailing list