mirror of
https://git.hardenedbsd.org/hardenedbsd/HardenedBSD.git
synced 2024-12-18 05:53:36 +01:00
Add a bridge interface flag called PRIVATE where any private port can not
communicate with another private port. All unicast/broadcast/multicast layer2 traffic is blocked so it works much the same way as using firewall rules but scales better and is generally easier as firewall packages usually do not allow ARP blocking. An example usage would be having a number of customers on separate vlans bridged with a server network. All the vlans are marked private, they can all communicate with the server network unhindered, but can not exchange any traffic whatsoever with each other. Approved by: re (rwatson)
This commit is contained in:
parent
c4a184bdc4
commit
85ce729794
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=171678
@ -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",
|
||||
|
@ -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
|
||||
|
@ -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 ((bif->bif_flags & IFBIF_DISCOVER) == 0 &&
|
||||
if ((dbif->bif_flags & IFBIF_STP) &&
|
||||
dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING)
|
||||
continue;
|
||||
|
||||
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 {
|
||||
|
@ -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 */
|
||||
|
Loading…
Reference in New Issue
Block a user