some of the discussion around dup-to made me think that a diff we
have here at work might be more broadly useful.

we run a box here with a bunch of ethernet ports plugged into span
ports on switches. basically every packet going to our firewalls gets
duplicated to this host. we then have code that generates flow data from
these ports. it's also nice to have one place to ssh to and so you can
tcpdump things. anyway, that flow collector watches packets on those
interfaces via bpf, but apart from that we don't actually want to
do anythign with the packets those interfaces receive. we especially
do not want them entering the stack. we ssh to this box over the
firewall, so if the span port copies those packets to the box and
the stack tries to process them, things dont work great.

we could enable the fildrop stuff with bpf, but there's an annoying gap
between when the interfaces come up and when the flow collector starts
running. also, if the flow collector crashes or we restart it cos we're
hacking on the code, this provides more gaps for packets to enter the
stack.

we prevented this by adding a "monitor" interface flag. it makes the
interface input code drop all the packets rather than queuing them for
the stack to process.

is there any interest in having this in the tree?

if so, i need to do some work to make sure all interfaces push
packets into the stack with if_input, ifiq_input, or if_vinput. a
bunch of them like gif and gre currently call protocol input routines
directly, so they skip this check.

so, thoughts?

Index: sbin/ifconfig/ifconfig.c
===================================================================
RCS file: /cvs/src/sbin/ifconfig/ifconfig.c,v
retrieving revision 1.432
diff -u -p -r1.432 ifconfig.c
--- sbin/ifconfig/ifconfig.c    16 Jan 2021 17:44:29 -0000      1.432
+++ sbin/ifconfig/ifconfig.c    27 Jan 2021 06:57:37 -0000
@@ -469,6 +469,8 @@ const struct        cmd {
        { "soii",       -IFXF_INET6_NOSOII,     0,      setifxflags },
        { "-soii",      IFXF_INET6_NOSOII,      0,      setifxflags },
 #ifndef SMALL
+       { "monitor",    IFXF_MONITOR,   0,              setifxflags },
+       { "-monitor",   -IFXF_MONITOR,  0,              setifxflags },
        { "hwfeatures", NEXTARG0,       0,              printifhwfeatures },
        { "metric",     NEXTARG,        0,              setifmetric },
        { "powersave",  NEXTARG0,       0,              setifpowersave },
@@ -675,7 +677,7 @@ const struct        cmd {
        "\7RUNNING\10NOARP\11PROMISC\12ALLMULTI\13OACTIVE\14SIMPLEX"    \
        "\15LINK0\16LINK1\17LINK2\20MULTICAST"                          \
        "\23INET6_NOPRIVACY\24MPLS\25WOL\26AUTOCONF6\27INET6_NOSOII"    \
-       "\30AUTOCONF4"
+       "\30AUTOCONF4" "\32MONITOR"
 
 int    getinfo(struct ifreq *, int);
 void   getsock(int);
Index: sys/net/if.c
===================================================================
RCS file: /cvs/src/sys/net/if.c,v
retrieving revision 1.625
diff -u -p -r1.625 if.c
--- sys/net/if.c        18 Jan 2021 09:55:43 -0000      1.625
+++ sys/net/if.c        27 Jan 2021 06:57:37 -0000
@@ -860,7 +860,8 @@ if_vinput(struct ifnet *ifp, struct mbuf
        }
 #endif
 
-       (*ifp->if_input)(ifp, m);
+       if (__predict_true(!ISSET(ifp->if_xflags, IFXF_MONITOR)))
+               (*ifp->if_input)(ifp, m);
 }
 
 void
Index: sys/net/if.h
===================================================================
RCS file: /cvs/src/sys/net/if.h,v
retrieving revision 1.205
diff -u -p -r1.205 if.h
--- sys/net/if.h        18 Jan 2021 09:55:43 -0000      1.205
+++ sys/net/if.h        27 Jan 2021 06:57:37 -0000
@@ -230,6 +230,7 @@ struct if_status_description {
 #define        IFXF_AUTOCONF6          0x20    /* [N] v6 autoconf enabled */
 #define IFXF_INET6_NOSOII      0x40    /* [N] don't do RFC 7217 */
 #define        IFXF_AUTOCONF4          0x80    /* [N] v4 autoconf (aka dhcp) 
enabled */
+#define        IFXF_MONITOR            0x200   /* [N] only used for bpf */
 
 #define        IFXF_CANTCHANGE \
        (IFXF_MPSAFE|IFXF_CLONED)
Index: sys/net/ifq.c
===================================================================
RCS file: /cvs/src/sys/net/ifq.c,v
retrieving revision 1.41
diff -u -p -r1.41 ifq.c
--- sys/net/ifq.c       7 Jul 2020 00:00:03 -0000       1.41
+++ sys/net/ifq.c       27 Jan 2021 06:57:37 -0000
@@ -715,10 +715,12 @@ ifiq_input(struct ifiqueue *ifiq, struct
        ifiq->ifiq_bytes += bytes;
 
        len = ml_len(&ifiq->ifiq_ml);
-       if (len > ifiq_maxlen_drop)
-               ifiq->ifiq_qdrops += ml_len(ml);
-       else
-               ml_enlist(&ifiq->ifiq_ml, ml);
+       if (__predict_true(!ISSET(ifp->if_xflags, IFXF_MONITOR))) {
+               if (len > ifiq_maxlen_drop)
+                       ifiq->ifiq_qdrops += ml_len(ml);
+               else
+                       ml_enlist(&ifiq->ifiq_ml, ml);
+       }
        mtx_leave(&ifiq->ifiq_mtx);
 
        if (ml_empty(ml))


Reply via email to