summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2006-08-02 03:54:28 +0000
committerthompsa <thompsa@FreeBSD.org>2006-08-02 03:54:28 +0000
commit6d3413a734a270473fb0033eb36af78dfba3bf8f (patch)
tree4e335be51e37f4703f646c2c8e50fe65b01ba253
parent2c7c629f570494df46e091bcdf982d7fee6519ff (diff)
downloadFreeBSD-src-6d3413a734a270473fb0033eb36af78dfba3bf8f.zip
FreeBSD-src-6d3413a734a270473fb0033eb36af78dfba3bf8f.tar.gz
- Use the new bridgestp callback to once again flush our bridge routes when an
interface is disabled. - Log port changes to syslog, defaulting to off
-rw-r--r--sys/net/if_bridge.c40
1 files changed, 38 insertions, 2 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 2eb7408..d50ddee 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -97,6 +97,7 @@ __FBSDID("$FreeBSD$");
#include <sys/ctype.h> /* string functions */
#include <sys/kernel.h>
#include <sys/random.h>
+#include <sys/syslog.h>
#include <sys/sysctl.h>
#include <vm/uma.h>
#include <sys/module.h>
@@ -265,6 +266,7 @@ static int bridge_rtnode_insert(struct bridge_softc *,
struct bridge_rtnode *);
static void bridge_rtnode_destroy(struct bridge_softc *,
struct bridge_rtnode *);
+static void bridge_state_change(struct ifnet *, int);
static struct bridge_iflist *bridge_lookup_member(struct bridge_softc *,
const char *name);
@@ -319,12 +321,15 @@ static int pfil_onlyip = 1; /* only pass IP[46] packets when pfil is enabled */
static int pfil_bridge = 1; /* run pfil hooks on the bridge interface */
static int pfil_member = 1; /* run pfil hooks on the member interface */
static int pfil_ipfw = 0; /* layer2 filter with ipfw */
+static int log_stp = 0; /* log STP state changes */
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_onlyip, CTLFLAG_RW,
&pfil_onlyip, 0, "Only pass IP packets when pfil is enabled");
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_bridge, CTLFLAG_RW,
&pfil_bridge, 0, "Packet filter on the bridge interface");
SYSCTL_INT(_net_link_bridge, OID_AUTO, pfil_member, CTLFLAG_RW,
&pfil_member, 0, "Packet filter on the member interface");
+SYSCTL_INT(_net_link_bridge, OID_AUTO, log_stp, CTLFLAG_RW,
+ &log_stp, 0, "Log STP state changes");
struct bridge_control {
int (*bc_func)(struct bridge_softc *, void *);
@@ -566,7 +571,7 @@ bridge_clone_create(struct if_clone *ifc, int unit, caddr_t params)
mtx_unlock(&bridge_list_mtx);
}
- bstp_attach(&sc->sc_stp);
+ bstp_attach(&sc->sc_stp, bridge_state_change);
ether_ifattach(ifp, eaddr);
/* Now undo some of the damage... */
ifp->if_baudrate = 0;
@@ -860,7 +865,7 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
bridge_rtdelete(sc, ifs, IFBF_FLUSHALL);
BRIDGE_UNLOCK(sc);
- bstp_drain(&bif->bif_stp); /* prepare to free */
+ bstp_drain(&bif->bif_stp); /* prepare to free */
BRIDGE_LOCK(sc);
free(bif, M_DEVBUF);
}
@@ -2715,6 +2720,37 @@ bridge_rtnode_destroy(struct bridge_softc *sc, struct bridge_rtnode *brt)
}
/*
+ * bridge_state_change:
+ *
+ * Callback from the bridgestp code when a port changes states.
+ */
+static void
+bridge_state_change(struct ifnet *ifp, int state)
+{
+ struct bridge_softc *sc = ifp->if_bridge;
+ static const char *stpstates[] = {
+ "disabled",
+ "listening",
+ "learning",
+ "forwarding",
+ "blocking",
+ };
+
+ if (log_stp)
+ log(LOG_NOTICE, "%s: state changed to %s on %s\n",
+ sc->sc_ifp->if_xname, stpstates[state], ifp->if_xname);
+
+ /* if the port is blocking then remove any routes to it */
+ switch (state) {
+ case BSTP_IFSTATE_DISABLED:
+ case BSTP_IFSTATE_BLOCKING:
+ BRIDGE_LOCK(sc);
+ bridge_rtdelete(sc, ifp, IFBF_FLUSHDYN);
+ BRIDGE_UNLOCK(sc);
+ }
+}
+
+/*
* Send bridge packets through pfil if they are one of the types pfil can deal
* with, or if they are ARP or REVARP. (pfil will pass ARP and REVARP without
* question.) If *bifp or *ifp are NULL then packet filtering is skipped for
OpenPOWER on IntegriCloud