Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -59,6 +59,7 @@ #include #include #include +#include #include #include @@ -2218,6 +2219,7 @@ if_down(struct ifnet *ifp) { + EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_DOWN); if_unroute(ifp, IFF_UP, AF_UNSPEC); } @@ -2308,6 +2310,8 @@ char new_name[IFNAMSIZ]; struct ifaddr *ifa; struct sockaddr_dl *sdl; + bool if_up_done; + ifr = (struct ifreq *)data; switch (cmd) { @@ -2413,6 +2417,8 @@ break; case SIOCSIFFLAGS: + if_up_done = false; + error = priv_check(td, PRIV_NET_SETIFFLAGS); if (error) return (error); @@ -2428,6 +2434,7 @@ } else if (new_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) { if_up(ifp); + if_up_done = true; } /* See if permanently promiscuous mode bit is about to flip */ if ((ifp->if_flags ^ new_flags) & IFF_PPROMISC) { @@ -2446,6 +2453,10 @@ if (ifp->if_ioctl) { (void) (*ifp->if_ioctl)(ifp, cmd, data); } + + if (if_up_done) + EVENTHANDLER_INVOKE(ifnet_event, ifp, IFNET_EVENT_UP); + getmicrotime(&ifp->if_lastchange); break; Index: sys/sys/eventhandler.h =================================================================== --- sys/sys/eventhandler.h +++ sys/sys/eventhandler.h @@ -277,4 +277,11 @@ struct ata_params *, int *); EVENTHANDLER_DECLARE(ada_probe_veto, ada_probe_veto_fn); +/* ifup/ifdown events */ +#define IFNET_EVENT_UP 0 +#define IFNET_EVENT_DOWN 1 +struct ifnet; +typedef void (*ifnet_event_fn)(void *, struct ifnet *ifp, int event); +EVENTHANDLER_DECLARE(ifnet_event, ifnet_event_fn); + #endif /* _SYS_EVENTHANDLER_H_ */