summaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2015-03-25 11:49:03 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2015-03-25 11:49:03 +0000
commit30c37c09fd2268eb453123f618b54f8bd08a09bd (patch)
tree4c2d0f2ccd8443eeb5f1e181f430419eafb6d628 /sys/net/if.c
parent25f64aa8a945b4a2689ef7d8abe56b6fb59694fd (diff)
introduce code for network input queues. these are to replace the
use of struct ifqueue for things handled by softnet. they instead use an mbuf_queue (yay mpsafe) and wrap up the schednetisr and if_congestion handling. ok mpi@
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c63
1 files changed, 62 insertions, 1 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 67ff20834f8..8028522cc55 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.322 2015/03/18 12:23:15 dlg Exp $ */
+/* $OpenBSD: if.c,v 1.323 2015/03/25 11:49:02 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -2132,6 +2132,28 @@ sysctl_ifq(int *name, u_int namelen, void *oldp, size_t *oldlenp,
/* NOTREACHED */
}
+int
+sysctl_niq(int *name, u_int namelen, void *oldp, size_t *oldlenp,
+ void *newp, size_t newlen, struct niqueue *niq)
+{
+ /* All sysctl names at this level are terminal. */
+ if (namelen != 1)
+ return (ENOTDIR);
+
+ switch (name[0]) {
+ case IFQCTL_LEN:
+ return (sysctl_rdint(oldp, oldlenp, newp, niq_len(niq)));
+ case IFQCTL_MAXLEN:
+ return (sysctl_int(oldp, oldlenp, newp, newlen,
+ &niq->ni_q.mq_maxlen)); /* XXX */
+ case IFQCTL_DROPS:
+ return (sysctl_rdint(oldp, oldlenp, newp, niq_drops(niq)));
+ default:
+ return (EOPNOTSUPP);
+ }
+ /* NOTREACHED */
+}
+
void
ifa_add(struct ifnet *ifp, struct ifaddr *ifa)
{
@@ -2351,3 +2373,42 @@ if_rxr_ioctl(struct if_rxrinfo *ifri, const char *name, u_int size,
return (if_rxr_info_ioctl(ifri, 1, &ifr));
}
+
+/*
+ * Network stack input queues.
+ */
+
+void
+niq_init(struct niqueue *niq, u_int maxlen, u_int isr)
+{
+ mq_init(&niq->ni_q, maxlen, IPL_NET);
+ niq->ni_isr = isr;
+}
+
+int
+niq_enqueue(struct niqueue *niq, struct mbuf *m)
+{
+ int rv;
+
+ rv = mq_enqueue(&niq->ni_q, m);
+ if (rv == 0)
+ schednetisr(niq->ni_isr);
+ else
+ if_congestion();
+
+ return (rv);
+}
+
+int
+niq_enlist(struct niqueue *niq, struct mbuf_list *ml)
+{
+ int rv;
+
+ rv = mq_enlist(&niq->ni_q, ml);
+ if (rv == 0)
+ schednetisr(niq->ni_isr);
+ else
+ if_congestion();
+
+ return (rv);
+}