Module Name: src Committed By: rmind Date: Thu May 22 23:42:53 UTC 2014
Modified Files: src/sys/netinet: ip_output.c ip_var.h raw_ip.c Log Message: - Make ip_setmoptions(), ip_getmoptions() and ip_pcbopts() static. - ip_output: eliminate 7th variadic argument; IP_RETURNMTU is flag always used to store MTU size into struct inpcb::inp_errormtu. - Clean up these routines: reduce #ifdefs, variable scopes, etc. To generate a diff of this commit: cvs rdiff -u -r1.225 -r1.226 src/sys/netinet/ip_output.c cvs rdiff -u -r1.101 -r1.102 src/sys/netinet/ip_var.h cvs rdiff -u -r1.122 -r1.123 src/sys/netinet/raw_ip.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.225 src/sys/netinet/ip_output.c:1.226 --- src/sys/netinet/ip_output.c:1.225 Sat May 17 21:26:20 2014 +++ src/sys/netinet/ip_output.c Thu May 22 23:42:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_output.c,v 1.225 2014/05/17 21:26:20 rmind Exp $ */ +/* $NetBSD: ip_output.c,v 1.226 2014/05/22 23:42:53 rmind Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -91,17 +91,15 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.225 2014/05/17 21:26:20 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: ip_output.c,v 1.226 2014/05/22 23:42:53 rmind Exp $"); #include "opt_inet.h" #include "opt_ipsec.h" #include "opt_mrouting.h" #include <sys/param.h> -#include <sys/malloc.h> #include <sys/kmem.h> #include <sys/mbuf.h> -#include <sys/errno.h> #include <sys/protosw.h> #include <sys/socket.h> #include <sys/socketvar.h> @@ -110,7 +108,6 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c, #include <sys/domain.h> #endif #include <sys/systm.h> -#include <sys/proc.h> #include <net/if.h> #include <net/route.h> @@ -134,10 +131,13 @@ __KERNEL_RCSID(0, "$NetBSD: ip_output.c, #include <netipsec/ipsec.h> #include <netipsec/key.h> +static int ip_pcbopts(struct inpcb *, const struct sockopt *); static struct mbuf *ip_insertoptions(struct mbuf *, struct mbuf *, int *); static struct ifnet *ip_multicast_if(struct in_addr *, int *); static void ip_mloopback(struct ifnet *, struct mbuf *, const struct sockaddr_in *); +static int ip_setmoptions(struct inpcb *, const struct sockopt *); +static int ip_getmoptions(struct inpcb *, struct sockopt *); extern pfil_head_t *inet_pfil_hook; /* XXX */ @@ -164,7 +164,7 @@ ip_output(struct mbuf *m0, ...) struct ifaddr *xifa; struct mbuf *opt; struct route *ro; - int flags, sw_csum, *mtu_p; + int flags, sw_csum; u_long mtu; struct ip_moptions *imo; struct socket *so; @@ -187,35 +187,23 @@ ip_output(struct mbuf *m0, ...) flags = va_arg(ap, int); imo = va_arg(ap, struct ip_moptions *); so = va_arg(ap, struct socket *); - if (flags & IP_RETURNMTU) - mtu_p = va_arg(ap, int *); - else - mtu_p = NULL; va_end(ap); MCLAIM(m, &ip_tx_mowner); -#ifdef DIAGNOSTIC - if ((m->m_flags & M_PKTHDR) == 0) - panic("ip_output: no HDR"); - - if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv6|M_CSUM_UDPv6)) != 0) { - panic("ip_output: IPv6 checksum offload flags: %d", - m->m_pkthdr.csum_flags); - } + KASSERT(solocked(so)); + KASSERT((m->m_flags & M_PKTHDR) != 0); + 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)); - if ((m->m_pkthdr.csum_flags & (M_CSUM_TCPv4|M_CSUM_UDPv4)) == - (M_CSUM_TCPv4|M_CSUM_UDPv4)) { - panic("ip_output: conflicting checksum offload flags: %d", - m->m_pkthdr.csum_flags); - } -#endif if (opt) { m = ip_insertoptions(m, opt, &len); if (len >= sizeof(struct ip)) hlen = len; } ip = mtod(m, struct ip *); + /* * Fill in IP header. */ @@ -228,6 +216,7 @@ ip_output(struct mbuf *m0, ...) } else { hlen = ip->ip_hl << 2; } + /* * Route packet. */ @@ -236,17 +225,15 @@ ip_output(struct mbuf *m0, ...) ro = &iproute; sockaddr_in_init(&u.dst4, &ip->ip_dst, 0); dst = satocsin(rtcache_getdst(ro)); + /* - * If there is a cached route, - * check that it is to the same destination - * and is still up. If not, free it and try again. - * The address family should also be checked in case of sharing the - * cache with IPv6. + * If there is a cached route, check that it is to the same + * destination and is still up. If not, free it and try again. + * The address family should also be checked in case of sharing + * the cache with IPv6. */ - if (dst == NULL) - ; - else if (dst->sin_family != AF_INET || - !in_hosteq(dst->sin_addr, ip->ip_dst)) + if (dst && (dst->sin_family != AF_INET || + !in_hosteq(dst->sin_addr, ip->ip_dst))) rtcache_free(ro); if ((rt = rtcache_validate(ro)) == NULL && @@ -254,9 +241,9 @@ ip_output(struct mbuf *m0, ...) dst = &u.dst4; rtcache_setdst(ro, &u.dst); } + /* - * If routing to interface only, - * short circuit routing lookup. + * If routing to interface only, short circuit routing lookup. */ if (flags & IP_ROUTETOIF) { if ((ia = ifatoia(ifa_ifwithladdr(sintocsa(dst)))) == NULL) { @@ -289,6 +276,7 @@ ip_output(struct mbuf *m0, ...) if (rt->rt_flags & RTF_GATEWAY) dst = satosin(rt->rt_gateway); } + if (IN_MULTICAST(ip->ip_dst.s_addr) || (ip->ip_dst.s_addr == INADDR_BROADCAST)) { struct in_multi *inm; @@ -582,8 +570,10 @@ sendit: * Must be able to put at least 8 bytes per fragment. */ if (ntohs(ip->ip_off) & IP_DF) { - if (flags & IP_RETURNMTU) - *mtu_p = mtu; + if (flags & IP_RETURNMTU) { + struct inpcb *inp = sotoinpcb(so); + inp->inp_errormtu = mtu; + } error = EMSGSIZE; IP_STATINC(IP_STAT_CANTFRAG); goto bad; @@ -613,15 +603,14 @@ sendit: if (natt_frag) { error = ip_output(m, opt, ro, flags | IP_RAWOUTPUT | IP_NOIPNEWID, - imo, so, mtu_p); + imo, so); } else { KASSERT((m->m_pkthdr.csum_flags & (M_CSUM_UDPv4 | M_CSUM_TCPv4)) == 0); KERNEL_LOCK(1, NULL); error = (*ifp->if_output)(ifp, m, (m->m_flags & M_MCAST) ? - sintocsa(rdst) : sintocsa(dst), - rt); + sintocsa(rdst) : sintocsa(dst), rt); KERNEL_UNLOCK_ONE(NULL); } } else @@ -816,13 +805,12 @@ ip_optlen(struct inpcb *inp) { struct mbuf *m = inp->inp_options; - if (m && m->m_len > offsetof(struct ipoption, ipopt_dst)) + if (m && m->m_len > offsetof(struct ipoption, ipopt_dst)) { return (m->m_len - offsetof(struct ipoption, ipopt_dst)); - else - return 0; + } + return 0; } - /* * Insert IP options into preformed packet. * Adjust IP destination as required for IP source routing, @@ -890,16 +878,12 @@ ip_optcopy(struct ip *ip, struct ip *jp) optlen = 1; continue; } -#ifdef DIAGNOSTIC - if (cnt < IPOPT_OLEN + sizeof(*cp)) - panic("malformed IPv4 option passed to ip_optcopy"); -#endif + + KASSERT(cnt >= IPOPT_OLEN + sizeof(*cp)); optlen = cp[IPOPT_OLEN]; -#ifdef DIAGNOSTIC - if (optlen < IPOPT_OLEN + sizeof(*cp) || optlen > cnt) - panic("malformed IPv4 option passed to ip_optcopy"); -#endif - /* bogus lengths should have been caught by ip_dooptions */ + KASSERT(optlen >= IPOPT_OLEN + sizeof(*cp) && optlen < cnt); + + /* Invalid lengths should have been caught by ip_dooptions. */ if (optlen > cnt) optlen = cnt; if (IPOPT_COPIED(opt)) { @@ -919,11 +903,9 @@ int ip_ctloutput(int op, struct socket *so, struct sockopt *sopt) { struct inpcb *inp = sotoinpcb(so); - int optval = 0; - int error = 0; -#if defined(IPSEC) - struct lwp *l = curlwp; /*XXX*/ -#endif + struct ip *ip = &inp->inp_ip; + int inpflags = inp->inp_flags; + int optval = 0, error = 0; if (sopt->sopt_level != IPPROTO_IP) { if (sopt->sopt_level == SOL_SOCKET && sopt->sopt_name == SO_NOHEADER) @@ -938,7 +920,7 @@ ip_ctloutput(int op, struct socket *so, #ifdef notyet case IP_RETOPTS: #endif - error = ip_pcbopts(&inp->inp_options, sopt); + error = ip_pcbopts(inp, sopt); break; case IP_TOS: @@ -957,11 +939,11 @@ ip_ctloutput(int op, struct socket *so, switch (sopt->sopt_name) { case IP_TOS: - inp->inp_ip.ip_tos = optval; + ip->ip_tos = optval; break; case IP_TTL: - inp->inp_ip.ip_ttl = optval; + ip->ip_ttl = optval; break; case IP_MINTTL: @@ -972,9 +954,9 @@ ip_ctloutput(int op, struct socket *so, break; #define OPTSET(bit) \ if (optval) \ - inp->inp_flags |= bit; \ + inpflags |= bit; \ else \ - inp->inp_flags &= ~bit; + inpflags &= ~bit; case IP_PKTINFO: OPTSET(INP_PKTINFO); @@ -1012,7 +994,7 @@ ip_ctloutput(int op, struct socket *so, case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: - error = ip_setmoptions(&inp->inp_moptions, sopt); + error = ip_setmoptions(inp, sopt); break; case IP_PORTRANGE: @@ -1020,22 +1002,20 @@ ip_ctloutput(int op, struct socket *so, if (error) break; - /* INP_LOCK(inp); */ switch (optval) { case IP_PORTRANGE_DEFAULT: case IP_PORTRANGE_HIGH: - inp->inp_flags &= ~(INP_LOWPORT); + inpflags &= ~(INP_LOWPORT); break; case IP_PORTRANGE_LOW: - inp->inp_flags |= INP_LOWPORT; + inpflags |= INP_LOWPORT; break; default: error = EINVAL; break; } - /* INP_UNLOCK(inp); */ break; case IP_PORTALGO: @@ -1050,7 +1030,7 @@ ip_ctloutput(int op, struct socket *so, #if defined(IPSEC) case IP_IPSEC_POLICY: error = ipsec4_set_policy(inp, sopt->sopt_name, - sopt->sopt_data, sopt->sopt_size, l->l_cred); + sopt->sopt_data, sopt->sopt_size, curlwp->l_cred); break; #endif /*IPSEC*/ @@ -1063,21 +1043,21 @@ ip_ctloutput(int op, struct socket *so, case PRCO_GETOPT: switch (sopt->sopt_name) { case IP_OPTIONS: - case IP_RETOPTS: - if (inp->inp_options) { + case IP_RETOPTS: { + struct mbuf *mopts = inp->inp_options; + + if (mopts) { struct mbuf *m; - m = m_copym(inp->inp_options, 0, M_COPYALL, - M_DONTWAIT); + m = m_copym(mopts, 0, M_COPYALL, M_DONTWAIT); if (m == NULL) { error = ENOBUFS; break; } - error = sockopt_setmbuf(sopt, m); } break; - + } case IP_PKTINFO: case IP_TOS: case IP_TTL: @@ -1091,11 +1071,11 @@ ip_ctloutput(int op, struct socket *so, case IP_ERRORMTU: switch (sopt->sopt_name) { case IP_TOS: - optval = inp->inp_ip.ip_tos; + optval = ip->ip_tos; break; case IP_TTL: - optval = inp->inp_ip.ip_ttl; + optval = ip->ip_ttl; break; case IP_MINTTL: @@ -1106,7 +1086,7 @@ ip_ctloutput(int op, struct socket *so, optval = inp->inp_errormtu; break; -#define OPTBIT(bit) (inp->inp_flags & bit ? 1 : 0) +#define OPTBIT(bit) (inpflags & bit ? 1 : 0) case IP_PKTINFO: optval = OPTBIT(INP_PKTINFO); @@ -1158,21 +1138,19 @@ ip_ctloutput(int op, struct socket *so, case IP_MULTICAST_LOOP: case IP_ADD_MEMBERSHIP: case IP_DROP_MEMBERSHIP: - error = ip_getmoptions(inp->inp_moptions, sopt); + error = ip_getmoptions(inp, sopt); break; case IP_PORTRANGE: - if (inp->inp_flags & INP_LOWPORT) + if (inpflags & INP_LOWPORT) optval = IP_PORTRANGE_LOW; else optval = IP_PORTRANGE_DEFAULT; - error = sockopt_setint(sopt, optval); - break; case IP_PORTALGO: - optval = ((struct inpcb_hdr *)inp)->inph_portalgo; + optval = inp->inp_portalgo; error = sockopt_setint(sopt, optval); break; @@ -1182,7 +1160,11 @@ ip_ctloutput(int op, struct socket *so, } break; } - return (error); + + if (!error) { + inp->inp_flags = inpflags; + } + return error; } /* @@ -1190,25 +1172,24 @@ ip_ctloutput(int op, struct socket *so, * Store in mbuf with pointer in pcbopt, adding pseudo-option * with destination address if source routed. */ -int -ip_pcbopts(struct mbuf **pcbopt, const struct sockopt *sopt) +static int +ip_pcbopts(struct inpcb *inp, const struct sockopt *sopt) { struct mbuf *m; const u_char *cp; u_char *dp; int cnt; - uint8_t optval, olen, offset; - - /* turn off any old options */ - if (*pcbopt) - (void)m_free(*pcbopt); - *pcbopt = NULL; + /* Turn off any old options. */ + if (inp->inp_options) { + m_free(inp->inp_options); + } + inp->inp_options = NULL; + if ((cnt = sopt->sopt_size) == 0) { + /* Only turning off any previous options. */ + return 0; + } cp = sopt->sopt_data; - cnt = sopt->sopt_size; - - if (cnt == 0) - return (0); /* Only turning off any previous options */ #ifndef __vax__ if (cnt % sizeof(int32_t)) @@ -1229,11 +1210,13 @@ ip_pcbopts(struct mbuf **pcbopt, const s * * [optval] [olen] [(olen - 2) data bytes] * - * we validate the list and copy options to an mbuf for prepending + * We validate the list and copy options to an mbuf for prepending * to data packets. The IP first-hop destination address will be * stored before actual options and is zero if unset. */ while (cnt > 0) { + uint8_t optval, olen, offset; + optval = cp[IPOPT_OPTVAL]; if (optval == IPOPT_EOL || optval == IPOPT_NOP) { @@ -1293,12 +1276,11 @@ ip_pcbopts(struct mbuf **pcbopt, const s cnt -= olen; } - *pcbopt = m; - return (0); - + inp->inp_options = m; + return 0; bad: (void)m_free(m); - return (EINVAL); + return EINVAL; } /* @@ -1369,16 +1351,16 @@ ip_getoptval(const struct sockopt *sopt, /* * Set the IP multicast options in response to user setsockopt(). */ -int -ip_setmoptions(struct ip_moptions **imop, const struct sockopt *sopt) +static int +ip_setmoptions(struct inpcb *inp, const struct sockopt *sopt) { + struct ip_moptions *imo = inp->inp_moptions; struct in_addr addr; struct ip_mreq lmreq, *mreq; struct ifnet *ifp; - struct ip_moptions *imo = *imop; int i, ifindex, error = 0; - if (imo == NULL) { + if (!imo) { /* * No multicast option buffer attached to the pcb; * allocate one and initialize to default values. @@ -1392,7 +1374,7 @@ ip_setmoptions(struct ip_moptions **imop imo->imo_multicast_ttl = IP_DEFAULT_MULTICAST_TTL; imo->imo_multicast_loop = IP_DEFAULT_MULTICAST_LOOP; imo->imo_num_memberships = 0; - *imop = imo; + inp->inp_moptions = imo; } switch (sopt->sopt_name) { @@ -1588,7 +1570,7 @@ ip_setmoptions(struct ip_moptions **imop imo->imo_multicast_loop == IP_DEFAULT_MULTICAST_LOOP && imo->imo_num_memberships == 0) { kmem_free(imo, sizeof(*imo)); - *imop = NULL; + inp->inp_moptions = NULL; } return error; @@ -1597,15 +1579,14 @@ ip_setmoptions(struct ip_moptions **imop /* * Return the IP multicast options in response to user getsockopt(). */ -int -ip_getmoptions(struct ip_moptions *imo, struct sockopt *sopt) +static int +ip_getmoptions(struct inpcb *inp, struct sockopt *sopt) { + struct ip_moptions *imo = inp->inp_moptions; struct in_addr addr; struct in_ifaddr *ia; - int error; uint8_t optval; - - error = 0; + int error = 0; switch (sopt->sopt_name) { case IP_MULTICAST_IF: @@ -1639,7 +1620,7 @@ ip_getmoptions(struct ip_moptions *imo, error = EOPNOTSUPP; } - return (error); + return error; } /* Index: src/sys/netinet/ip_var.h diff -u src/sys/netinet/ip_var.h:1.101 src/sys/netinet/ip_var.h:1.102 --- src/sys/netinet/ip_var.h:1.101 Thu May 22 22:01:12 2014 +++ src/sys/netinet/ip_var.h Thu May 22 23:42:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: ip_var.h,v 1.101 2014/05/22 22:01:12 rmind Exp $ */ +/* $NetBSD: ip_var.h,v 1.102 2014/05/22 23:42:53 rmind Exp $ */ /* * Copyright (c) 1982, 1986, 1993 @@ -203,12 +203,10 @@ void ip_drain(void); void ip_drainstub(void); void ip_forward(struct mbuf *, int); void ip_freemoptions(struct ip_moptions *); -int ip_getmoptions(struct ip_moptions *, struct sockopt *); int ip_optcopy(struct ip *, struct ip *); u_int ip_optlen(struct inpcb *); int ip_output(struct mbuf *, ...); int ip_fragment(struct mbuf *, struct ifnet *, u_long); -int ip_pcbopts(struct mbuf **, const struct sockopt *); void ip_reass_init(void); int ip_reass_packet(struct mbuf **, struct ip *); @@ -217,7 +215,6 @@ void ip_reass_drain(void); void ip_savecontrol(struct inpcb *, struct mbuf **, struct ip *, struct mbuf *); -int ip_setmoptions(struct ip_moptions **, const struct sockopt *); void ip_slowtimo(void); void ip_fasttimo(void); struct mbuf * Index: src/sys/netinet/raw_ip.c diff -u src/sys/netinet/raw_ip.c:1.122 src/sys/netinet/raw_ip.c:1.123 --- src/sys/netinet/raw_ip.c:1.122 Tue May 20 19:04:00 2014 +++ src/sys/netinet/raw_ip.c Thu May 22 23:42:53 2014 @@ -1,4 +1,4 @@ -/* $NetBSD: raw_ip.c,v 1.122 2014/05/20 19:04:00 rmind Exp $ */ +/* $NetBSD: raw_ip.c,v 1.123 2014/05/22 23:42:53 rmind Exp $ */ /* * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. @@ -65,7 +65,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.122 2014/05/20 19:04:00 rmind Exp $"); +__KERNEL_RCSID(0, "$NetBSD: raw_ip.c,v 1.123 2014/05/22 23:42:53 rmind Exp $"); #include "opt_inet.h" #include "opt_compat_netbsd.h" @@ -381,8 +381,13 @@ rip_output(struct mbuf *m, ...) flags |= IP_RAWOUTPUT; IP_STATINC(IP_STAT_RAWOUT); } - return (ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, - inp->inp_socket, &inp->inp_errormtu)); + + /* + * IP output. Note: if IP_RETURNMTU flag is set, the MTU size + * will be stored in inp_errormtu. + */ + return ip_output(m, opts, &inp->inp_route, flags, inp->inp_moptions, + inp->inp_socket); } /*