The branch stable/14 has been updated by markj:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=772e980da4bd5d47eceee95e91e8573ecb48be1c

commit 772e980da4bd5d47eceee95e91e8573ecb48be1c
Author:     Mark Johnston <ma...@freebsd.org>
AuthorDate: 2024-09-06 16:55:42 +0000
Commit:     Mark Johnston <ma...@freebsd.org>
CommitDate: 2024-09-20 11:39:16 +0000

    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
    
    (cherry picked from commit 58f194223ab8578269772a6874a8444e5e03afaf)
---
 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 9beac09d54c9..fe51ba5a0b60 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -2614,7 +2614,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;
@@ -2625,6 +2630,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) {
@@ -3386,7 +3397,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 4c3cfd06ca03..2403b22c191f 100644
--- a/sys/net/if.h
+++ b/sys/net/if.h
@@ -162,7 +162,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 */
 
 /*

Reply via email to