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))