git: c10447a9256b - main - bpf: add BIOCGETIFLIST ioctl that returns all available tap points
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 15 Dec 2025 21:45:31 UTC
The branch main has been updated by glebius:
URL: https://cgit.FreeBSD.org/src/commit/?id=c10447a9256b561bf2edf26b5abf5f28071a15c7
commit c10447a9256b561bf2edf26b5abf5f28071a15c7
Author: Gleb Smirnoff <glebius@FreeBSD.org>
AuthorDate: 2025-12-15 20:51:26 +0000
Commit: Gleb Smirnoff <glebius@FreeBSD.org>
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,