aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKristof Provost <kp@FreeBSD.org>2021-02-21 20:18:46 +0000
committerKristof Provost <kp@FreeBSD.org>2021-02-23 12:54:07 +0000
commit89fa9c34d76bbf85cd7cda60c1868f5e3dba4ec7 (patch)
tree93c727da50d4353c47e3e26c79063acdb30ae4d0
parent711ed156b94562c3dcb2ee9c1b3f240f960a75d2 (diff)
downloadsrc-89fa9c34d76bbf85cd7cda60c1868f5e3dba4ec7.tar.gz
src-89fa9c34d76bbf85cd7cda60c1868f5e3dba4ec7.zip
bridge/stp: Ensure we enter NET_EPOCH whenever we can send traffic
Reviewed by: donner@ MFC after: 1 week Sponsored by: Orange Business Services Differential Revision: https://reviews.freebsd.org/D28858
-rw-r--r--sys/net/bridgestp.c9
-rw-r--r--sys/net/if_bridge.c9
2 files changed, 17 insertions, 1 deletions
diff --git a/sys/net/bridgestp.c b/sys/net/bridgestp.c
index c36dc61d1397..82524440c241 100644
--- a/sys/net/bridgestp.c
+++ b/sys/net/bridgestp.c
@@ -154,6 +154,8 @@ static void bstp_reinit(struct bstp_state *);
static void
bstp_transmit(struct bstp_state *bs, struct bstp_port *bp)
{
+ NET_EPOCH_ASSERT();
+
if (bs->bs_running == 0)
return;
@@ -346,6 +348,7 @@ bstp_send_bpdu(struct bstp_state *bs, struct bstp_port *bp,
struct ether_header *eh;
BSTP_LOCK_ASSERT(bs);
+ NET_EPOCH_ASSERT();
ifp = bp->bp_ifp;
@@ -923,6 +926,8 @@ bstp_update_state(struct bstp_state *bs, struct bstp_port *bp)
static void
bstp_update_roles(struct bstp_state *bs, struct bstp_port *bp)
{
+ NET_EPOCH_ASSERT();
+
switch (bp->bp_role) {
case BSTP_ROLE_DISABLED:
/* Clear any flags if set */
@@ -1862,6 +1867,7 @@ bstp_disable_port(struct bstp_state *bs, struct bstp_port *bp)
static void
bstp_tick(void *arg)
{
+ struct epoch_tracker et;
struct bstp_state *bs = arg;
struct bstp_port *bp;
@@ -1870,6 +1876,7 @@ bstp_tick(void *arg)
if (bs->bs_running == 0)
return;
+ NET_EPOCH_ENTER(et);
CURVNET_SET(bs->bs_vnet);
/* poll link events on interfaces that do not support linkstate */
@@ -1908,6 +1915,7 @@ bstp_tick(void *arg)
}
CURVNET_RESTORE();
+ NET_EPOCH_EXIT(et);
callout_reset(&bs->bs_bstpcallout, hz, bstp_tick, bs);
}
@@ -2229,6 +2237,7 @@ bstp_enable(struct bstp_port *bp)
struct ifnet *ifp = bp->bp_ifp;
KASSERT(bp->bp_active == 0, ("already a bstp member"));
+ NET_EPOCH_ASSERT(); /* Because bstp_update_roles() causes traffic. */
switch (ifp->if_type) {
case IFT_ETHER: /* These can do spanning tree. */
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 7c4e48ff04c6..3dba672aa0fe 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1326,6 +1326,7 @@ bridge_ioctl_gifflags(struct bridge_softc *sc, void *arg)
static int
bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
{
+ struct epoch_tracker et;
struct ifbreq *req = arg;
struct bridge_iflist *bif;
struct bstp_port *bp;
@@ -1340,11 +1341,15 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
/* SPAN is readonly */
return (EINVAL);
+ NET_EPOCH_ENTER(et);
+
if (req->ifbr_ifsflags & IFBIF_STP) {
if ((bif->bif_flags & IFBIF_STP) == 0) {
error = bstp_enable(&bif->bif_stp);
- if (error)
+ if (error) {
+ NET_EPOCH_EXIT(et);
return (error);
+ }
}
} else {
if ((bif->bif_flags & IFBIF_STP) != 0)
@@ -1360,6 +1365,8 @@ bridge_ioctl_sifflags(struct bridge_softc *sc, void *arg)
/* Save the bits relating to the bridge */
bif->bif_flags = req->ifbr_ifsflags & IFBIFMASK;
+ NET_EPOCH_EXIT(et);
+
return (0);
}