add BIOCSETFNR, which is like BIOCSETF but doesnt reset the buffer or stats.
authordlg <dlg@openbsd.org>
Thu, 15 Aug 2024 12:20:20 +0000 (12:20 +0000)
committerdlg <dlg@openbsd.org>
Thu, 15 Aug 2024 12:20:20 +0000 (12:20 +0000)
from Matthew Luckie <mjl@luckie.org.nz> via tech@
deraadt@ likes it.

share/man/man4/bpf.4
sys/net/bpf.c
sys/net/bpf.h
sys/net/bpfdesc.h

index 4990dc8..2c5d476 100644 (file)
@@ -1,4 +1,4 @@
-.\"    $OpenBSD: bpf.4,v 1.46 2024/08/05 23:56:10 dlg Exp $
+.\"    $OpenBSD: bpf.4,v 1.47 2024/08/15 12:20:20 dlg Exp $
 .\"     $NetBSD: bpf.4,v 1.7 1995/09/27 18:31:50 thorpej Exp $
 .\"
 .\" Copyright (c) 1990 The Regents of the University of California.
@@ -23,7 +23,7 @@
 .\" This document is derived in part from the enet man page (enet.4)
 .\" distributed with 4.3BSD Unix.
 .\"
-.Dd $Mdocdate: August 5 2024 $
+.Dd $Mdocdate: August 15 2024 $
 .Dt BPF 4
 .Os
 .Sh NAME
@@ -318,6 +318,7 @@ readable.
 The maximum wait time that can be set is 5 minutes (300 seconds).
 .Pp
 .It Dv BIOCSETF Fa "struct bpf_program *"
+.It Dv BIOCSETFNR Fa "struct bpf_program *"
 Sets the filter program used by the kernel to discard uninteresting packets.
 An array of instructions and its length are passed in using the following
 structure:
@@ -335,9 +336,11 @@ field, while its length in units of
 is given by the
 .Fa bf_len
 field.
-Also, the actions of
+If
+.Dv BIOCSETF
+is used, the actions of
 .Dv BIOCFLUSH
-are performed.
+are also performed.
 .Pp
 See section
 .Sx FILTER MACHINE
@@ -350,8 +353,6 @@ network.
 See
 .Dv BIOCSETF
 for a description of the filter program.
-This ioctl also acts as
-.Dv BIOCFLUSH .
 .Pp
 Note that the filter operates on the packet data written to the descriptor.
 If the
index b7c2f1b..d77ad57 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.c,v 1.224 2024/08/12 17:02:58 mvs Exp $   */
+/*     $OpenBSD: bpf.c,v 1.225 2024/08/15 12:20:20 dlg Exp $   */
 /*     $NetBSD: bpf.c,v 1.33 1997/02/21 23:59:35 thorpej Exp $ */
 
 /*
@@ -760,7 +760,8 @@ bpf_get_wtimeout(struct bpf_d *d, struct timeval *tv)
 /*
  *  FIONREAD           Check for read packet available.
  *  BIOCGBLEN          Get buffer len [for read()].
- *  BIOCSETF           Set ethernet read filter.
+ *  BIOCSETF           Set read filter.
+ *  BIOCSETFNR          Set read filter without resetting descriptor.
  *  BIOCFLUSH          Flush read packet buffer.
  *  BIOCPROMISC                Put interface into promiscuous mode.
  *  BIOCGDLTLIST       Get supported link layer types.
@@ -867,17 +868,12 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
                break;
 
        /*
-        * Set link layer read filter.
+        * Set link layer read/write filter.
         */
        case BIOCSETF:
-               error = bpf_setf(d, (struct bpf_program *)addr, 0);
-               break;
-
-       /*
-        * Set link layer write filter.
-        */
+       case BIOCSETFNR:
        case BIOCSETWF:
-               error = bpf_setf(d, (struct bpf_program *)addr, 1);
+               error = bpf_setf(d, (struct bpf_program *)addr, cmd);
                break;
 
        /*
@@ -1122,7 +1118,7 @@ bpfioctl(dev_t dev, u_long cmd, caddr_t addr, int flag, struct proc *p)
  * free it and replace it.  Returns EINVAL for bogus requests.
  */
 int
-bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
+bpf_setf(struct bpf_d *d, struct bpf_program *fp, u_long cmd)
 {
        struct bpf_program_smr *bps, *old_bps;
        struct bpf_insn *fcode;
@@ -1157,7 +1153,7 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
                bps->bps_bf.bf_insns = fcode;
        }
 
-       if (wf == 0) {
+       if (cmd != BIOCSETWF) {
                old_bps = SMR_PTR_GET_LOCKED(&d->bd_rfilter);
                SMR_PTR_SET_LOCKED(&d->bd_rfilter, bps);
        } else {
@@ -1165,9 +1161,12 @@ bpf_setf(struct bpf_d *d, struct bpf_program *fp, int wf)
                SMR_PTR_SET_LOCKED(&d->bd_wfilter, bps);
        }
 
-       mtx_enter(&d->bd_mtx);
-       bpf_resetd(d);
-       mtx_leave(&d->bd_mtx);
+       if (cmd == BIOCSETF) {
+               mtx_enter(&d->bd_mtx);
+               bpf_resetd(d);
+               mtx_leave(&d->bd_mtx);
+       }
+
        if (old_bps != NULL)
                smr_call(&old_bps->bps_smr, bpf_prog_smr, old_bps);
 
index ab64061..91b367c 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpf.h,v 1.72 2024/01/26 21:14:08 jan Exp $    */
+/*     $OpenBSD: bpf.h,v 1.73 2024/08/15 12:20:20 dlg Exp $    */
 /*     $NetBSD: bpf.h,v 1.15 1996/12/13 07:57:33 mikel Exp $   */
 
 /*
@@ -122,6 +122,7 @@ struct bpf_version {
 #define BIOCSWTIMEOUT  _IOW('B',126, struct timeval)
 #define BIOCGWTIMEOUT  _IOR('B',126, struct timeval)
 #define BIOCDWTIMEOUT  _IO('B',126)
+#define BIOCSETFNR     _IOW('B',127, struct bpf_program)
 
 /*
  * Direction filters for BIOCSDIRFILT/BIOCGDIRFILT
index 76b75ff..4b558c4 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: bpfdesc.h,v 1.48 2023/03/09 05:56:58 dlg Exp $        */
+/*     $OpenBSD: bpfdesc.h,v 1.49 2024/08/15 12:20:20 dlg Exp $        */
 /*     $NetBSD: bpfdesc.h,v 1.11 1995/09/27 18:30:42 thorpej Exp $     */
 
 /*
@@ -123,6 +123,6 @@ struct bpf_if {
        struct ifnet *bif_ifp;          /* corresponding interface */
 };
 
-int     bpf_setf(struct bpf_d *, struct bpf_program *, int);
+int     bpf_setf(struct bpf_d *, struct bpf_program *, u_long);
 #endif /* _KERNEL */
 #endif /* _NET_BPFDESC_H_ */