diff --git a/sys/net/if.c b/sys/net/if.c index 42f55b7eb250..427871db3b11 100644 --- a/sys/net/if.c +++ b/sys/net/if.c @@ -4263,6 +4263,55 @@ if_getmtu_family(if_t ifp, int family) return (((struct ifnet *)ifp)->if_mtu); } +/* + * Methods for drivers to access interface unicast and multicast + * link level addresses. Driver shall not know 'struct ifaddr' neither + * 'struct ifmultiaddr'. + */ +u_int +if_foreach_lladdr(if_t ifp, iflladdr_cb_t cb, void *cb_arg) +{ + struct epoch_tracker et; + struct ifaddr *ifa; + u_int count; + + MPASS(cb); + + count = 0; + NET_EPOCH_ENTER(et); + CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { + if (ifa->ifa_addr->sa_family != AF_LINK) + continue; + count += (*cb)(cb_arg, (struct sockaddr_dl *)ifa->ifa_addr, + count); + } + NET_EPOCH_EXIT(et); + + return (count); +} + +u_int +if_foreach_llmaddr(if_t ifp, iflladdr_cb_t cb, void *cb_arg) +{ + struct epoch_tracker et; + struct ifmultiaddr *ifma; + u_int count; + + MPASS(cb); + + count = 0; + NET_EPOCH_ENTER(et); + CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { + if (ifma->ifma_addr->sa_family != AF_LINK) + continue; + count += (*cb)(cb_arg, (struct sockaddr_dl *)ifma->ifma_addr, + count); + } + NET_EPOCH_EXIT(et); + + return (count); +} + int if_setsoftc(if_t ifp, void *softc) { diff --git a/sys/net/if_var.h b/sys/net/if_var.h index 94581357e011..ab34d03d6d6a 100644 --- a/sys/net/if_var.h +++ b/sys/net/if_var.h @@ -765,11 +765,20 @@ void if_bpfmtap(if_t ifp, struct mbuf *m); void if_etherbpfmtap(if_t ifp, struct mbuf *m); void if_vlancap(if_t ifp); -int if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max); -int if_multiaddr_array(if_t ifp, void *mta, int *cnt, int max); +/* + * Traversing through interface address lists. + */ +struct sockaddr_dl; +typedef u_int iflladdr_cb_t(void *, struct sockaddr_dl *, u_int); +u_int if_foreach_lladdr(if_t, iflladdr_cb_t, void *); +u_int if_foreach_llmaddr(if_t, iflladdr_cb_t, void *); int if_multiaddr_count(if_t ifp, int max); +/* Obsoleted multicast management functions. */ +int if_setupmultiaddr(if_t ifp, void *mta, int *cnt, int max); +int if_multiaddr_array(if_t ifp, void *mta, int *cnt, int max); int if_multi_apply(struct ifnet *ifp, int (*filter)(void *, struct ifmultiaddr *, int), void *arg); + int if_getamcount(if_t ifp); struct ifaddr * if_getifaddr(if_t ifp);