Extend fixes made in r278103 and r38754 by copying the complete packet
header and not only partial flags and fields. Firewalls can attach classification tags to the outgoing mbufs which should be copied to all the new fragments. Else only the first fragment will be let through by the firewall. This can easily be tested by sending a large ping packet through a firewall. It was also discovered that VLAN related flags and fields should be copied for packets traversing through VLANs. This is all handled by "m_dup_pkthdr()". Regarding the MAC policy check in ip_fragment(), the tag provided by the originating mbuf is copied instead of using the default one provided by m_gethdr(). Tested by: Karim Fodil-Lemelin <fodillemlinkarim at gmail.com> MFC after: 2 weeks Sponsored by: Mellanox Technologies PR: 7802
This commit is contained in:
parent
033749179f
commit
c4c4346f5f
@ -774,11 +774,19 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
IPSTAT_INC(ips_odropped);
|
||||
goto done;
|
||||
}
|
||||
/* make sure the flowid is the same for the fragmented mbufs */
|
||||
M_HASHTYPE_SET(m, M_HASHTYPE_GET(m0));
|
||||
m->m_pkthdr.flowid = m0->m_pkthdr.flowid;
|
||||
/* copy multicast flag, if any */
|
||||
m->m_flags |= (m0->m_flags & M_MCAST);
|
||||
/*
|
||||
* Make sure the complete packet header gets copied
|
||||
* from the originating mbuf to the newly created
|
||||
* mbuf. This also ensures that existing firewall
|
||||
* classification(s), VLAN tags and so on get copied
|
||||
* to the resulting fragmented packet(s):
|
||||
*/
|
||||
if (m_dup_pkthdr(m, m0, M_NOWAIT) == 0) {
|
||||
m_free(m);
|
||||
error = ENOBUFS;
|
||||
IPSTAT_INC(ips_odropped);
|
||||
goto done;
|
||||
}
|
||||
/*
|
||||
* In the first mbuf, leave room for the link header, then
|
||||
* copy the original IP header including options. The payload
|
||||
@ -808,11 +816,9 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
goto done;
|
||||
}
|
||||
m->m_pkthdr.len = mhlen + len;
|
||||
m->m_pkthdr.rcvif = NULL;
|
||||
#ifdef MAC
|
||||
mac_netinet_fragment(m0, m);
|
||||
#endif
|
||||
m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
|
||||
mhip->ip_off = htons(mhip->ip_off);
|
||||
mhip->ip_sum = 0;
|
||||
if (m->m_pkthdr.csum_flags & CSUM_IP & ~if_hwassist_flags) {
|
||||
|
Loading…
Reference in New Issue
Block a user