summaryrefslogtreecommitdiff
path: root/sys/net/if.c
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-07-22 02:16:03 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-07-22 02:16:03 +0000
commite7539b190c92e728ca85bde26d2ba6e8599ec22c (patch)
tree855bd097524f5c275d95140541bec54bcee6faae /sys/net/if.c
parent2a91cae0189e06d8a9ef9b033ff30a43f9c53bb4 (diff)
deprecate interface input handler lists, just use one input function.
the interface input handler lists were originally set up to help us during the intial mpsafe network stack work. at the time not all the virtual ethernet interfaces (vlan, svlan, bridge, trunk, etc) were mpsafe, so we wanted a way to avoid them by default, and only take the kernel lock hit when they were specifically enabled on the interface. since then, they have been fixed up to be mpsafe. i could leave the list in place, but it has some semantic problems. because virtual interfaces filter packets based on the order they were attached to the parent interface, you can get packets taken away in surprising ways, especially when you reboot and netstart does something different to what you did by hand. by hardcoding the order that things like vlan and bridge get to look at packets, we can document the behaviour and get consistency. it also means we can get rid of a use of SRPs which were difficult to replace with SMRs. the interface input handler list is an SRPL, which we would like to deprecate. it turns out that you can sleep during stack processing, which you're not supposed to do with SRPs or SMRs, but SRPs are a lot more forgiving and it worked. lastly, it turns out that this code is faster than the input list handling, so lots of winning all around. special thanks to hrvoje popovski and aaron bieber for testing. this has been in snaps as part of a larger diff for over a week.
Diffstat (limited to 'sys/net/if.c')
-rw-r--r--sys/net/if.c111
1 files changed, 3 insertions, 108 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index a7aacb0c6c8..51ec987c37d 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if.c,v 1.614 2020/07/20 13:55:32 mvs Exp $ */
+/* $OpenBSD: if.c,v 1.615 2020/07/22 02:16:01 dlg Exp $ */
/* $NetBSD: if.c,v 1.35 1996/05/07 05:26:04 thorpej Exp $ */
/*
@@ -633,8 +633,6 @@ if_attach_common(struct ifnet *ifp)
if (ifp->if_enqueue == NULL)
ifp->if_enqueue = if_enqueue_ifq;
ifp->if_llprio = IFQ_DEFPRIO;
-
- SRPL_INIT(&ifp->if_inputs);
}
void
@@ -807,109 +805,6 @@ if_output_local(struct ifnet *ifp, struct mbuf *m, sa_family_t af)
return (ifiq_enqueue(ifiq, m) == 0 ? 0 : ENOBUFS);
}
-struct ifih {
- SRPL_ENTRY(ifih) ifih_next;
- int (*ifih_input)(struct ifnet *, struct mbuf *,
- void *);
- void *ifih_cookie;
- int ifih_refcnt;
- struct refcnt ifih_srpcnt;
-};
-
-void if_ih_ref(void *, void *);
-void if_ih_unref(void *, void *);
-
-struct srpl_rc ifih_rc = SRPL_RC_INITIALIZER(if_ih_ref, if_ih_unref, NULL);
-
-void
-if_ih_insert(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *,
- void *), void *cookie)
-{
- struct ifih *ifih;
-
- /* the kernel lock guarantees serialised modifications to if_inputs */
- KERNEL_ASSERT_LOCKED();
-
- SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) {
- if (ifih->ifih_input == input && ifih->ifih_cookie == cookie) {
- ifih->ifih_refcnt++;
- break;
- }
- }
-
- if (ifih == NULL) {
- ifih = malloc(sizeof(*ifih), M_DEVBUF, M_WAITOK);
-
- ifih->ifih_input = input;
- ifih->ifih_cookie = cookie;
- ifih->ifih_refcnt = 1;
- refcnt_init(&ifih->ifih_srpcnt);
- SRPL_INSERT_HEAD_LOCKED(&ifih_rc, &ifp->if_inputs,
- ifih, ifih_next);
- }
-}
-
-void
-if_ih_ref(void *null, void *i)
-{
- struct ifih *ifih = i;
-
- refcnt_take(&ifih->ifih_srpcnt);
-}
-
-void
-if_ih_unref(void *null, void *i)
-{
- struct ifih *ifih = i;
-
- refcnt_rele_wake(&ifih->ifih_srpcnt);
-}
-
-void
-if_ih_remove(struct ifnet *ifp, int (*input)(struct ifnet *, struct mbuf *,
- void *), void *cookie)
-{
- struct ifih *ifih;
-
- /* the kernel lock guarantees serialised modifications to if_inputs */
- KERNEL_ASSERT_LOCKED();
-
- SRPL_FOREACH_LOCKED(ifih, &ifp->if_inputs, ifih_next) {
- if (ifih->ifih_input == input && ifih->ifih_cookie == cookie)
- break;
- }
-
- KASSERT(ifih != NULL);
-
- if (--ifih->ifih_refcnt == 0) {
- SRPL_REMOVE_LOCKED(&ifih_rc, &ifp->if_inputs, ifih,
- ifih, ifih_next);
-
- refcnt_finalize(&ifih->ifih_srpcnt, "ifihrm");
- free(ifih, M_DEVBUF, sizeof(*ifih));
- }
-}
-
-static void
-if_ih_input(struct ifnet *ifp, struct mbuf *m)
-{
- struct ifih *ifih;
- struct srp_ref sr;
-
- /*
- * Pass this mbuf to all input handlers of its
- * interface until it is consumed.
- */
- SRPL_FOREACH(ifih, &sr, &ifp->if_inputs, ifih_next) {
- if ((*ifih->ifih_input)(ifp, m, ifih->ifih_cookie))
- break;
- }
- SRPL_LEAVE(&sr);
-
- if (ifih == NULL)
- m_freem(m);
-}
-
void
if_input_process(struct ifnet *ifp, struct mbuf_list *ml)
{
@@ -935,7 +830,7 @@ if_input_process(struct ifnet *ifp, struct mbuf_list *ml)
*/
NET_LOCK();
while ((m = ml_dequeue(ml)) != NULL)
- if_ih_input(ifp, m);
+ (*ifp->if_input)(ifp, m);
NET_UNLOCK();
}
@@ -962,7 +857,7 @@ if_vinput(struct ifnet *ifp, struct mbuf *m)
}
#endif
- if_ih_input(ifp, m);
+ (*ifp->if_input)(ifp, m);
}
void