bridge: Change lists to CK_LIST as a peparation for epochification
Prepare the ground for a rework of the bridge locking approach. We will use an epoch-based approach in the datapath and making it safe to iterate over the interface, span and rtnode lists without holding the BRIDGE_LOCK. Replace the relevant lists by their ConcurrencyKit equivalents. No functional change in this commit. Reviewed by: emaste, ae, philip (previous version) Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D24249
This commit is contained in:
parent
2f06c66ad5
commit
dd00a42a6b
@ -229,7 +229,7 @@ extern void nd6_setmtu(struct ifnet *);
|
|||||||
* Bridge interface list entry.
|
* Bridge interface list entry.
|
||||||
*/
|
*/
|
||||||
struct bridge_iflist {
|
struct bridge_iflist {
|
||||||
LIST_ENTRY(bridge_iflist) bif_next;
|
CK_LIST_ENTRY(bridge_iflist) bif_next;
|
||||||
struct ifnet *bif_ifp; /* member if */
|
struct ifnet *bif_ifp; /* member if */
|
||||||
struct bstp_port bif_stp; /* STP state */
|
struct bstp_port bif_stp; /* STP state */
|
||||||
uint32_t bif_flags; /* member if flags */
|
uint32_t bif_flags; /* member if flags */
|
||||||
@ -243,8 +243,8 @@ struct bridge_iflist {
|
|||||||
* Bridge route node.
|
* Bridge route node.
|
||||||
*/
|
*/
|
||||||
struct bridge_rtnode {
|
struct bridge_rtnode {
|
||||||
LIST_ENTRY(bridge_rtnode) brt_hash; /* hash table linkage */
|
CK_LIST_ENTRY(bridge_rtnode) brt_hash; /* hash table linkage */
|
||||||
LIST_ENTRY(bridge_rtnode) brt_list; /* list linkage */
|
CK_LIST_ENTRY(bridge_rtnode) brt_list; /* list linkage */
|
||||||
struct bridge_iflist *brt_dst; /* destination if */
|
struct bridge_iflist *brt_dst; /* destination if */
|
||||||
unsigned long brt_expire; /* expiration time */
|
unsigned long brt_expire; /* expiration time */
|
||||||
uint8_t brt_flags; /* address flags */
|
uint8_t brt_flags; /* address flags */
|
||||||
@ -267,11 +267,11 @@ struct bridge_softc {
|
|||||||
struct callout sc_brcallout; /* bridge callout */
|
struct callout sc_brcallout; /* bridge callout */
|
||||||
uint32_t sc_iflist_ref; /* refcount for sc_iflist */
|
uint32_t sc_iflist_ref; /* refcount for sc_iflist */
|
||||||
uint32_t sc_iflist_xcnt; /* refcount for sc_iflist */
|
uint32_t sc_iflist_xcnt; /* refcount for sc_iflist */
|
||||||
LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */
|
CK_LIST_HEAD(, bridge_iflist) sc_iflist; /* member interface list */
|
||||||
LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */
|
CK_LIST_HEAD(, bridge_rtnode) *sc_rthash; /* our forwarding table */
|
||||||
LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */
|
CK_LIST_HEAD(, bridge_rtnode) sc_rtlist; /* list version of above */
|
||||||
uint32_t sc_rthash_key; /* key for hash */
|
uint32_t sc_rthash_key; /* key for hash */
|
||||||
LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */
|
CK_LIST_HEAD(, bridge_iflist) sc_spanlist; /* span ports list */
|
||||||
struct bstp_state sc_stp; /* STP state */
|
struct bstp_state sc_stp; /* STP state */
|
||||||
uint32_t sc_brtexceeded; /* # of cache drops */
|
uint32_t sc_brtexceeded; /* # of cache drops */
|
||||||
struct ifnet *sc_ifaddr; /* member mac copied from */
|
struct ifnet *sc_ifaddr; /* member mac copied from */
|
||||||
@ -697,8 +697,8 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
|
|||||||
|
|
||||||
callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
|
callout_init_mtx(&sc->sc_brcallout, &sc->sc_mtx, 0);
|
||||||
|
|
||||||
LIST_INIT(&sc->sc_iflist);
|
CK_LIST_INIT(&sc->sc_iflist);
|
||||||
LIST_INIT(&sc->sc_spanlist);
|
CK_LIST_INIT(&sc->sc_spanlist);
|
||||||
|
|
||||||
ifp->if_softc = sc;
|
ifp->if_softc = sc;
|
||||||
if_initname(ifp, bridge_name, unit);
|
if_initname(ifp, bridge_name, unit);
|
||||||
@ -774,10 +774,10 @@ bridge_clone_destroy(struct ifnet *ifp)
|
|||||||
bridge_stop(ifp, 1);
|
bridge_stop(ifp, 1);
|
||||||
ifp->if_flags &= ~IFF_UP;
|
ifp->if_flags &= ~IFF_UP;
|
||||||
|
|
||||||
while ((bif = LIST_FIRST(&sc->sc_iflist)) != NULL)
|
while ((bif = CK_LIST_FIRST(&sc->sc_iflist)) != NULL)
|
||||||
bridge_delete_member(sc, bif, 0);
|
bridge_delete_member(sc, bif, 0);
|
||||||
|
|
||||||
while ((bif = LIST_FIRST(&sc->sc_spanlist)) != NULL) {
|
while ((bif = CK_LIST_FIRST(&sc->sc_spanlist)) != NULL) {
|
||||||
bridge_delete_span(sc, bif);
|
bridge_delete_span(sc, bif);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -916,12 +916,12 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
|
|||||||
error = EINVAL;
|
error = EINVAL;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (LIST_EMPTY(&sc->sc_iflist)) {
|
if (CK_LIST_EMPTY(&sc->sc_iflist)) {
|
||||||
sc->sc_ifp->if_mtu = ifr->ifr_mtu;
|
sc->sc_ifp->if_mtu = ifr->ifr_mtu;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
BRIDGE_LOCK(sc);
|
BRIDGE_LOCK(sc);
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (bif->bif_ifp->if_mtu != ifr->ifr_mtu) {
|
if (bif->bif_ifp->if_mtu != ifr->ifr_mtu) {
|
||||||
log(LOG_NOTICE, "%s: invalid MTU: %u(%s)"
|
log(LOG_NOTICE, "%s: invalid MTU: %u(%s)"
|
||||||
" != %d\n", sc->sc_ifp->if_xname,
|
" != %d\n", sc->sc_ifp->if_xname,
|
||||||
@ -961,13 +961,13 @@ bridge_mutecaps(struct bridge_softc *sc)
|
|||||||
/* Initial bitmask of capabilities to test */
|
/* Initial bitmask of capabilities to test */
|
||||||
mask = BRIDGE_IFCAPS_MASK;
|
mask = BRIDGE_IFCAPS_MASK;
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
/* Every member must support it or its disabled */
|
/* Every member must support it or its disabled */
|
||||||
mask &= bif->bif_savedcaps;
|
mask &= bif->bif_savedcaps;
|
||||||
}
|
}
|
||||||
|
|
||||||
BRIDGE_XLOCK(sc);
|
BRIDGE_XLOCK(sc);
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
enabled = bif->bif_ifp->if_capenable;
|
enabled = bif->bif_ifp->if_capenable;
|
||||||
enabled &= ~BRIDGE_IFCAPS_STRIP;
|
enabled &= ~BRIDGE_IFCAPS_STRIP;
|
||||||
/* strip off mask bits and enable them again if allowed */
|
/* strip off mask bits and enable them again if allowed */
|
||||||
@ -1021,7 +1021,7 @@ bridge_lookup_member(struct bridge_softc *sc, const char *name)
|
|||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
ifp = bif->bif_ifp;
|
ifp = bif->bif_ifp;
|
||||||
if (strcmp(ifp->if_xname, name) == 0)
|
if (strcmp(ifp->if_xname, name) == 0)
|
||||||
return (bif);
|
return (bif);
|
||||||
@ -1042,7 +1042,7 @@ bridge_lookup_member_if(struct bridge_softc *sc, struct ifnet *member_ifp)
|
|||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (bif->bif_ifp == member_ifp)
|
if (bif->bif_ifp == member_ifp)
|
||||||
return (bif);
|
return (bif);
|
||||||
}
|
}
|
||||||
@ -1061,6 +1061,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
|||||||
{
|
{
|
||||||
struct ifnet *ifs = bif->bif_ifp;
|
struct ifnet *ifs = bif->bif_ifp;
|
||||||
struct ifnet *fif = NULL;
|
struct ifnet *fif = NULL;
|
||||||
|
struct bridge_iflist *bifl;
|
||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
@ -1069,7 +1070,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
|||||||
|
|
||||||
ifs->if_bridge = NULL;
|
ifs->if_bridge = NULL;
|
||||||
BRIDGE_XLOCK(sc);
|
BRIDGE_XLOCK(sc);
|
||||||
LIST_REMOVE(bif, bif_next);
|
CK_LIST_REMOVE(bif, bif_next);
|
||||||
BRIDGE_XDROP(sc);
|
BRIDGE_XDROP(sc);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1078,12 +1079,13 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
|||||||
* to its default address if no members are left.
|
* to its default address if no members are left.
|
||||||
*/
|
*/
|
||||||
if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) {
|
if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) {
|
||||||
if (LIST_EMPTY(&sc->sc_iflist)) {
|
if (CK_LIST_EMPTY(&sc->sc_iflist)) {
|
||||||
bcopy(&sc->sc_defaddr,
|
bcopy(&sc->sc_defaddr,
|
||||||
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
||||||
sc->sc_ifaddr = NULL;
|
sc->sc_ifaddr = NULL;
|
||||||
} else {
|
} else {
|
||||||
fif = LIST_FIRST(&sc->sc_iflist)->bif_ifp;
|
bifl = CK_LIST_FIRST(&sc->sc_iflist);
|
||||||
|
fif = bifl->bif_ifp;
|
||||||
bcopy(IF_LLADDR(fif),
|
bcopy(IF_LLADDR(fif),
|
||||||
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
||||||
sc->sc_ifaddr = fif;
|
sc->sc_ifaddr = fif;
|
||||||
@ -1144,7 +1146,7 @@ bridge_delete_span(struct bridge_softc *sc, struct bridge_iflist *bif)
|
|||||||
KASSERT(bif->bif_ifp->if_bridge == NULL,
|
KASSERT(bif->bif_ifp->if_bridge == NULL,
|
||||||
("%s: not a span interface", __func__));
|
("%s: not a span interface", __func__));
|
||||||
|
|
||||||
LIST_REMOVE(bif, bif_next);
|
CK_LIST_REMOVE(bif, bif_next);
|
||||||
free(bif, M_DEVBUF);
|
free(bif, M_DEVBUF);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1163,7 +1165,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
return (EINVAL);
|
return (EINVAL);
|
||||||
|
|
||||||
/* If it's in the span list, it can't be a member. */
|
/* If it's in the span list, it can't be a member. */
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
||||||
if (ifs == bif->bif_ifp)
|
if (ifs == bif->bif_ifp)
|
||||||
return (EBUSY);
|
return (EBUSY);
|
||||||
|
|
||||||
@ -1202,7 +1204,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
* interfaces.
|
* interfaces.
|
||||||
*/
|
*/
|
||||||
BRIDGE_XLOCK(sc);
|
BRIDGE_XLOCK(sc);
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (in6ifa_llaonifp(bif->bif_ifp)) {
|
if (in6ifa_llaonifp(bif->bif_ifp)) {
|
||||||
BRIDGE_UNLOCK(sc);
|
BRIDGE_UNLOCK(sc);
|
||||||
in6_ifdetach(bif->bif_ifp);
|
in6_ifdetach(bif->bif_ifp);
|
||||||
@ -1228,7 +1230,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/* Allow the first Ethernet member to define the MTU */
|
/* Allow the first Ethernet member to define the MTU */
|
||||||
if (LIST_EMPTY(&sc->sc_iflist))
|
if (CK_LIST_EMPTY(&sc->sc_iflist))
|
||||||
sc->sc_ifp->if_mtu = ifs->if_mtu;
|
sc->sc_ifp->if_mtu = ifs->if_mtu;
|
||||||
else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
|
else if (sc->sc_ifp->if_mtu != ifs->if_mtu) {
|
||||||
if_printf(sc->sc_ifp, "invalid MTU: %u(%s) != %u\n",
|
if_printf(sc->sc_ifp, "invalid MTU: %u(%s) != %u\n",
|
||||||
@ -1249,7 +1251,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
* member and the MAC address of the bridge has not been changed from
|
* member and the MAC address of the bridge has not been changed from
|
||||||
* the default randomly generated one.
|
* the default randomly generated one.
|
||||||
*/
|
*/
|
||||||
if (V_bridge_inherit_mac && LIST_EMPTY(&sc->sc_iflist) &&
|
if (V_bridge_inherit_mac && CK_LIST_EMPTY(&sc->sc_iflist) &&
|
||||||
!memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr.octet, ETHER_ADDR_LEN)) {
|
!memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr.octet, ETHER_ADDR_LEN)) {
|
||||||
bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN);
|
||||||
sc->sc_ifaddr = ifs;
|
sc->sc_ifaddr = ifs;
|
||||||
@ -1266,7 +1268,7 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
*
|
*
|
||||||
* NOTE: insert_***HEAD*** should be safe for the traversals.
|
* NOTE: insert_***HEAD*** should be safe for the traversals.
|
||||||
*/
|
*/
|
||||||
LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
|
CK_LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next);
|
||||||
|
|
||||||
/* Set interface capabilities to the intersection set of all members */
|
/* Set interface capabilities to the intersection set of all members */
|
||||||
bridge_mutecaps(sc);
|
bridge_mutecaps(sc);
|
||||||
@ -1413,9 +1415,9 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
|
|||||||
int count, buflen, len, error = 0;
|
int count, buflen, len, error = 0;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next)
|
||||||
count++;
|
count++;
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
||||||
count++;
|
count++;
|
||||||
|
|
||||||
buflen = sizeof(breq) * count;
|
buflen = sizeof(breq) * count;
|
||||||
@ -1431,7 +1433,7 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
|
|||||||
buf = outbuf;
|
buf = outbuf;
|
||||||
len = min(bifc->ifbic_len, buflen);
|
len = min(bifc->ifbic_len, buflen);
|
||||||
bzero(&breq, sizeof(breq));
|
bzero(&breq, sizeof(breq));
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (len < sizeof(breq))
|
if (len < sizeof(breq))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1446,7 +1448,7 @@ bridge_ioctl_gifs(struct bridge_softc *sc, void *arg)
|
|||||||
buf += sizeof(breq);
|
buf += sizeof(breq);
|
||||||
len -= sizeof(breq);
|
len -= sizeof(breq);
|
||||||
}
|
}
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
|
||||||
if (len < sizeof(breq))
|
if (len < sizeof(breq))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1481,7 +1483,7 @@ bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
|
|||||||
return (0);
|
return (0);
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
LIST_FOREACH(brt, &sc->sc_rtlist, brt_list)
|
CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list)
|
||||||
count++;
|
count++;
|
||||||
buflen = sizeof(bareq) * count;
|
buflen = sizeof(bareq) * count;
|
||||||
|
|
||||||
@ -1493,7 +1495,7 @@ bridge_ioctl_rts(struct bridge_softc *sc, void *arg)
|
|||||||
buf = outbuf;
|
buf = outbuf;
|
||||||
len = min(bac->ifbac_len, buflen);
|
len = min(bac->ifbac_len, buflen);
|
||||||
bzero(&bareq, sizeof(bareq));
|
bzero(&bareq, sizeof(bareq));
|
||||||
LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
|
CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
|
||||||
if (len < sizeof(bareq))
|
if (len < sizeof(bareq))
|
||||||
goto out;
|
goto out;
|
||||||
strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
|
strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname,
|
||||||
@ -1696,7 +1698,7 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
|
|||||||
if (ifs == NULL)
|
if (ifs == NULL)
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
||||||
if (ifs == bif->bif_ifp)
|
if (ifs == bif->bif_ifp)
|
||||||
return (EBUSY);
|
return (EBUSY);
|
||||||
|
|
||||||
@ -1719,7 +1721,7 @@ bridge_ioctl_addspan(struct bridge_softc *sc, void *arg)
|
|||||||
bif->bif_ifp = ifs;
|
bif->bif_ifp = ifs;
|
||||||
bif->bif_flags = IFBIF_SPAN;
|
bif->bif_flags = IFBIF_SPAN;
|
||||||
|
|
||||||
LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
|
CK_LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next);
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
@ -1735,7 +1737,7 @@ bridge_ioctl_delspan(struct bridge_softc *sc, void *arg)
|
|||||||
if (ifs == NULL)
|
if (ifs == NULL)
|
||||||
return (ENOENT);
|
return (ENOENT);
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
||||||
if (ifs == bif->bif_ifp)
|
if (ifs == bif->bif_ifp)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1797,7 +1799,7 @@ bridge_ioctl_gifsstp(struct bridge_softc *sc, void *arg)
|
|||||||
int count, buflen, len, error = 0;
|
int count, buflen, len, error = 0;
|
||||||
|
|
||||||
count = 0;
|
count = 0;
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if ((bif->bif_flags & IFBIF_STP) != 0)
|
if ((bif->bif_flags & IFBIF_STP) != 0)
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
@ -1816,7 +1818,7 @@ bridge_ioctl_gifsstp(struct bridge_softc *sc, void *arg)
|
|||||||
buf = outbuf;
|
buf = outbuf;
|
||||||
len = min(bifstp->ifbpstp_len, buflen);
|
len = min(bifstp->ifbpstp_len, buflen);
|
||||||
bzero(&bpreq, sizeof(bpreq));
|
bzero(&bpreq, sizeof(bpreq));
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (len < sizeof(bpreq))
|
if (len < sizeof(bpreq))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1898,7 +1900,7 @@ bridge_ifdetach(void *arg __unused, struct ifnet *ifp)
|
|||||||
BRIDGE_LIST_LOCK();
|
BRIDGE_LIST_LOCK();
|
||||||
LIST_FOREACH(sc, &V_bridge_list, sc_list) {
|
LIST_FOREACH(sc, &V_bridge_list, sc_list) {
|
||||||
BRIDGE_LOCK(sc);
|
BRIDGE_LOCK(sc);
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next)
|
||||||
if (ifp == bif->bif_ifp) {
|
if (ifp == bif->bif_ifp) {
|
||||||
bridge_delete_span(sc, bif);
|
bridge_delete_span(sc, bif);
|
||||||
break;
|
break;
|
||||||
@ -2113,7 +2115,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
dst_if = bif->bif_ifp;
|
dst_if = bif->bif_ifp;
|
||||||
|
|
||||||
if (dst_if->if_type == IFT_GIF)
|
if (dst_if->if_type == IFT_GIF)
|
||||||
@ -2131,7 +2133,7 @@ bridge_output(struct ifnet *ifp, struct mbuf *m, struct sockaddr *sa,
|
|||||||
bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
|
bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (LIST_NEXT(bif, bif_next) == NULL) {
|
if (CK_LIST_NEXT(bif, bif_next) == NULL) {
|
||||||
used = 1;
|
used = 1;
|
||||||
mc = m;
|
mc = m;
|
||||||
} else {
|
} else {
|
||||||
@ -2546,7 +2548,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
|
|||||||
do { GRAB_OUR_PACKETS(ifp) } while (0);
|
do { GRAB_OUR_PACKETS(ifp) } while (0);
|
||||||
|
|
||||||
/* Now check the all bridge members. */
|
/* Now check the all bridge members. */
|
||||||
LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) {
|
||||||
GRAB_OUR_PACKETS(bif2->bif_ifp)
|
GRAB_OUR_PACKETS(bif2->bif_ifp)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2599,7 +2601,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) {
|
||||||
dst_if = dbif->bif_ifp;
|
dst_if = dbif->bif_ifp;
|
||||||
if (dst_if == src_if)
|
if (dst_if == src_if)
|
||||||
continue;
|
continue;
|
||||||
@ -2619,7 +2621,7 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
|
|||||||
if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
if (LIST_NEXT(dbif, bif_next) == NULL) {
|
if (CK_LIST_NEXT(dbif, bif_next) == NULL) {
|
||||||
mc = m;
|
mc = m;
|
||||||
used = 1;
|
used = 1;
|
||||||
} else {
|
} else {
|
||||||
@ -2677,10 +2679,10 @@ bridge_span(struct bridge_softc *sc, struct mbuf *m)
|
|||||||
struct ifnet *dst_if;
|
struct ifnet *dst_if;
|
||||||
struct mbuf *mc;
|
struct mbuf *mc;
|
||||||
|
|
||||||
if (LIST_EMPTY(&sc->sc_spanlist))
|
if (CK_LIST_EMPTY(&sc->sc_spanlist))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) {
|
||||||
dst_if = bif->bif_ifp;
|
dst_if = bif->bif_ifp;
|
||||||
|
|
||||||
if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
|
||||||
@ -2816,7 +2818,7 @@ bridge_rttrim(struct bridge_softc *sc)
|
|||||||
if (sc->sc_brtcnt <= sc->sc_brtmax)
|
if (sc->sc_brtcnt <= sc->sc_brtmax)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
||||||
if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
|
if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
|
||||||
bridge_rtnode_destroy(sc, brt);
|
bridge_rtnode_destroy(sc, brt);
|
||||||
if (sc->sc_brtcnt <= sc->sc_brtmax)
|
if (sc->sc_brtcnt <= sc->sc_brtmax)
|
||||||
@ -2859,7 +2861,7 @@ bridge_rtage(struct bridge_softc *sc)
|
|||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
||||||
if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
|
if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) {
|
||||||
if (time_uptime >= brt->brt_expire)
|
if (time_uptime >= brt->brt_expire)
|
||||||
bridge_rtnode_destroy(sc, brt);
|
bridge_rtnode_destroy(sc, brt);
|
||||||
@ -2879,7 +2881,7 @@ bridge_rtflush(struct bridge_softc *sc, int full)
|
|||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
||||||
if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
|
if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)
|
||||||
bridge_rtnode_destroy(sc, brt);
|
bridge_rtnode_destroy(sc, brt);
|
||||||
}
|
}
|
||||||
@ -2922,7 +2924,7 @@ bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full)
|
|||||||
|
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) {
|
||||||
if (brt->brt_ifp == ifp && (full ||
|
if (brt->brt_ifp == ifp && (full ||
|
||||||
(brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
|
(brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC))
|
||||||
bridge_rtnode_destroy(sc, brt);
|
bridge_rtnode_destroy(sc, brt);
|
||||||
@ -2943,10 +2945,10 @@ bridge_rtable_init(struct bridge_softc *sc)
|
|||||||
M_DEVBUF, M_WAITOK);
|
M_DEVBUF, M_WAITOK);
|
||||||
|
|
||||||
for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
|
for (i = 0; i < BRIDGE_RTHASH_SIZE; i++)
|
||||||
LIST_INIT(&sc->sc_rthash[i]);
|
CK_LIST_INIT(&sc->sc_rthash[i]);
|
||||||
|
|
||||||
sc->sc_rthash_key = arc4random();
|
sc->sc_rthash_key = arc4random();
|
||||||
LIST_INIT(&sc->sc_rtlist);
|
CK_LIST_INIT(&sc->sc_rtlist);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -3027,7 +3029,7 @@ bridge_rtnode_lookup(struct bridge_softc *sc, const uint8_t *addr, uint16_t vlan
|
|||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
hash = bridge_rthash(sc, addr);
|
hash = bridge_rthash(sc, addr);
|
||||||
LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
|
CK_LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) {
|
||||||
dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr);
|
dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr);
|
||||||
if (dir == 0 && (brt->brt_vlan == vlan || vlan == 0))
|
if (dir == 0 && (brt->brt_vlan == vlan || vlan == 0))
|
||||||
return (brt);
|
return (brt);
|
||||||
@ -3055,9 +3057,9 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
|
|||||||
|
|
||||||
hash = bridge_rthash(sc, brt->brt_addr);
|
hash = bridge_rthash(sc, brt->brt_addr);
|
||||||
|
|
||||||
lbrt = LIST_FIRST(&sc->sc_rthash[hash]);
|
lbrt = CK_LIST_FIRST(&sc->sc_rthash[hash]);
|
||||||
if (lbrt == NULL) {
|
if (lbrt == NULL) {
|
||||||
LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
|
CK_LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3066,14 +3068,14 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
|
|||||||
if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan)
|
if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan)
|
||||||
return (EEXIST);
|
return (EEXIST);
|
||||||
if (dir > 0) {
|
if (dir > 0) {
|
||||||
LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
|
CK_LIST_INSERT_BEFORE(lbrt, brt, brt_hash);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
if (LIST_NEXT(lbrt, brt_hash) == NULL) {
|
if (CK_LIST_NEXT(lbrt, brt_hash) == NULL) {
|
||||||
LIST_INSERT_AFTER(lbrt, brt, brt_hash);
|
CK_LIST_INSERT_AFTER(lbrt, brt, brt_hash);
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
lbrt = LIST_NEXT(lbrt, brt_hash);
|
lbrt = CK_LIST_NEXT(lbrt, brt_hash);
|
||||||
} while (lbrt != NULL);
|
} while (lbrt != NULL);
|
||||||
|
|
||||||
#ifdef DIAGNOSTIC
|
#ifdef DIAGNOSTIC
|
||||||
@ -3081,7 +3083,7 @@ bridge_rtnode_insert(struct bridge_softc *sc, struct bridge_rtnode *brt)
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
out:
|
out:
|
||||||
LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
|
CK_LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list);
|
||||||
sc->sc_brtcnt++;
|
sc->sc_brtcnt++;
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
@ -3097,9 +3099,9 @@ bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
|
|||||||
{
|
{
|
||||||
BRIDGE_LOCK_ASSERT(sc);
|
BRIDGE_LOCK_ASSERT(sc);
|
||||||
|
|
||||||
LIST_REMOVE(brt, brt_hash);
|
CK_LIST_REMOVE(brt, brt_hash);
|
||||||
|
|
||||||
LIST_REMOVE(brt, brt_list);
|
CK_LIST_REMOVE(brt, brt_list);
|
||||||
sc->sc_brtcnt--;
|
sc->sc_brtcnt--;
|
||||||
brt->brt_dst->bif_addrcnt--;
|
brt->brt_dst->bif_addrcnt--;
|
||||||
uma_zfree(V_bridge_rtnode_zone, brt);
|
uma_zfree(V_bridge_rtnode_zone, brt);
|
||||||
@ -3126,7 +3128,7 @@ bridge_rtable_expire(struct ifnet *ifp, int age)
|
|||||||
if (age == 0)
|
if (age == 0)
|
||||||
bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
|
bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
|
||||||
else {
|
else {
|
||||||
LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
|
CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) {
|
||||||
/* Cap the expiry time to 'age' */
|
/* Cap the expiry time to 'age' */
|
||||||
if (brt->brt_ifp == ifp &&
|
if (brt->brt_ifp == ifp &&
|
||||||
brt->brt_expire > time_uptime + age &&
|
brt->brt_expire > time_uptime + age &&
|
||||||
@ -3664,7 +3666,7 @@ bridge_linkcheck(struct bridge_softc *sc)
|
|||||||
new_link = LINK_STATE_DOWN;
|
new_link = LINK_STATE_DOWN;
|
||||||
hasls = 0;
|
hasls = 0;
|
||||||
/* Our link is considered up if at least one of our ports is active */
|
/* Our link is considered up if at least one of our ports is active */
|
||||||
LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
|
||||||
if (bif->bif_ifp->if_capabilities & IFCAP_LINKSTATE)
|
if (bif->bif_ifp->if_capabilities & IFCAP_LINKSTATE)
|
||||||
hasls++;
|
hasls++;
|
||||||
if (bif->bif_ifp->if_link_state == LINK_STATE_UP) {
|
if (bif->bif_ifp->if_link_state == LINK_STATE_UP) {
|
||||||
@ -3672,7 +3674,7 @@ bridge_linkcheck(struct bridge_softc *sc)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (!LIST_EMPTY(&sc->sc_iflist) && !hasls) {
|
if (!CK_LIST_EMPTY(&sc->sc_iflist) && !hasls) {
|
||||||
/* If no interfaces support link-state then we default to up */
|
/* If no interfaces support link-state then we default to up */
|
||||||
new_link = LINK_STATE_UP;
|
new_link = LINK_STATE_UP;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user