The branch main has been updated by glebius:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=c10447a9256b561bf2edf26b5abf5f28071a15c7

commit c10447a9256b561bf2edf26b5abf5f28071a15c7
Author:     Gleb Smirnoff <[email protected]>
AuthorDate: 2025-12-15 20:51:26 +0000
Commit:     Gleb Smirnoff <[email protected]>
CommitDate: 2025-12-15 20:51:26 +0000

    bpf: add BIOCGETIFLIST ioctl that returns all available tap points
    
    Differential Revision:  https://reviews.freebsd.org/D53873
---
 share/man/man4/bpf.4 | 27 +++++++++++++++++++++-
 sys/net/bpf.c        | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++--
 sys/net/bpf.h        | 10 ++++++++
 sys/sys/param.h      |  2 +-
 4 files changed, 100 insertions(+), 4 deletions(-)

diff --git a/share/man/man4/bpf.4 b/share/man/man4/bpf.4
index 8082f6eac39a..dcf321c40782 100644
--- a/share/man/man4/bpf.4
+++ b/share/man/man4/bpf.4
@@ -47,7 +47,7 @@
 .\" This document is derived in part from the enet man page (enet.4)
 .\" distributed with 4.3BSD Unix.
 .\"
-.Dd October 13, 2021
+.Dd December 10, 2025
 .Dt BPF 4
 .Os
 .Sh NAME
@@ -276,6 +276,31 @@ The (third) argument to
 .Xr ioctl 2
 should be a pointer to the type indicated.
 .Bl -tag -width BIOCGETBUFMODE
+.It Dv BIOCGETIFLIST
+.Pq Li "struct bpf_iflist"
+Returns list of available tapping points, that can later be attached
+to with
+.Dv BIOCSETIF .
+On entry the
+.Vt bi_ubuf
+shall point to user supplied buffer.
+The
+.Vt bi_size
+shall specify length of the buffer, or 0 if the request is used
+to determine the required length.
+The
+.Vt bi_count
+can be used to limit the output to first
+.Va count
+entries, otherwise shall be 0.
+On return, if the buffer length was enough to accomodate all desired entries,
+then the supplied buffer is filled with NUL-terminated names of
+available tapping points and
+.Vt bi_count
+is set to the number of copied names.
+Otherwise
+.Er ENOSPC
+is returned.
 .It Dv BIOCGBLEN
 .Pq Li u_int
 Returns the required buffer length for reads on
diff --git a/sys/net/bpf.c b/sys/net/bpf.c
index 0155b27b4919..4026c44112ab 100644
--- a/sys/net/bpf.c
+++ b/sys/net/bpf.c
@@ -221,8 +221,7 @@ struct bpf_dltlist32 {
  * structures registered by different layers in the stack (i.e., 802.11
  * frames, ethernet frames, etc).
  */
-LIST_HEAD(bpf_iflist, bpf_if);
-static struct bpf_iflist bpf_iflist = LIST_HEAD_INITIALIZER();
+static LIST_HEAD(, bpf_if) bpf_iflist = LIST_HEAD_INITIALIZER();
 static struct sx       bpf_sx;         /* bpf global lock */
 
 static void    bpfif_ref(struct bpf_if *);
@@ -240,6 +239,7 @@ static void catchpacket(struct bpf_d *, u_char *, u_int, 
u_int,
                    void (*)(struct bpf_d *, caddr_t, u_int, void *, u_int),
                    struct bintime *);
 static void    reset_d(struct bpf_d *);
+static int     bpf_getiflist(struct bpf_iflist *);
 static int     bpf_setf(struct bpf_d *, struct bpf_program *, u_long cmd);
 static int     bpf_getdltlist(struct bpf_d *, struct bpf_dltlist *);
 static int     bpf_setdlt(struct bpf_d *, u_int);
@@ -1100,6 +1100,7 @@ reset_d(struct bpf_d *d)
 
 /*
  *  FIONREAD           Check for read packet available.
+ *  BIOCGETIFLIST      Get list of all tap points.
  *  BIOCGBLEN          Get buffer len [for read()].
  *  BIOCSETF           Set read filter.
  *  BIOCSETFNR         Set read filter without resetting descriptor.
@@ -1153,6 +1154,7 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int 
flags,
 
        if (d->bd_flags & BPFD_LOCKED) {
                switch (cmd) {
+               case BIOCGETIFLIST:
                case BIOCGBLEN:
                case BIOCFLUSH:
                case BIOCGDLT:
@@ -1230,6 +1232,12 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int 
flags,
                        *(int *)addr = n;
                        break;
                }
+       /*
+        * Get list of all tap points.
+        */
+       case BIOCGETIFLIST:
+               error = bpf_getiflist((struct bpf_iflist *)addr);
+               break;
 
        /*
         * Get buffer len [for read()].
@@ -1706,6 +1714,59 @@ bpfioctl(struct cdev *dev, u_long cmd, caddr_t addr, int 
flags,
        return (error);
 }
 
+/*
+ * Return list of available tapping points, or report how much space is
+ * required for a successful return.
+ */
+static int
+bpf_getiflist(struct bpf_iflist *bi)
+{
+       struct bpf_if *bp;
+       u_int allsize, size, cnt;
+       char *uaddr;
+
+       BPF_LOCK();
+
+       cnt = allsize = size = 0;
+       LIST_FOREACH(bp, &bpf_iflist, bif_next) {
+               allsize += strlen(bp->bif_name) + 1;
+               if (++cnt == bi->bi_count)
+                       size = allsize;
+       }
+       if (size == 0)
+               size = allsize;
+
+       if (bi->bi_size == 0) {
+               BPF_UNLOCK();
+               bi->bi_size = size;
+               bi->bi_count = cnt;
+               return (0);
+       } else if (bi->bi_size < size) {
+               BPF_UNLOCK();
+               return (ENOSPC);
+       }
+
+       uaddr = bi->bi_ubuf;
+       cnt = 0;
+       LIST_FOREACH(bp, &bpf_iflist, bif_next) {
+               u_int len;
+               int error;
+
+               len = strlen(bp->bif_name) + 1;
+               if ((error = copyout(bp->bif_name, uaddr, len)) != 0) {
+                       BPF_UNLOCK();
+                       return (error);
+               }
+               if (++cnt == bi->bi_count)
+                       break;
+               uaddr += len;
+       }
+       BPF_UNLOCK();
+       bi->bi_count = cnt;
+
+       return (0);
+}
+
 /*
  * Set d's packet filter program to fp. If this file already has a filter,
  * free it and replace it. Returns EINVAL for bogus requests.
diff --git a/sys/net/bpf.h b/sys/net/bpf.h
index cda03c06d51d..f6bcb0e34ed4 100644
--- a/sys/net/bpf.h
+++ b/sys/net/bpf.h
@@ -118,6 +118,15 @@ struct bpf_zbuf {
        size_t   bz_buflen;     /* Size of zero-copy buffers. */
 };
 
+/*
+ * Struct used by BIOCGETIFLIST.
+ */
+struct bpf_iflist {
+       u_int    bi_size;
+       u_int    bi_count;
+       void    *bi_ubuf;
+};
+
 #define        BIOCGBLEN       _IOR('B', 102, u_int)
 #define        BIOCSBLEN       _IOWR('B', 102, u_int)
 #define        BIOCSETF        _IOW('B', 103, struct bpf_program)
@@ -151,6 +160,7 @@ struct bpf_zbuf {
 #define        BIOCGTSTAMP     _IOR('B', 131, u_int)
 #define        BIOCSTSTAMP     _IOW('B', 132, u_int)
 #define        BIOCSETVLANPCP  _IOW('B', 133, u_int)
+#define        BIOCGETIFLIST   _IOWR('B', 134, struct bpf_iflist)
 
 /* Obsolete */
 #define        BIOCGSEESENT    BIOCGDIRECTION
diff --git a/sys/sys/param.h b/sys/sys/param.h
index 003c28c082cb..fa09878507c6 100644
--- a/sys/sys/param.h
+++ b/sys/sys/param.h
@@ -74,7 +74,7 @@
  * cannot include sys/param.h and should only be updated here.
  */
 #undef __FreeBSD_version
-#define __FreeBSD_version 1600005
+#define __FreeBSD_version 1600006
 
 /*
  * __FreeBSD_kernel__ indicates that this system uses the kernel of FreeBSD,

Reply via email to