o Remove last argument to ip_fragment(), and obtain all needed information
on checksums directly from mbuf flags. This simplifies code. o Clear CSUM_IP from the mbuf in ip_fragment() if we did checksums in hardware. Some driver may not announce CSUM_IP in theur if_hwassist, although try to do checksums if CSUM_IP set on mbuf. Example is em(4). o While here, consistently use CSUM_IP instead of its alias CSUM_DELAY_IP. After this change CSUM_DELAY_IP vanishes from the stack. Submitted by: Sebastian Kuzminsky <seb lineratesystems.com>
This commit is contained in:
parent
5c0adc7db8
commit
078468ede4
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=242161
@ -3379,8 +3379,8 @@ bridge_fragment(struct ifnet *ifp, struct mbuf *m, struct ether_header *eh,
|
||||
goto out;
|
||||
ip = mtod(m, struct ip *);
|
||||
|
||||
error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist,
|
||||
CSUM_DELAY_IP);
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP;
|
||||
error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist);
|
||||
if (error)
|
||||
goto out;
|
||||
|
||||
|
@ -542,10 +542,8 @@ ip_fastforward(struct mbuf *m)
|
||||
* We have to fragment the packet
|
||||
*/
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP;
|
||||
if (ip_fragment(ip, &m, mtu, ifp->if_hwassist,
|
||||
(~ifp->if_hwassist & CSUM_DELAY_IP))) {
|
||||
if (ip_fragment(ip, &m, mtu, ifp->if_hwassist))
|
||||
goto drop;
|
||||
}
|
||||
KASSERT(m != NULL, ("null mbuf and no error"));
|
||||
/*
|
||||
* Send off the fragments via outgoing interface
|
||||
|
@ -2404,7 +2404,8 @@ pim_register_prepare(struct ip *ip, struct mbuf *m)
|
||||
ip->ip_sum = in_cksum(mb_copy, ip->ip_hl << 2);
|
||||
} else {
|
||||
/* Fragment the packet */
|
||||
if (ip_fragment(ip, &mb_copy, mtu, 0, CSUM_DELAY_IP) != 0) {
|
||||
mb_copy->m_pkthdr.csum_flags |= CSUM_IP;
|
||||
if (ip_fragment(ip, &mb_copy, mtu, 0) != 0) {
|
||||
m_freem(mb_copy);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -125,7 +125,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
struct sockaddr_in *dst;
|
||||
struct in_ifaddr *ia;
|
||||
int isbroadcast;
|
||||
uint16_t ip_len, ip_off, sw_csum;
|
||||
uint16_t ip_len, ip_off;
|
||||
struct route iproute;
|
||||
struct rtentry *rte; /* cache for ro->ro_rt */
|
||||
struct in_addr odst;
|
||||
@ -583,18 +583,16 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
}
|
||||
|
||||
m->m_pkthdr.csum_flags |= CSUM_IP;
|
||||
sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_hwassist;
|
||||
if (sw_csum & CSUM_DELAY_DATA) {
|
||||
if (m->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~ifp->if_hwassist) {
|
||||
in_delayed_cksum(m);
|
||||
sw_csum &= ~CSUM_DELAY_DATA;
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
|
||||
}
|
||||
#ifdef SCTP
|
||||
if (sw_csum & CSUM_SCTP) {
|
||||
if (m->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) {
|
||||
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
|
||||
sw_csum &= ~CSUM_SCTP;
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_SCTP;
|
||||
}
|
||||
#endif
|
||||
m->m_pkthdr.csum_flags &= ifp->if_hwassist;
|
||||
|
||||
/*
|
||||
* If small enough for interface, or the interface will take
|
||||
@ -604,8 +602,10 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
(m->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 ||
|
||||
((ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) {
|
||||
ip->ip_sum = 0;
|
||||
if (sw_csum & CSUM_DELAY_IP)
|
||||
if (m->m_pkthdr.csum_flags & CSUM_IP & ~ifp->if_hwassist) {
|
||||
ip->ip_sum = in_cksum(m, hlen);
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_IP;
|
||||
}
|
||||
|
||||
/*
|
||||
* Record statistics for this interface address.
|
||||
@ -646,7 +646,7 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
* Too large for interface; fragment if possible. If successful,
|
||||
* on return, m will point to a list of packets to be sent.
|
||||
*/
|
||||
error = ip_fragment(ip, &m, mtu, ifp->if_hwassist, sw_csum);
|
||||
error = ip_fragment(ip, &m, mtu, ifp->if_hwassist);
|
||||
if (error)
|
||||
goto bad;
|
||||
for (; m; m = m0) {
|
||||
@ -691,11 +691,10 @@ ip_output(struct mbuf *m, struct mbuf *opt, struct route *ro, int flags,
|
||||
* chain of fragments that should be freed by the caller.
|
||||
*
|
||||
* if_hwassist_flags is the hw offload capabilities (see if_data.ifi_hwassist)
|
||||
* sw_csum contains the delayed checksums flags (e.g., CSUM_DELAY_IP).
|
||||
*/
|
||||
int
|
||||
ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
u_long if_hwassist_flags, int sw_csum)
|
||||
u_long if_hwassist_flags)
|
||||
{
|
||||
int error = 0;
|
||||
int hlen = ip->ip_hl << 2;
|
||||
@ -833,8 +832,10 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
m->m_pkthdr.csum_flags = m0->m_pkthdr.csum_flags;
|
||||
mhip->ip_off = htons(mhip->ip_off);
|
||||
mhip->ip_sum = 0;
|
||||
if (sw_csum & CSUM_DELAY_IP)
|
||||
if (m->m_pkthdr.csum_flags & CSUM_IP & ~if_hwassist_flags) {
|
||||
mhip->ip_sum = in_cksum(m, mhlen);
|
||||
m->m_pkthdr.csum_flags &= ~CSUM_IP;
|
||||
}
|
||||
*mnext = m;
|
||||
mnext = &m->m_nextpkt;
|
||||
}
|
||||
@ -853,8 +854,10 @@ ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
ip->ip_len = htons((u_short)m0->m_pkthdr.len);
|
||||
ip->ip_off = htons(ip_off | IP_MF);
|
||||
ip->ip_sum = 0;
|
||||
if (sw_csum & CSUM_DELAY_IP)
|
||||
if (m0->m_pkthdr.csum_flags & CSUM_IP & ~if_hwassist_flags) {
|
||||
ip->ip_sum = in_cksum(m0, hlen);
|
||||
m0->m_pkthdr.csum_flags &= ~CSUM_IP;
|
||||
}
|
||||
|
||||
done:
|
||||
*m_frag = m0;
|
||||
|
@ -210,7 +210,7 @@ int inp_setmoptions(struct inpcb *, struct sockopt *);
|
||||
int ip_ctloutput(struct socket *, struct sockopt *sopt);
|
||||
void ip_drain(void);
|
||||
int ip_fragment(struct ip *ip, struct mbuf **m_frag, int mtu,
|
||||
u_long if_hwassist_flags, int sw_csum);
|
||||
u_long if_hwassist_flags);
|
||||
void ip_forward(struct mbuf *m, int srcrt);
|
||||
void ip_init(void);
|
||||
#ifdef VIMAGE
|
||||
|
@ -5140,7 +5140,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
|
||||
struct pf_addr naddr;
|
||||
struct pf_src_node *sn = NULL;
|
||||
int error = 0;
|
||||
uint16_t ip_len, ip_off, sw_csum;
|
||||
uint16_t ip_len, ip_off;
|
||||
|
||||
KASSERT(m && *m && r && oifp, ("%s: invalid parameters", __func__));
|
||||
KASSERT(dir == PF_IN || dir == PF_OUT, ("%s: invalid direction",
|
||||
@ -5240,18 +5240,16 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
|
||||
|
||||
/* Copied from FreeBSD 10.0-CURRENT ip_output. */
|
||||
m0->m_pkthdr.csum_flags |= CSUM_IP;
|
||||
sw_csum = m0->m_pkthdr.csum_flags & ~ifp->if_hwassist;
|
||||
if (sw_csum & CSUM_DELAY_DATA) {
|
||||
if (m0->m_pkthdr.csum_flags & CSUM_DELAY_DATA & ~ifp->if_hwassist) {
|
||||
in_delayed_cksum(m0);
|
||||
sw_csum &= ~CSUM_DELAY_DATA;
|
||||
m0->m_pkthdr.csum_flags &= ~CSUM_DELAY_DATA;
|
||||
}
|
||||
#ifdef SCTP
|
||||
if (sw_csum & CSUM_SCTP) {
|
||||
if (m0->m_pkthdr.csum_flags & CSUM_SCTP & ~ifp->if_hwassist) {
|
||||
sctp_delayed_cksum(m, (uint32_t)(ip->ip_hl << 2));
|
||||
sw_csum &= ~CSUM_SCTP;
|
||||
m0->m_pkthdr.csum_flags &= ~CSUM_SCTP;
|
||||
}
|
||||
#endif
|
||||
m0->m_pkthdr.csum_flags &= ifp->if_hwassist;
|
||||
|
||||
/*
|
||||
* If small enough for interface, or the interface will take
|
||||
@ -5261,8 +5259,10 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
|
||||
(m0->m_pkthdr.csum_flags & ifp->if_hwassist & CSUM_TSO) != 0 ||
|
||||
((ip_off & IP_DF) == 0 && (ifp->if_hwassist & CSUM_FRAGMENT))) {
|
||||
ip->ip_sum = 0;
|
||||
if (sw_csum & CSUM_DELAY_IP)
|
||||
if (m0->m_pkthdr.csum_flags & CSUM_IP & ~ifp->if_hwassist) {
|
||||
ip->ip_sum = in_cksum(m0, ip->ip_hl << 2);
|
||||
m0->m_pkthdr.csum_flags &= ~CSUM_IP;
|
||||
}
|
||||
m0->m_flags &= ~(M_PROTOFLAGS);
|
||||
error = (*ifp->if_output)(ifp, m0, sintosa(&dst), NULL);
|
||||
goto done;
|
||||
@ -5280,7 +5280,7 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist, sw_csum);
|
||||
error = ip_fragment(ip, &m0, ifp->if_mtu, ifp->if_hwassist);
|
||||
if (error)
|
||||
goto bad;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user