diff --git a/sys/net/if.c b/sys/net/if.c --- a/sys/net/if.c +++ b/sys/net/if.c @@ -2611,7 +2611,12 @@ (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 increment a counter when toggling them. + */ if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { if (new_flags & IFF_PPROMISC) ifp->if_flags |= IFF_PROMISC; @@ -2622,6 +2627,12 @@ ((new_flags & IFF_PPROMISC) ? "enabled" : "disabled")); } + if ((ifp->if_flags ^ new_flags) & IFF_ALLMULTI) { + if (new_flags & IFF_ALLMULTI) + 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) {