Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/net Add a bpf_register_track_event() function (and dereg...



details:   https://anonhg.NetBSD.org/src/rev/c0ab9415d8bb
branches:  trunk
changeset: 1021614:c0ab9415d8bb
user:      martin <martin%NetBSD.org@localhost>
date:      Wed Jun 09 15:44:15 2021 +0000

description:
Add a bpf_register_track_event() function (and deregister equivalent)
that allows a driver to track listeners attaching/detaching from tap
points.

This is usefull for drivers that would have to do extra work for some
taps and can not easily decide (at the driver level) if the work would
be needed further up the stack.

An example is providing radiotap headers for IEEE 802.11 frames.

diffstat:

 sys/net/bpf.c     |  87 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
 sys/net/bpf.h     |  31 ++++++++++++++++++-
 sys/net/bpfdesc.h |  11 ++++++-
 3 files changed, 124 insertions(+), 5 deletions(-)

diffs (253 lines):

diff -r 48b25793a34e -r c0ab9415d8bb sys/net/bpf.c
--- a/sys/net/bpf.c     Wed Jun 09 15:38:39 2021 +0000
+++ b/sys/net/bpf.c     Wed Jun 09 15:44:15 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.c,v 1.239 2020/12/18 01:31:49 thorpej Exp $        */
+/*     $NetBSD: bpf.c,v 1.240 2021/06/09 15:44:15 martin Exp $ */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -39,7 +39,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.239 2020/12/18 01:31:49 thorpej Exp $");
+__KERNEL_RCSID(0, "$NetBSD: bpf.c,v 1.240 2021/06/09 15:44:15 martin Exp $");
 
 #if defined(_KERNEL_OPT)
 #include "opt_bpf.h"
@@ -461,6 +461,7 @@
 static void
 bpf_attachd(struct bpf_d *d, struct bpf_if *bp)
 {
+       struct bpf_event_tracker *t;
 
        KASSERT(mutex_owned(&bpf_mtx));
        KASSERT(mutex_owned(d->bd_mtx));
@@ -473,6 +474,11 @@
        BPFIF_DLIST_WRITER_INSERT_HEAD(bp, d);
 
        *bp->bif_driverp = bp;
+
+       SLIST_FOREACH(t, &bp->bif_trackers, bet_entries) {
+               t->bet_notify(bp, bp->bif_ifp, bp->bif_dlt,
+                   BPF_TRACK_EVENT_ATTACH);
+       }
 }
 
 /*
@@ -482,6 +488,7 @@
 bpf_detachd(struct bpf_d *d)
 {
        struct bpf_if *bp;
+       struct bpf_event_tracker *t;
 
        KASSERT(mutex_owned(&bpf_mtx));
        KASSERT(mutex_owned(d->bd_mtx));
@@ -522,7 +529,13 @@
                 */
                *d->bd_bif->bif_driverp = NULL;
        }
+
        d->bd_bif = NULL;
+
+       SLIST_FOREACH(t, &bp->bif_trackers, bet_entries) {
+               t->bet_notify(bp, bp->bif_ifp, bp->bif_dlt,
+                   BPF_TRACK_EVENT_DETACH);
+       }
 }
 
 static void
@@ -2125,6 +2138,7 @@
        BPF_IFLIST_ENTRY_INIT(bp);
        PSLIST_INIT(&bp->bif_dlist_head);
        psref_target_init(&bp->bif_psref, bpf_psref_class);
+       SLIST_INIT(&bp->bif_trackers);
 
        BPF_IFLIST_WRITER_INSERT_HEAD(bp);
 
@@ -2133,7 +2147,7 @@
        bp->bif_hdrlen = hdrlen;
        mutex_exit(&bpf_mtx);
 #if 0
-       printf("bpf: %s attached\n", ifp->if_xname);
+       printf("bpf: %s attached with dlt %x\n", ifp->if_xname, dlt);
 #endif
 }
 
@@ -2196,6 +2210,14 @@
                        pserialize_perform(bpf_psz);
                        psref_target_destroy(&bp->bif_psref, bpf_psref_class);
 
+                       while (!SLIST_EMPTY(&bp->bif_trackers)) {
+                               struct bpf_event_tracker *t =
+                                   SLIST_FIRST(&bp->bif_trackers);
+                               SLIST_REMOVE_HEAD(&bp->bif_trackers,
+                                   bet_entries);
+                               kmem_free(t, sizeof(*t));
+                       }
+
                        BPF_IFLIST_ENTRY_DESTROY(bp);
                        if (bp->bif_si != NULL) {
                                /* XXX NOMPSAFE: assumed running on one CPU */
@@ -2523,10 +2545,69 @@
 
 }
 
+static int
+_bpf_register_track_event(struct bpf_if **driverp,
+           void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
+{
+       struct bpf_if *bp;
+       struct bpf_event_tracker *t;
+       int ret = ENOENT;
+
+       t = kmem_zalloc(sizeof(*t), KM_SLEEP);
+       if (!t)
+               return ENOMEM;
+       t->bet_notify = _fun;
+
+       mutex_enter(&bpf_mtx);
+       BPF_IFLIST_WRITER_FOREACH(bp) {
+               if (bp->bif_driverp != driverp)
+                       continue;
+               SLIST_INSERT_HEAD(&bp->bif_trackers, t, bet_entries);
+               ret = 0;
+               break;
+       }
+       mutex_exit(&bpf_mtx);
+
+       return ret;
+}
+
+static int
+_bpf_deregister_track_event(struct bpf_if **driverp,
+           void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
+{
+       struct bpf_if *bp;
+       struct bpf_event_tracker *t = NULL;
+       int ret = ENOENT;
+
+       mutex_enter(&bpf_mtx);
+       BPF_IFLIST_WRITER_FOREACH(bp) {
+               if (bp->bif_driverp != driverp)
+                       continue;
+               SLIST_FOREACH(t, &bp->bif_trackers, bet_entries) {
+                       if (t->bet_notify == _fun) {
+                               ret = 0;
+                               break;
+                       }
+               }
+               if (ret == 0)
+                       break;
+       }
+       if (ret == 0 && t && t->bet_notify == _fun) {
+               SLIST_REMOVE(&bp->bif_trackers, t, bpf_event_tracker,
+                   bet_entries);
+       }
+       mutex_exit(&bpf_mtx);
+       if (ret == 0)
+               kmem_free(t, sizeof(*t));
+       return ret;
+}
+
 struct bpf_ops bpf_ops_kernel = {
        .bpf_attach =           _bpfattach,
        .bpf_detach =           _bpfdetach,
        .bpf_change_type =      _bpf_change_type,
+       .bpf_register_track_event = _bpf_register_track_event,
+       .bpf_deregister_track_event = _bpf_deregister_track_event,
 
        .bpf_mtap =             _bpf_mtap,
        .bpf_mtap2 =            _bpf_mtap2,
diff -r 48b25793a34e -r c0ab9415d8bb sys/net/bpf.h
--- a/sys/net/bpf.h     Wed Jun 09 15:38:39 2021 +0000
+++ b/sys/net/bpf.h     Wed Jun 09 15:44:15 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpf.h,v 1.76 2021/06/09 15:38:39 martin Exp $  */
+/*     $NetBSD: bpf.h,v 1.77 2021/06/09 15:44:15 martin Exp $  */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -450,6 +450,11 @@
 
        void (*bpf_mtap_softint_init)(struct ifnet *);
        void (*bpf_mtap_softint)(struct ifnet *, struct mbuf *);
+
+       int (*bpf_register_track_event)(struct bpf_if **,
+           void (*)(struct bpf_if *, struct ifnet *, int, int));
+       int (*bpf_deregister_track_event)(struct bpf_if **,
+           void (*)(struct bpf_if *, struct ifnet *, int, int));
 };
 
 extern struct bpf_ops *bpf_ops;
@@ -545,6 +550,24 @@
                bpf_ops->bpf_mtap_softint(_ifp, _m);
 }
 
+static __inline int
+bpf_register_track_event(struct bpf_if **_dp,
+           void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
+{
+       if (bpf_ops->bpf_register_track_event == NULL)
+               return ENXIO;
+       return bpf_ops->bpf_register_track_event(_dp, _fun);
+}
+
+static __inline int
+bpf_deregister_track_event(struct bpf_if **_dp,
+           void (*_fun)(struct bpf_if *, struct ifnet *, int, int))
+{
+       if (bpf_ops->bpf_deregister_track_event == NULL)
+               return ENXIO;
+       return bpf_ops->bpf_deregister_track_event(_dp, _fun);
+}
+
 void   bpf_setops(void);
 
 void   bpf_ops_handover_enter(struct bpf_ops *);
@@ -570,6 +593,12 @@
 
 u_int  bpf_filter_with_aux_data(const struct bpf_insn *, const u_char *, u_int, u_int, const struct bpf_aux_data *);
 
+/*
+ * events to be tracked by bpf_register_track_event callbacks
+ */
+#define        BPF_TRACK_EVENT_ATTACH  1
+#define        BPF_TRACK_EVENT_DETACH  2
+
 
 __END_DECLS
 
diff -r 48b25793a34e -r c0ab9415d8bb sys/net/bpfdesc.h
--- a/sys/net/bpfdesc.h Wed Jun 09 15:38:39 2021 +0000
+++ b/sys/net/bpfdesc.h Wed Jun 09 15:44:15 2021 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: bpfdesc.h,v 1.47 2020/06/11 13:36:20 roy Exp $ */
+/*     $NetBSD: bpfdesc.h,v 1.48 2021/06/09 15:44:15 martin Exp $      */
 
 /*
  * Copyright (c) 1990, 1991, 1993
@@ -162,6 +162,14 @@
 
 
 /*
+ * Record for each event tracker watching a tap point
+ */
+struct bpf_event_tracker {
+       SLIST_ENTRY(bpf_event_tracker) bet_entries;
+       void (*bet_notify)(struct bpf_if *, struct ifnet *, int, int);
+};
+
+/*
  * Descriptor associated with each attached hardware interface.
  */
 struct bpf_if {
@@ -179,6 +187,7 @@
        struct pslist_entry bif_iflist_entry;
        struct pslist_head bif_dlist_head;
        struct psref_target bif_psref;
+       SLIST_HEAD(, bpf_event_tracker) bif_trackers;
 #endif
 };
 



Home | Main Index | Thread Index | Old Index