From 58f194223ab8578269772a6874a8444e5e03afaf Mon Sep 17 00:00:00 2001 From: Mark Johnston Date: Fri, 6 Sep 2024 16:55:42 +0000 Subject: [PATCH] ifnet: Add handling for toggling IFF_ALLMULTI in ifhwioctl() IFF_ALLMULTI has an associated activation counter and so needs special treatment, like IFF_PROMISC. Introduce IFF_PALLMULTI, akin to IFF_PPROMISC, which indicates that userspace requested allmulti mode, and handle it specially in ifhwioctl(). Reviewed by: zlei, glebius MFC after: 2 weeks Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D46524 --- sys/net/if.c | 16 ++++++++++++++-- sys/net/if.h | 2 +- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/sys/net/if.c b/sys/net/if.c index 4458d710d826..ebad5c5d16e5 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2611,7 +2611,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) (ifp->if_flags & IFF_UP) == 0) { do_ifup = 1; } - /* See if permanently promiscuous mode bit is about to flip */ + + /* + * See if the promiscuous mode or allmulti bits are about to + * flip. They require special handling because in-kernel + * consumers may indepdently toggle them. + */ if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { if (new_flags & IFF_PPROMISC) ifp->if_flags |= IFF_PROMISC; @@ -2622,6 +2627,12 @@ ifhwioctl(u_long cmd, struct ifnet *ifp, caddr_t data, struct thread *td) ((new_flags & IFF_PPROMISC) ? "enabled" : "disabled")); } + if ((ifp->if_flags ^ new_flags) & IFF_PALLMULTI) { + if (new_flags & IFF_PALLMULTI) + ifp->if_flags |= IFF_ALLMULTI; + else if (ifp->if_amcount == 0) + ifp->if_flags &= ~IFF_ALLMULTI; + } ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) | (new_flags &~ IFF_CANTCHANGE); if (ifp->if_ioctl) { @@ -3383,7 +3394,8 @@ int if_allmulti(struct ifnet *ifp, int onswitch) { - return (if_setflag(ifp, IFF_ALLMULTI, 0, &ifp->if_amcount, onswitch)); + return (if_setflag(ifp, IFF_ALLMULTI, IFF_PALLMULTI, &ifp->if_amcount, + onswitch)); } struct ifmultiaddr * diff --git a/sys/net/if.h b/sys/net/if.h index 5c4b0637b25a..d54190f6ccf8 100644 --- a/sys/net/if.h +++ b/sys/net/if.h @@ -160,7 +160,7 @@ struct if_data { #define IFF_STICKYARP 0x100000 /* (n) sticky ARP */ #define IFF_DYING 0x200000 /* (n) interface is winding down */ #define IFF_RENAMING 0x400000 /* (n) interface is being renamed */ -#define IFF_SPARE 0x800000 +#define IFF_PALLMULTI 0x800000 /* (n) user-requested allmulti mode */ #define IFF_NETLINK_1 0x1000000 /* (n) used by netlink */ /*