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);
}
/*