On Mon, Aug 05, 2013 at 10:28:57AM -0400, Lawrence Teo wrote: > Index: ip_output.c > =================================================================== > RCS file: /cvs/src/sys/netinet/ip_output.c,v > retrieving revision 1.244 > diff -U5 -p -r1.244 ip_output.c > --- ip_output.c 31 Jul 2013 15:41:52 -0000 1.244 > +++ ip_output.c 5 Aug 2013 02:44:20 -0000 > @@ -2058,25 +2058,35 @@ ip_mloopback(struct ifnet *ifp, struct m > */ > void > in_delayed_cksum(struct mbuf *m) > { > struct ip *ip; > - u_int16_t csum, offset; > + u_int16_t csum = 0, offset; > > ip = mtod(m, struct ip *); > offset = ip->ip_hl << 2; > + > + if (ip->ip_p == IPPROTO_ICMP) > + if (m_copyback(m, offset + offsetof(struct icmp, icmp_cksum), > + sizeof(csum), &csum, M_NOWAIT)) > + return;
The code at the end of this function tries to avoid the m_copyback() in the common case unless (offset + sizeof(u_int16_t)) > m->m_len). Do we want this optimization here? bluhm > + > csum = in4_cksum(m, 0, offset, m->m_pkthdr.len - offset); > - if (csum == 0 && ip->ip_p == IPPROTO_UDP) > - csum = 0xffff; > > switch (ip->ip_p) { > case IPPROTO_TCP: > offset += offsetof(struct tcphdr, th_sum); > break; > > case IPPROTO_UDP: > offset += offsetof(struct udphdr, uh_sum); > + if (csum == 0) > + csum = 0xffff; > + break; > + > + case IPPROTO_ICMP: > + offset += offsetof(struct icmp, icmp_cksum); > break; > > default: > return; > } > @@ -2101,17 +2111,9 @@ in_proto_cksum_out(struct mbuf *m, struc > ifp->if_bridgeport != NULL) { > in_delayed_cksum(m); > m->m_pkthdr.csum_flags &= ~M_UDP_CSUM_OUT; /* Clear */ > } > } else if (m->m_pkthdr.csum_flags & M_ICMP_CSUM_OUT) { > - struct ip *ip = mtod(m, struct ip *); > - int hlen; > - struct icmp *icp; > - > - hlen = ip->ip_hl << 2; > - icp = (struct icmp *)(mtod(m, caddr_t) + hlen); > - icp->icmp_cksum = 0; > - icp->icmp_cksum = in4_cksum(m, 0, hlen, > - ntohs(ip->ip_len) - hlen); > + in_delayed_cksum(m); > m->m_pkthdr.csum_flags &= ~M_ICMP_CSUM_OUT; /* Clear */ > } > }