summaryrefslogtreecommitdiffstats
path: root/sys/netinet/ip_input.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/netinet/ip_input.c')
-rw-r--r--sys/netinet/ip_input.c136
1 files changed, 87 insertions, 49 deletions
diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c
index ef1586d..ce92c2f 100644
--- a/sys/netinet/ip_input.c
+++ b/sys/netinet/ip_input.c
@@ -92,31 +92,32 @@ CTASSERT(sizeof(struct ip) == 20);
int rsvp_on = 0;
int ipforwarding = 0;
-SYSCTL_INT(_net_inet_ip, IPCTL_FORWARDING, forwarding, CTLFLAG_RW,
- &ipforwarding, 0, "Enable IP forwarding between interfaces");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, IPCTL_FORWARDING,
+ forwarding, CTLFLAG_RW, ipforwarding, 0,
+ "Enable IP forwarding between interfaces");
static int ipsendredirects = 1; /* XXX */
-SYSCTL_INT(_net_inet_ip, IPCTL_SENDREDIRECTS, redirect, CTLFLAG_RW,
- &ipsendredirects, 0, "Enable sending IP redirects");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, IPCTL_SENDREDIRECTS,
+ redirect, CTLFLAG_RW, ipsendredirects, 0,
+ "Enable sending IP redirects");
int ip_defttl = IPDEFTTL;
-SYSCTL_INT(_net_inet_ip, IPCTL_DEFTTL, ttl, CTLFLAG_RW,
- &ip_defttl, 0, "Maximum TTL on IP packets");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, IPCTL_DEFTTL,
+ ttl, CTLFLAG_RW, ip_defttl, 0, "Maximum TTL on IP packets");
static int ip_keepfaith = 0;
-SYSCTL_INT(_net_inet_ip, IPCTL_KEEPFAITH, keepfaith, CTLFLAG_RW,
- &ip_keepfaith, 0,
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, IPCTL_KEEPFAITH,
+ keepfaith, CTLFLAG_RW, ip_keepfaith, 0,
"Enable packet capture for FAITH IPv4->IPv6 translater daemon");
static int ip_sendsourcequench = 0;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, sendsourcequench, CTLFLAG_RW,
- &ip_sendsourcequench, 0,
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO,
+ sendsourcequench, CTLFLAG_RW, ip_sendsourcequench, 0,
"Enable the transmission of source quench packets");
int ip_do_randomid = 0;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, random_id, CTLFLAG_RW,
- &ip_do_randomid, 0,
- "Assign random ip_id values");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, random_id,
+ CTLFLAG_RW, ip_do_randomid, 0, "Assign random ip_id values");
/*
* XXX - Setting ip_checkinterface mostly implements the receive side of
@@ -132,8 +133,9 @@ SYSCTL_INT(_net_inet_ip, OID_AUTO, random_id, CTLFLAG_RW,
* packets for those addresses are received.
*/
static int ip_checkinterface = 0;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, check_interface, CTLFLAG_RW,
- &ip_checkinterface, 0, "Verify packet arrives on correct interface");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO,
+ check_interface, CTLFLAG_RW, ip_checkinterface, 0,
+ "Verify packet arrives on correct interface");
struct pfil_head inet_pfil_hook; /* Packet filter hooks */
@@ -154,8 +156,8 @@ SYSCTL_INT(_net_inet_ip, IPCTL_INTRQDROPS, intr_queue_drops, CTLFLAG_RD,
"Number of packets dropped from the IP input queue");
struct ipstat ipstat;
-SYSCTL_STRUCT(_net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RW,
- &ipstat, ipstat, "IP statistics (struct ipstat, netinet/ip_var.h)");
+SYSCTL_V_STRUCT(V_NET, vnet_inet, _net_inet_ip, IPCTL_STATS, stats, CTLFLAG_RW,
+ ipstat, ipstat, "IP statistics (struct ipstat, netinet/ip_var.h)");
/*
* IP datagram reassembly.
@@ -180,12 +182,13 @@ static void ipq_zone_change(void *);
static int maxnipq; /* Administrative limit on # reass queues. */
static int nipq = 0; /* Total # of reass queues */
-SYSCTL_INT(_net_inet_ip, OID_AUTO, fragpackets, CTLFLAG_RD,
- &nipq, 0, "Current number of IPv4 fragment reassembly queue entries");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, fragpackets,
+ CTLFLAG_RD, nipq, 0,
+ "Current number of IPv4 fragment reassembly queue entries");
static int maxfragsperpacket;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, maxfragsperpacket, CTLFLAG_RW,
- &maxfragsperpacket, 0,
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, maxfragsperpacket,
+ CTLFLAG_RW, maxfragsperpacket, 0,
"Maximum number of IPv4 fragments allowed per packet");
struct callout ipport_tick_callout;
@@ -197,8 +200,8 @@ SYSCTL_INT(_net_inet_ip, IPCTL_DEFMTU, mtu, CTLFLAG_RW,
#ifdef IPSTEALTH
int ipstealth = 0;
-SYSCTL_INT(_net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW,
- &ipstealth, 0, "IP stealth mode, no TTL decrementation on forwarding");
+SYSCTL_V_INT(V_NET, vnet_inet, _net_inet_ip, OID_AUTO, stealth, CTLFLAG_RW,
+ ipstealth, 0, "IP stealth mode, no TTL decrementation on forwarding");
#endif
/*
@@ -218,6 +221,7 @@ static void ip_freef(struct ipqhead *, struct ipq *);
void
ip_init(void)
{
+ INIT_VNET_INET(curvnet);
struct protosw *pr;
int i;
@@ -289,6 +293,7 @@ ip_fini(void *xtp)
void
ip_input(struct mbuf *m)
{
+ INIT_VNET_INET(curvnet);
struct ip *ip = NULL;
struct in_ifaddr *ia = NULL;
struct ifaddr *ifa;
@@ -681,6 +686,7 @@ bad:
static void
maxnipq_update(void)
{
+ INIT_VNET_INET(curvnet);
/*
* -1 for unlimited allocation.
@@ -704,6 +710,7 @@ maxnipq_update(void)
static void
ipq_zone_change(void *tag)
{
+ INIT_VNET_INET(curvnet);
if (V_maxnipq > 0 && V_maxnipq < (nmbclusters / 32)) {
V_maxnipq = nmbclusters / 32;
@@ -714,6 +721,7 @@ ipq_zone_change(void *tag)
static int
sysctl_maxnipq(SYSCTL_HANDLER_ARGS)
{
+ INIT_VNET_INET(curvnet);
int error, i;
i = V_maxnipq;
@@ -749,6 +757,7 @@ SYSCTL_PROC(_net_inet_ip, OID_AUTO, maxfragpackets, CTLTYPE_INT|CTLFLAG_RW,
struct mbuf *
ip_reass(struct mbuf *m)
{
+ INIT_VNET_INET(curvnet);
struct ip *ip;
struct mbuf *p, *q, *nq, *t;
struct ipq *fp = NULL;
@@ -1064,6 +1073,7 @@ done:
static void
ip_freef(struct ipqhead *fhp, struct ipq *fp)
{
+ INIT_VNET_INET(curvnet);
struct mbuf *q;
IPQ_LOCK_ASSERT();
@@ -1086,36 +1096,47 @@ ip_freef(struct ipqhead *fhp, struct ipq *fp)
void
ip_slowtimo(void)
{
+ VNET_ITERATOR_DECL(vnet_iter);
struct ipq *fp;
int i;
IPQ_LOCK();
- for (i = 0; i < IPREASS_NHASH; i++) {
- for(fp = TAILQ_FIRST(&V_ipq[i]); fp;) {
- struct ipq *fpp;
-
- fpp = fp;
- fp = TAILQ_NEXT(fp, ipq_list);
- if(--fpp->ipq_ttl == 0) {
- V_ipstat.ips_fragtimeout += fpp->ipq_nfrags;
- ip_freef(&V_ipq[i], fpp);
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ INIT_VNET_INET(vnet_iter);
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ for(fp = TAILQ_FIRST(&V_ipq[i]); fp;) {
+ struct ipq *fpp;
+
+ fpp = fp;
+ fp = TAILQ_NEXT(fp, ipq_list);
+ if(--fpp->ipq_ttl == 0) {
+ V_ipstat.ips_fragtimeout +=
+ fpp->ipq_nfrags;
+ ip_freef(&V_ipq[i], fpp);
+ }
}
}
- }
- /*
- * If we are over the maximum number of fragments
- * (due to the limit being lowered), drain off
- * enough to get down to the new limit.
- */
- if (V_maxnipq >= 0 && V_nipq > V_maxnipq) {
- for (i = 0; i < IPREASS_NHASH; i++) {
- while (V_nipq > V_maxnipq && !TAILQ_EMPTY(&V_ipq[i])) {
- V_ipstat.ips_fragdropped +=
- TAILQ_FIRST(&V_ipq[i])->ipq_nfrags;
- ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i]));
+ /*
+ * If we are over the maximum number of fragments
+ * (due to the limit being lowered), drain off
+ * enough to get down to the new limit.
+ */
+ if (V_maxnipq >= 0 && V_nipq > V_maxnipq) {
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ while (V_nipq > V_maxnipq &&
+ !TAILQ_EMPTY(&V_ipq[i])) {
+ V_ipstat.ips_fragdropped +=
+ TAILQ_FIRST(&V_ipq[i])->ipq_nfrags;
+ ip_freef(&V_ipq[i],
+ TAILQ_FIRST(&V_ipq[i]));
+ }
}
}
+ CURVNET_RESTORE();
}
+ VNET_LIST_RUNLOCK();
IPQ_UNLOCK();
}
@@ -1125,16 +1146,24 @@ ip_slowtimo(void)
void
ip_drain(void)
{
+ VNET_ITERATOR_DECL(vnet_iter);
int i;
IPQ_LOCK();
- for (i = 0; i < IPREASS_NHASH; i++) {
- while(!TAILQ_EMPTY(&V_ipq[i])) {
- V_ipstat.ips_fragdropped +=
- TAILQ_FIRST(&V_ipq[i])->ipq_nfrags;
- ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i]));
+ VNET_LIST_RLOCK();
+ VNET_FOREACH(vnet_iter) {
+ CURVNET_SET(vnet_iter);
+ INIT_VNET_INET(vnet_iter);
+ for (i = 0; i < IPREASS_NHASH; i++) {
+ while(!TAILQ_EMPTY(&V_ipq[i])) {
+ V_ipstat.ips_fragdropped +=
+ TAILQ_FIRST(&V_ipq[i])->ipq_nfrags;
+ ip_freef(&V_ipq[i], TAILQ_FIRST(&V_ipq[i]));
+ }
}
+ CURVNET_RESTORE();
}
+ VNET_LIST_RUNLOCK();
IPQ_UNLOCK();
in_rtqdrain();
}
@@ -1251,6 +1280,7 @@ u_char inetctlerrmap[PRC_NCMDS] = {
void
ip_forward(struct mbuf *m, int srcrt)
{
+ INIT_VNET_INET(curvnet);
struct ip *ip = mtod(m, struct ip *);
struct in_ifaddr *ia = NULL;
struct mbuf *mcopy;
@@ -1466,6 +1496,8 @@ void
ip_savecontrol(struct inpcb *inp, struct mbuf **mp, struct ip *ip,
struct mbuf *m)
{
+ INIT_VNET_NET(inp->inp_vnet);
+
if (inp->inp_socket->so_options & (SO_BINTIME | SO_TIMESTAMP)) {
struct bintime bt;
@@ -1564,6 +1596,8 @@ struct socket *ip_rsvpd;
int
ip_rsvp_init(struct socket *so)
{
+ INIT_VNET_INET(so->so_vnet);
+
if (so->so_type != SOCK_RAW ||
so->so_proto->pr_protocol != IPPROTO_RSVP)
return EOPNOTSUPP;
@@ -1587,6 +1621,8 @@ ip_rsvp_init(struct socket *so)
int
ip_rsvp_done(void)
{
+ INIT_VNET_INET(curvnet);
+
V_ip_rsvpd = NULL;
/*
* This may seem silly, but we need to be sure we don't over-decrement
@@ -1602,6 +1638,8 @@ ip_rsvp_done(void)
void
rsvp_input(struct mbuf *m, int off) /* XXX must fixup manually */
{
+ INIT_VNET_INET(curvnet);
+
if (rsvp_input_p) { /* call the real one if loaded */
rsvp_input_p(m, off);
return;
OpenPOWER on IntegriCloud