1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-29 12:03:03 +00:00

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/D1815
Reviewed by:	ae
Approved by:	gnn (mentor)
This commit is contained in:
Kristof Provost 2015-04-07 20:29:03 +00:00
parent dd3856601d
commit 53deb05c36
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=281234

View File

@ -413,39 +413,6 @@ ip6_forward(struct mbuf *m, int srcrt)
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
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".
*/
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;
@ -571,6 +538,40 @@ ip6_forward(struct mbuf *m, int srcrt)
}
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
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".
*/
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);