diff options
| author | Gleb Smirnoff <glebius@FreeBSD.org> | 2019-10-21 17:59:02 +0000 |
|---|---|---|
| committer | Gleb Smirnoff <glebius@FreeBSD.org> | 2019-10-21 17:59:02 +0000 |
| commit | 7dce56596f36f124ae0f77b234f16920489f8869 (patch) | |
| tree | 23f0d9c1e1415dd79746adc1af30de6710f61d8a /sys | |
| parent | 3d5013337a7136f8ee099cb27f0c66160dd27c91 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/dev/virtio/network/if_vtnet.c | 79 |
1 files changed, 38 insertions, 41 deletions
diff --git a/sys/dev/virtio/network/if_vtnet.c b/sys/dev/virtio/network/if_vtnet.c index 46be384aedc3..ee3c2310f2da 100644 --- a/sys/dev/virtio/network/if_vtnet.c +++ b/sys/dev/virtio/network/if_vtnet.c @@ -3285,6 +3285,34 @@ vtnet_rx_filter(struct vtnet_softc *sc) ifp->if_flags & IFF_ALLMULTI ? "enable" : "disable"); } +static u_int +vtnet_copy_ifaddr(void *arg, struct sockaddr_dl *sdl, u_int ucnt) +{ + struct vtnet_softc *sc = arg; + + if (memcmp(LLADDR(sdl), sc->vtnet_hwaddr, ETHER_ADDR_LEN) == 0) + return (0); + + if (ucnt < VTNET_MAX_MAC_ENTRIES) + bcopy(LLADDR(sdl), + &sc->vtnet_mac_filter->vmf_unicast.macs[ucnt], + ETHER_ADDR_LEN); + + return (1); +} + +static u_int +vtnet_copy_maddr(void *arg, struct sockaddr_dl *sdl, u_int mcnt) +{ + struct vtnet_mac_filter *filter = arg; + + if (mcnt < VTNET_MAX_MAC_ENTRIES) + bcopy(LLADDR(sdl), &filter->vmf_multicast.macs[mcnt], + ETHER_ADDR_LEN); + + return (1); +} + static void vtnet_rx_filter_mac(struct vtnet_softc *sc) { @@ -3293,42 +3321,23 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc) struct sglist_seg segs[4]; struct sglist sg; struct ifnet *ifp; - struct ifaddr *ifa; - struct ifmultiaddr *ifma; - int ucnt, mcnt, promisc, allmulti, error; + bool promisc, allmulti; + u_int ucnt, mcnt; + int error; uint8_t ack; ifp = sc->vtnet_ifp; filter = sc->vtnet_mac_filter; - ucnt = 0; - mcnt = 0; - promisc = 0; - allmulti = 0; VTNET_CORE_LOCK_ASSERT(sc); KASSERT(sc->vtnet_flags & VTNET_FLAG_CTRL_RX, ("%s: CTRL_RX feature not negotiated", __func__)); /* Unicast MAC addresses: */ - if_addr_rlock(ifp); - CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { - if (ifa->ifa_addr->sa_family != AF_LINK) - continue; - else if (memcmp(LLADDR((struct sockaddr_dl *)ifa->ifa_addr), - sc->vtnet_hwaddr, ETHER_ADDR_LEN) == 0) - continue; - else if (ucnt == VTNET_MAX_MAC_ENTRIES) { - promisc = 1; - break; - } + ucnt = if_foreach_lladdr(ifp, vtnet_copy_ifaddr, sc); + promisc = (ucnt > VTNET_MAX_MAC_ENTRIES); - bcopy(LLADDR((struct sockaddr_dl *)ifa->ifa_addr), - &filter->vmf_unicast.macs[ucnt], ETHER_ADDR_LEN); - ucnt++; - } - if_addr_runlock(ifp); - - if (promisc != 0) { + if (promisc) { filter->vmf_unicast.nentries = 0; if_printf(ifp, "more than %d MAC addresses assigned, " "falling back to promiscuous mode\n", @@ -3337,22 +3346,10 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc) filter->vmf_unicast.nentries = ucnt; /* Multicast MAC addresses: */ - if_maddr_rlock(ifp); - CK_STAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { - if (ifma->ifma_addr->sa_family != AF_LINK) - continue; - else if (mcnt == VTNET_MAX_MAC_ENTRIES) { - allmulti = 1; - break; - } - - bcopy(LLADDR((struct sockaddr_dl *)ifma->ifma_addr), - &filter->vmf_multicast.macs[mcnt], ETHER_ADDR_LEN); - mcnt++; - } - if_maddr_runlock(ifp); + mcnt = if_foreach_llmaddr(ifp, vtnet_copy_maddr, filter); + allmulti = (mcnt > VTNET_MAX_MAC_ENTRIES); - if (allmulti != 0) { + if (allmulti) { filter->vmf_multicast.nentries = 0; if_printf(ifp, "more than %d multicast MAC addresses " "assigned, falling back to all-multicast mode\n", @@ -3360,7 +3357,7 @@ vtnet_rx_filter_mac(struct vtnet_softc *sc) } else filter->vmf_multicast.nentries = mcnt; - if (promisc != 0 && allmulti != 0) + if (promisc && allmulti) goto out; hdr.class = VIRTIO_NET_CTRL_MAC; |
