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
This commit is contained in:
Mark Johnston 2024-09-06 16:55:42 +00:00
parent 39667ed7ad
commit 58f194223a
2 changed files with 15 additions and 3 deletions

View File

@ -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 *

View File

@ -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 */
/*