Module Name: src Committed By: maxv Date: Tue Feb 6 17:08:19 UTC 2018
Modified Files: src/sys/netinet: ip_output.c Log Message: Several changes, mostly cosmetic: * Add a KASSERT in ip_output(), we expect (at least) the IP header to be here. * In ip_fragment(), declare two variables instead of recomputing the values each time. Add an XXX for ipoff, it seems to me we should also remove IP_RF. * Rename the arguments of ip_optcopy(). * Style: use NULL for pointers, remove ()s for return statements, and add whitespaces for clarity. No real functional change. To generate a diff of this commit: cvs rdiff -u -r1.292 -r1.293 src/sys/netinet/ip_output.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/netinet/ip_output.c diff -u src/sys/netinet/ip_output.c:1.292 src/sys/netinet/ip_output.c:1.293 --- src/sys/netinet/ip_output.c:1.292 Wed Jan 10 18:51:31 2018 +++ src/sys/netinet/ip_output.c Tue Feb 6 17:08:18 2018 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.292 2018/01/10 18:51:31 christos Exp $ */ +/* $NetBSD: ip_output.c,v 1.293 2018/02/06 17:08:18 maxv Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -29,7 +29,7 @@ * SUCH DAMAGE. */ -/*- +/* * Copyright (c) 1998 The NetBSD Foundation, Inc. * All rights reserved. * @@ -91,7 +91,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.292 2018/01/10 18:51:31 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.293 2018/02/06 17:08:18 maxv Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -156,7 +156,7 @@ static int ip_ifaddrvalid(const struct i extern pfil_head_t *inet_pfil_hook; /* XXX */ -int ip_do_loopback_cksum = 0; +int ip_do_loopback_cksum = 0; static int ip_mark_mpls(struct ifnet * const ifp, struct mbuf * const m, @@ -232,8 +232,7 @@ ip_output(struct mbuf *m0, struct mbuf * struct ip *ip; struct ifnet *ifp, *mifp = NULL; struct mbuf *m = m0; - int hlen = sizeof (struct ip); - int len, error = 0; + int len, hlen, error = 0; struct route iproute; const struct sockaddr_in *dst; struct in_ifaddr *ia = NULL; @@ -262,11 +261,12 @@ ip_output(struct mbuf *m0, struct mbuf * KASSERT((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) == 0); KASSERT((m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) != (M_CSUM_TCPv4|M_CSUM_UDPv4)); + KASSERT(m->m_len >= sizeof(struct ip)); + hlen = sizeof(struct ip); if (opt) { m = ip_insertoptions(m, opt, &len); - if (len >= sizeof(struct ip)) - hlen = len; + hlen = len; } ip = mtod(m, struct ip *); @@ -538,8 +538,8 @@ ip_output(struct mbuf *m0, struct mbuf * } /* - * packets with Class-D address as source are not valid per - * RFC 1112 + * Packets with Class-D address as source are not valid per + * RFC1112. */ if (IN_MULTICAST(ip->ip_src.s_addr)) { IP_STATINC(IP_STAT_ODROPPED); @@ -576,7 +576,6 @@ sendit: } else if ((m->m_pkthdr.csum_flags & M_CSUM_TSOv4) == 0) { ip->ip_id = ip_newid(ia); } else { - /* * TSO capable interfaces (typically?) increment * ip_id for each segment. @@ -673,6 +672,7 @@ sendit: m->m_pkthdr.csum_flags |= M_CSUM_IPv4; } sw_csum = m->m_pkthdr.csum_flags & ~ifp->if_csum_flags_tx; + /* * If small enough for mtu of path, or if using TCP segmentation * offload, can just send directly. @@ -726,8 +726,7 @@ sendit: } /* - * We can't use HW checksumming if we're about to - * fragment the packet. + * We can't use HW checksumming if we're about to fragment the packet. * * XXX Some hardware can do this. */ @@ -791,6 +790,7 @@ sendit: if (error == 0) { IP_STATINC(IP_STAT_FRAGMENTED); } + done: ia4_release(ia, &psref_ia); rtcache_unref(rt, ro); @@ -803,6 +803,7 @@ done: if (bind_need_restore) curlwp_bindx(bound); return error; + bad: m_freem(m); goto done; @@ -819,16 +820,24 @@ ip_fragment(struct mbuf *m, struct ifnet int sw_csum = m->m_pkthdr.csum_flags; int fragments = 0; int error = 0; + int ipoff; + bool mff; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; + + /* XXX: Why don't we remove IP_RF? */ + ipoff = ntohs(ip->ip_off) & ~IP_MF; + + mff = (ip->ip_off & htons(IP_MF)) != 0; + if (ifp != NULL) sw_csum &= ~ifp->if_csum_flags_tx; len = (mtu - hlen) &~ 7; if (len < 8) { m_freem(m); - return (EMSGSIZE); + return EMSGSIZE; } firstlen = len; @@ -839,45 +848,52 @@ ip_fragment(struct mbuf *m, struct ifnet * make new header and copy data of each part and link onto chain. */ m0 = m; - mhlen = sizeof (struct ip); + mhlen = sizeof(struct ip); for (off = hlen + len; off < ntohs(ip->ip_len); off += len) { MGETHDR(m, M_DONTWAIT, MT_HEADER); - if (m == 0) { + if (m == NULL) { error = ENOBUFS; IP_STATINC(IP_STAT_ODROPPED); goto sendorfree; } MCLAIM(m, m0->m_owner); + *mnext = m; mnext = &m->m_nextpkt; + m->m_data += max_linkhdr; mhip = mtod(m, struct ip *); *mhip = *ip; + /* we must inherit MCAST and BCAST flags */ m->m_flags |= m0->m_flags & (M_MCAST|M_BCAST); - if (hlen > sizeof (struct ip)) { - mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + + if (hlen > sizeof(struct ip)) { + mhlen = ip_optcopy(ip, mhip) + sizeof(struct ip); mhip->ip_hl = mhlen >> 2; } m->m_len = mhlen; - mhip->ip_off = ((off - hlen) >> 3) + - (ntohs(ip->ip_off) & ~IP_MF); - if (ip->ip_off & htons(IP_MF)) + + mhip->ip_off = ((off - hlen) >> 3) + ipoff; + if (mff) mhip->ip_off |= IP_MF; if (off + len >= ntohs(ip->ip_len)) len = ntohs(ip->ip_len) - off; else mhip->ip_off |= IP_MF; HTONS(mhip->ip_off); + mhip->ip_len = htons((u_int16_t)(len + mhlen)); m->m_next = m_copym(m0, off, len, M_DONTWAIT); - if (m->m_next == 0) { - error = ENOBUFS; /* ??? */ + if (m->m_next == NULL) { + error = ENOBUFS; IP_STATINC(IP_STAT_ODROPPED); goto sendorfree; } + m->m_pkthdr.len = mhlen + len; m_reset_rcvif(m); + mhip->ip_sum = 0; KASSERT((m->m_pkthdr.csum_flags & M_CSUM_IPv4) == 0); if (sw_csum & M_CSUM_IPv4) { @@ -896,6 +912,7 @@ ip_fragment(struct mbuf *m, struct ifnet IP_STATINC(IP_STAT_OFRAGMENTS); fragments++; } + /* * Update first fragment by trimming what's been copied out * and updating header, then send each fragment (in order). @@ -918,6 +935,7 @@ ip_fragment(struct mbuf *m, struct ifnet KASSERT(M_CSUM_DATA_IPv4_IPHL(m->m_pkthdr.csum_data) >= sizeof(struct ip)); } + sendorfree: /* * If there is no room for all the fragments, don't queue @@ -940,7 +958,8 @@ sendorfree: m_freem(m); } } - return (error); + + return error; } /* @@ -974,7 +993,6 @@ in_delayed_cksum(struct mbuf *m) * Determine the maximum length of the options to be inserted; * we would far rather allocate too much space rather than too little. */ - u_int ip_optlen(struct inpcb *inp) { @@ -1001,13 +1019,13 @@ ip_insertoptions(struct mbuf *m, struct optlen = opt->m_len - sizeof(p->ipopt_dst); if (optlen + ntohs(ip->ip_len) > IP_MAXPACKET) - return (m); /* XXX should fail */ + return m; /* XXX should fail */ if (!in_nullhost(p->ipopt_dst)) ip->ip_dst = p->ipopt_dst; if (M_READONLY(m) || M_LEADINGSPACE(m) < optlen) { MGETHDR(n, M_DONTWAIT, MT_HEADER); - if (n == 0) - return (m); + if (n == NULL) + return m; MCLAIM(n, m->m_owner); M_MOVE_PKTHDR(n, m); m->m_len -= sizeof(struct ip); @@ -1027,22 +1045,22 @@ ip_insertoptions(struct mbuf *m, struct bcopy((void *)p->ipopt_list, (void *)(ip + 1), (unsigned)optlen); *phlen = sizeof(struct ip) + optlen; ip->ip_len = htons(ntohs(ip->ip_len) + optlen); - return (m); + return m; } /* - * Copy options from ip to jp, - * omitting those not copied during fragmentation. + * Copy options from ipsrc to ipdst, omitting those not copied during + * fragmentation. */ int -ip_optcopy(struct ip *ip, struct ip *jp) +ip_optcopy(struct ip *ipsrc, struct ip *ipdst) { u_char *cp, *dp; int opt, optlen, cnt; - cp = (u_char *)(ip + 1); - dp = (u_char *)(jp + 1); - cnt = (ip->ip_hl << 2) - sizeof (struct ip); + cp = (u_char *)(ipsrc + 1); + dp = (u_char *)(ipdst + 1); + cnt = (ipsrc->ip_hl << 2) - sizeof(struct ip); for (; cnt > 0; cnt -= optlen, cp += optlen) { opt = cp[0]; if (opt == IPOPT_EOL) @@ -1066,9 +1084,12 @@ ip_optcopy(struct ip *ip, struct ip *jp) dp += optlen; } } - for (optlen = dp - (u_char *)(jp+1); optlen & 0x3; optlen++) + + for (optlen = dp - (u_char *)(ipdst+1); optlen & 0x3; optlen++) { *dp++ = IPOPT_EOL; - return (optlen); + } + + return optlen; } /* @@ -1560,12 +1581,12 @@ ip_pcbopts(struct inpcb *inp, const stru #ifndef __vax__ if (cnt % sizeof(int32_t)) - return (EINVAL); + return EINVAL; #endif m = m_get(M_DONTWAIT, MT_SOOPTS); if (m == NULL) - return (ENOBUFS); + return ENOBUFS; dp = mtod(m, u_char *); memset(dp, 0, sizeof(struct in_addr)); @@ -1645,6 +1666,7 @@ ip_pcbopts(struct inpcb *inp, const stru inp->inp_options = m; return 0; + bad: (void)m_free(m); return EINVAL;