summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--sbin/ifconfig/ifbridge.c16
-rw-r--r--sbin/ifconfig/ifconfig.810
-rw-r--r--sys/net/if_bridge.c70
-rw-r--r--sys/net/if_bridgevar.h4
4 files changed, 66 insertions, 34 deletions
diff --git a/sbin/ifconfig/ifbridge.c b/sbin/ifconfig/ifbridge.c
index 72fd491..d8176a8 100644
--- a/sbin/ifconfig/ifbridge.c
+++ b/sbin/ifconfig/ifbridge.c
@@ -665,6 +665,20 @@ setbridge_timeout(const char *arg, int d, int s, const struct afswtch *afp)
err(1, "BRDGSTO %s", arg);
}
+static void
+setbridge_private(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ do_bridgeflag(s, val, IFBIF_PRIVATE, 1);
+}
+
+static void
+unsetbridge_private(const char *val, int d, int s, const struct afswtch *afp)
+{
+
+ do_bridgeflag(s, val, IFBIF_PRIVATE, 0);
+}
+
static struct cmd bridge_cmds[] = {
DEF_CMD_ARG("addm", setbridge_add),
DEF_CMD_ARG("deletem", setbridge_delete),
@@ -701,6 +715,8 @@ static struct cmd bridge_cmds[] = {
DEF_CMD_ARG2("ifpriority", setbridge_ifpriority),
DEF_CMD_ARG2("ifpathcost", setbridge_ifpathcost),
DEF_CMD_ARG("timeout", setbridge_timeout),
+ DEF_CMD_ARG("private", setbridge_private),
+ DEF_CMD_ARG("-private", unsetbridge_private),
};
static struct afswtch af_bridge = {
.af_name = "af_bridge",
diff --git a/sbin/ifconfig/ifconfig.8 b/sbin/ifconfig/ifconfig.8
index 79f0ce2..63b4317 100644
--- a/sbin/ifconfig/ifconfig.8
+++ b/sbin/ifconfig/ifconfig.8
@@ -1502,6 +1502,16 @@ address is seen on a different interface.
Clear the
.Dq sticky
attribute on a member interface.
+.It Cm private Ar interface
+Mark an interface as a
+.Dq private
+interface.
+A private interface does not forward any traffic to any other port that is also
+a private interface.
+.It Cm -private Ar interface
+Clear the
+.Dq private
+attribute on a member interface.
.It Cm span Ar interface
Add the interface named by
.Ar interface
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 3f0cabf..6c96cbb 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -243,7 +243,8 @@ static void bridge_enqueue(struct bridge_softc *, struct ifnet *,
struct mbuf *);
static void bridge_rtdelete(struct bridge_softc *, struct ifnet *ifp, int);
-static void bridge_forward(struct bridge_softc *, struct mbuf *m);
+static void bridge_forward(struct bridge_softc *, struct bridge_iflist *,
+ struct mbuf *m);
static void bridge_timer(void *);
@@ -1873,9 +1874,10 @@ bridge_start(struct ifnet *ifp)
* NOTE: Releases the lock on return.
*/
static void
-bridge_forward(struct bridge_softc *sc, struct mbuf *m)
+bridge_forward(struct bridge_softc *sc, struct bridge_iflist *sbif,
+ struct mbuf *m)
{
- struct bridge_iflist *bif;
+ struct bridge_iflist *dbif;
struct ifnet *src_if, *dst_if, *ifp;
struct ether_header *eh;
uint16_t vlan;
@@ -1887,19 +1889,8 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
sc->sc_ifp->if_ibytes += m->m_pkthdr.len;
vlan = VLANTAGOF(m);
- /*
- * Look up the bridge_iflist.
- */
- bif = bridge_lookup_member_if(sc, src_if);
- if (bif == NULL) {
- /* Interface is not a bridge member (anymore?) */
- BRIDGE_UNLOCK(sc);
- m_freem(m);
- return;
- }
-
- if ((bif->bif_flags & IFBIF_STP) &&
- bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
+ if ((sbif->bif_flags & IFBIF_STP) &&
+ sbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
BRIDGE_UNLOCK(sc);
m_freem(m);
return;
@@ -1912,7 +1903,7 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
* address is valid and not multicast, record
* the address.
*/
- if ((bif->bif_flags & IFBIF_LEARNING) != 0 &&
+ if ((sbif->bif_flags & IFBIF_LEARNING) != 0 &&
ETHER_IS_MULTICAST(eh->ether_shost) == 0 &&
(eh->ether_shost[0] == 0 &&
eh->ether_shost[1] == 0 &&
@@ -1921,11 +1912,11 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
eh->ether_shost[4] == 0 &&
eh->ether_shost[5] == 0) == 0) {
(void) bridge_rtupdate(sc, eh->ether_shost, vlan,
- bif, 0, IFBAF_DYNAMIC);
+ sbif, 0, IFBAF_DYNAMIC);
}
- if ((bif->bif_flags & IFBIF_STP) != 0 &&
- bif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING) {
+ if ((sbif->bif_flags & IFBIF_STP) != 0 &&
+ sbif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING) {
m_freem(m);
BRIDGE_UNLOCK(sc);
return;
@@ -1993,16 +1984,23 @@ bridge_forward(struct bridge_softc *sc, struct mbuf *m)
m_freem(m);
return;
}
- bif = bridge_lookup_member_if(sc, dst_if);
- if (bif == NULL) {
+ dbif = bridge_lookup_member_if(sc, dst_if);
+ if (dbif == NULL) {
/* Not a member of the bridge (anymore?) */
BRIDGE_UNLOCK(sc);
m_freem(m);
return;
}
- if ((bif->bif_flags & IFBIF_STP) &&
- bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
+ /* Private segments can not talk to each other */
+ if (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE) {
+ BRIDGE_UNLOCK(sc);
+ m_freem(m);
+ return;
+ }
+
+ if ((dbif->bif_flags & IFBIF_STP) &&
+ dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) {
BRIDGE_UNLOCK(sc);
m_freem(m);
return;
@@ -2122,7 +2120,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
}
/* Perform the bridge forwarding function with the copy. */
- bridge_forward(sc, mc);
+ bridge_forward(sc, bif, mc);
/*
* Reinject the mbuf as arriving on the bridge so we have a
@@ -2210,7 +2208,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m)
#undef GRAB_OUR_PACKETS
/* Perform the bridge forwarding function. */
- bridge_forward(sc, m);
+ bridge_forward(sc, bif, m);
return (NULL);
}
@@ -2228,11 +2226,13 @@ static void
bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
struct mbuf *m, int runfilt)
{
- struct bridge_iflist *bif;
+ struct bridge_iflist *dbif, *sbif;
struct mbuf *mc;
struct ifnet *dst_if;
int error = 0, used = 0, i;
+ sbif = bridge_lookup_member_if(sc, src_if);
+
BRIDGE_LOCK2REF(sc, error);
if (error) {
m_freem(m);
@@ -2251,23 +2251,27 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *src_if,
goto out;
}
- LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
- dst_if = bif->bif_ifp;
+ LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) {
+ dst_if = dbif->bif_ifp;
if (dst_if == src_if)
continue;
- if ((bif->bif_flags & IFBIF_STP) &&
- bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
+ /* Private segments can not talk to each other */
+ if (sbif && (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE))
+ continue;
+
+ if ((dbif->bif_flags & IFBIF_STP) &&
+ dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
continue;
- if ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
+ if ((dbif->bif_flags & IFBIF_DISCOVER) == 0 &&
(m->m_flags & (M_BCAST|M_MCAST)) == 0)
continue;
if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0)
continue;
- if (LIST_NEXT(bif, bif_next) == NULL) {
+ if (LIST_NEXT(dbif, bif_next) == NULL) {
mc = m;
used = 1;
} else {
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
index 8097cd9..ddd8ce7 100644
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -142,9 +142,11 @@ struct ifbreq {
#define IFBIF_BSTP_AUTOPTP 0x0100 /* member stp autoptp enabled */
#define IFBIF_BSTP_ADMEDGE 0x0200 /* member stp admin edge enabled */
#define IFBIF_BSTP_ADMCOST 0x0400 /* member stp admin path cost */
+#define IFBIF_PRIVATE 0x0800 /* if is a private segment */
#define IFBIFBITS "\020\001LEARNING\002DISCOVER\003STP\004SPAN" \
- "\005STICKY\006EDGE\007AUTOEDGE\010PTP\011AUTOPTP"
+ "\005STICKY\014PRIVATE\006EDGE\007AUTOEDGE\010PTP" \
+ "\011AUTOPTP"
#define IFBIFMASK ~(IFBIF_BSTP_EDGE|IFBIF_BSTP_AUTOEDGE|IFBIF_BSTP_PTP| \
IFBIF_BSTP_AUTOPTP|IFBIF_BSTP_ADMEDGE| \
IFBIF_BSTP_ADMCOST) /* not saved */
OpenPOWER on IntegriCloud