summaryrefslogtreecommitdiffstats
path: root/sys/netinet6
diff options
context:
space:
mode:
authorkp <kp@FreeBSD.org>2015-06-18 20:57:21 +0000
committerkp <kp@FreeBSD.org>2015-06-18 20:57:21 +0000
commit1af840c38ec20bb93f4838a45f3df0e34d6c5660 (patch)
treeff7b70e4bae96d7810ddc588acd9a2211c4668b9 /sys/netinet6
parent801d5721d10bb679d21776f0f8f4d459d302c588 (diff)
downloadFreeBSD-src-1af840c38ec20bb93f4838a45f3df0e34d6c5660.zip
FreeBSD-src-1af840c38ec20bb93f4838a45f3df0e34d6c5660.tar.gz
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
Diffstat (limited to 'sys/netinet6')
-rw-r--r--sys/netinet6/ip6_forward.c81
1 files changed, 41 insertions, 40 deletions
diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c
index a22c084..caa58e6 100644
--- a/sys/netinet6/ip6_forward.c
+++ b/sys/netinet6/ip6_forward.c
@@ -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);
OpenPOWER on IntegriCloud