summaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-08 13:15:33 +0000
committerMartin Pieuchot <mpi@cvs.openbsd.org>2018-02-08 13:15:33 +0000
commit2df627dc6a50bf2976d6a49755b8f2d8a6f0ffc9 (patch)
tree5829caf6c2798a0d9fa72b53c3abbeb5885cbc44 /sys
parent7b3cd90ace3f642e57833f8d2d610c9b28f883b3 (diff)
Add a new '-protected' option for bridge members.
Bridge members that are part of the same protected domain, refered by a number between 1 and 31, cannot talk to each others. This is useful to isolate VMs or untrusted networks at layer 2. Members can be part of multiple protected domain making it possible to create complex protected setups. ok ccardenas@, claudio@, dlg@, henning@
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_bridge.c38
-rw-r--r--sys/net/if_bridge.h4
-rw-r--r--sys/sys/sockio.h3
3 files changed, 42 insertions, 3 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index 8465fcac0ee..839f6460deb 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.c,v 1.304 2018/02/07 11:30:01 mpi Exp $ */
+/* $OpenBSD: if_bridge.c,v 1.305 2018/02/08 13:15:31 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -409,6 +409,7 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
}
req->ifbr_ifsflags = p->bif_flags;
req->ifbr_portno = p->ifp->if_index & 0xfff;
+ req->ifbr_protected = p->bif_protected;
if (p->bif_flags & IFBIF_STP) {
bp = p->bif_stp;
req->ifbr_state = bstp_getstate(bs, bp);
@@ -496,6 +497,19 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
brop->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec;
brop->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec;
break;
+ case SIOCBRDGSIFPROT:
+ ifs = ifunit(req->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ p = (struct bridge_iflist *)ifs->if_bridgeport;
+ if (p == NULL || p->bridge_sc != sc) {
+ error = ESRCH;
+ break;
+ }
+ p->bif_protected = req->ifbr_protected;
+ break;
case SIOCBRDGRTS:
case SIOCBRDGGCACHE:
case SIOCBRDGGPRI:
@@ -594,6 +608,7 @@ bridge_bifconf(struct bridge_softc *sc, struct ifbifconf *bifc)
strlcpy(breq->ifbr_ifsname, p->ifp->if_xname, IFNAMSIZ);
breq->ifbr_ifsflags = p->bif_flags;
breq->ifbr_portno = p->ifp->if_index & 0xfff;
+ breq->ifbr_protected = p->bif_protected;
if (p->bif_flags & IFBIF_STP) {
bp = p->bif_stp;
breq->ifbr_state = bstp_getstate(sc->sc_stp, bp);
@@ -855,6 +870,7 @@ bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
struct bridge_rtnode *dst_p;
struct ether_addr *dst, *src;
struct ether_header eh;
+ u_int32_t protected;
int len;
@@ -967,6 +983,7 @@ bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
bridge_broadcast(sc, src_if, &eh, m);
return;
}
+ protected = ifl->bif_protected;
/*
* At this point, we're dealing with a unicast frame going to a
@@ -982,6 +999,14 @@ bridgeintr_frame(struct bridge_softc *sc, struct ifnet *src_if, struct mbuf *m)
m_freem(m);
return;
}
+ /*
+ * Do not transmit if both ports are part of the same protected
+ * domain.
+ */
+ if (protected != 0 && (protected & ifl->bif_protected)) {
+ m_freem(m);
+ return;
+ }
if (bridge_filterrule(&ifl->bif_brlout, &eh, m) == BRL_ACTION_BLOCK) {
m_freem(m);
return;
@@ -1173,6 +1198,10 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
struct mbuf *mc;
struct ifnet *dst_if;
int len, used = 0;
+ u_int32_t protected;
+
+ p = (struct bridge_iflist *)ifp->if_bridgeport;
+ protected = p->bif_protected;
TAILQ_FOREACH(p, &sc->sc_iflist, next) {
dst_if = p->ifp;
@@ -1193,6 +1222,13 @@ bridge_broadcast(struct bridge_softc *sc, struct ifnet *ifp,
bridge_blocknonip(eh, m))
continue;
+ /*
+ * Do not transmit if both ports are part of the same
+ * protected domain.
+ */
+ if (protected != 0 && (protected & p->bif_protected))
+ continue;
+
if (bridge_filterrule(&p->bif_brlout, eh, m) == BRL_ACTION_BLOCK)
continue;
diff --git a/sys/net/if_bridge.h b/sys/net/if_bridge.h
index 75596a5b040..abb5d643bf6 100644
--- a/sys/net/if_bridge.h
+++ b/sys/net/if_bridge.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_bridge.h,v 1.56 2018/02/05 03:51:53 henning Exp $ */
+/* $OpenBSD: if_bridge.h,v 1.57 2018/02/08 13:15:32 mpi Exp $ */
/*
* Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net)
@@ -46,6 +46,7 @@ struct ifbreq {
char ifbr_ifsname[IFNAMSIZ]; /* member ifs name */
u_int32_t ifbr_ifsflags; /* member ifs flags */
u_int32_t ifbr_portno; /* member port number */
+ u_int32_t ifbr_protected; /* protected domains */
u_int8_t ifbr_state; /* member stp state */
u_int8_t ifbr_priority; /* member stp priority */
@@ -415,6 +416,7 @@ struct bridge_iflist {
struct brl_head bif_brlout; /* output rules */
struct ifnet *ifp; /* member interface */
u_int32_t bif_flags; /* member flags */
+ u_int32_t bif_protected; /* protected domains */
void *bif_dhcookie;
};
#define bif_state bif_stp->bp_state
diff --git a/sys/sys/sockio.h b/sys/sys/sockio.h
index 4d630796c44..7e9fdf21b8c 100644
--- a/sys/sys/sockio.h
+++ b/sys/sys/sockio.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: sockio.h,v 1.72 2017/10/24 09:36:13 jsg Exp $ */
+/* $OpenBSD: sockio.h,v 1.73 2018/02/08 13:15:32 mpi Exp $ */
/* $NetBSD: sockio.h,v 1.5 1995/08/23 00:40:47 thorpej Exp $ */
/*-
@@ -89,6 +89,7 @@
#define SIOCBRDGDADDR _IOW('i', 71, struct ifbareq) /* delete addr */
#define SIOCBRDGFLUSH _IOW('i', 72, struct ifbreq) /* flush addr cache */
#define SIOCBRDGADDL _IOW('i', 73, struct ifbreq) /* add local port */
+#define SIOCBRDGSIFPROT _IOW('i', 74, struct ifbreq) /* set protected grp */
#define SIOCBRDGARL _IOW('i', 77, struct ifbrlreq) /* add bridge rule */
#define SIOCBRDGFRL _IOW('i', 78, struct ifbrlreq) /* flush brdg rules */