From f79061ff05119f98b31bd77e88fa11b44e7c9a66 Mon Sep 17 00:00:00 2001 From: glebius Date: Fri, 26 Oct 2012 21:06:33 +0000 Subject: 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 --- sys/net/if_bridge.c | 4 ++-- sys/netinet/ip_fastfwd.c | 4 +--- sys/netinet/ip_mroute.c | 3 ++- sys/netinet/ip_output.c | 29 ++++++++++++++++------------- sys/netinet/ip_var.h | 2 +- sys/netpfil/pf/pf.c | 18 +++++++++--------- 6 files changed, 31 insertions(+), 29 deletions(-) diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 11cd3d6..e935782 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -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; diff --git a/sys/netinet/ip_fastfwd.c b/sys/netinet/ip_fastfwd.c index b8d04ec..2ef163b 100644 --- a/sys/netinet/ip_fastfwd.c +++ b/sys/netinet/ip_fastfwd.c @@ -542,10 +542,8 @@ passout: * 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 diff --git a/sys/netinet/ip_mroute.c b/sys/netinet/ip_mroute.c index b72885f..5b33504 100644 --- a/sys/netinet/ip_mroute.c +++ b/sys/netinet/ip_mroute.c @@ -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; } diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 2df0fe8..96faf47 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -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 @@ passout: } 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 @@ passout: (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 @@ passout: * 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 @@ bad: * 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 @@ smart_frag_failure: 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 @@ smart_frag_failure: 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; diff --git a/sys/netinet/ip_var.h b/sys/netinet/ip_var.h index a685ddd..6b2f86e 100644 --- a/sys/netinet/ip_var.h +++ b/sys/netinet/ip_var.h @@ -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 diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c index 0b07728..0825367 100644 --- a/sys/netpfil/pf/pf.c +++ b/sys/netpfil/pf/pf.c @@ -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; -- cgit v1.1