David Gwynne([email protected]) on 2021.01.27 17:13:09 +1000:
> 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?
I'd like this.
Previously when i needed something similar, i put the interface into its own
routing domain. But of course that doesnt avoid the packets entering the
stack, just some consequences.
I also think 'monitor' is the right keyword for ifconfig.
ok benno, but manpage is missing
> 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))
>
>