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
This commit is contained in:
parent
801d5721d1
commit
1af840c38e
@ -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);
|
||||
|
Loading…
x
Reference in New Issue
Block a user