summaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorakoshibe <akoshibe@cvs.openbsd.org>2019-05-10 15:13:39 +0000
committerakoshibe <akoshibe@cvs.openbsd.org>2019-05-10 15:13:39 +0000
commitc4cbc9e619ed18d7b368c60ef69db97ce03628fb (patch)
treec5503730a92f8cf273cc6cdf79fb8d95e5eac1ad /sys/net
parentce8b34ccb9ac9298d85f822ac75cd4c982ffffa6 (diff)
Add port protection support to switch(4). The behavior copies that of
bridge(4), where the SIOCBRDGSIFPROT ioctl can be used to add a port to up to 31 protected domains. This allows configuration by specifying a list of IDs to the 'protected' option in ifconfig(8): # ifconfig switch0 protected pair1 1,2,.. Domain membership is checked for unicast, flooded (broadcast), and local (host-network-bound, e.g. trunk) traffic. OK benno@
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if_switch.c18
-rw-r--r--sys/net/if_switch.h3
-rw-r--r--sys/net/switchofp.c20
3 files changed, 34 insertions, 7 deletions
diff --git a/sys/net/if_switch.c b/sys/net/if_switch.c
index d61941c47f7..6a95c0bbe68 100644
--- a/sys/net/if_switch.c
+++ b/sys/net/if_switch.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_switch.c,v 1.26 2019/04/28 22:15:57 mpi Exp $ */
+/* $OpenBSD: if_switch.c,v 1.27 2019/05/10 15:13:38 akoshibe Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -434,6 +434,7 @@ switch_ioctl(struct ifnet *ifp, unsigned long cmd, caddr_t data)
}
breq->ifbr_ifsflags = swpo->swpo_flags;
breq->ifbr_portno = swpo->swpo_port_no;
+ breq->ifbr_protected = swpo->swpo_protected;
break;
case SIOCSIFFLAGS:
if ((ifp->if_flags & IFF_UP) == IFF_UP)
@@ -467,6 +468,19 @@ switch_ioctl(struct ifnet *ifp, unsigned 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(breq->ifbr_ifsname);
+ if (ifs == NULL) {
+ error = ENOENT;
+ break;
+ }
+ swpo = (struct switch_port *)ifs->if_switchport;
+ if (swpo == NULL || swpo->swpo_switch != sc) {
+ error = ESRCH;
+ break;
+ }
+ swpo->swpo_protected = breq->ifbr_protected;
+ break;
case SIOCSWGDPID:
case SIOCSWSDPID:
case SIOCSWGMAXFLOW:
@@ -560,7 +574,7 @@ switch_port_list(struct switch_softc *sc, struct ifbifconf *bifc)
strlcpy(breq.ifbr_name, sc->sc_if.if_xname, IFNAMSIZ);
breq.ifbr_ifsflags = swpo->swpo_flags;
breq.ifbr_portno = swpo->swpo_port_no;
-
+ breq.ifbr_protected = swpo->swpo_protected;
if ((error = copyout((caddr_t)&breq,
(caddr_t)(bifc->ifbic_req + n), sizeof(breq))) != 0)
goto done;
diff --git a/sys/net/if_switch.h b/sys/net/if_switch.h
index 9291befdda1..cda310729d5 100644
--- a/sys/net/if_switch.h
+++ b/sys/net/if_switch.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: if_switch.h,v 1.10 2016/11/20 12:45:26 reyk Exp $ */
+/* $OpenBSD: if_switch.h,v 1.11 2019/05/10 15:13:38 akoshibe Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -174,6 +174,7 @@ struct switch_port {
struct timespec swpo_appended;
struct switch_softc *swpo_switch;
uint32_t swpo_flags;
+ uint32_t swpo_protected;
void *swpo_dhcookie;
void (*swop_bk_start)(struct ifnet *);
};
diff --git a/sys/net/switchofp.c b/sys/net/switchofp.c
index 8c0fe5d7272..15cb3956377 100644
--- a/sys/net/switchofp.c
+++ b/sys/net/switchofp.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: switchofp.c,v 1.72 2018/12/28 14:32:47 bluhm Exp $ */
+/* $OpenBSD: switchofp.c,v 1.73 2019/05/10 15:13:38 akoshibe Exp $ */
/*
* Copyright (c) 2016 Kazuya GODA <goda@openbsd.org>
@@ -3492,6 +3492,7 @@ swofp_action_output(struct switch_softc *sc, struct mbuf *m,
struct ofp_action_output *oao;
struct switch_port *swpo;
struct mbuf *mc;
+ uint32_t protected = 0;
m->m_pkthdr.csum_flags = 0;
@@ -3509,6 +3510,14 @@ swofp_action_output(struct switch_softc *sc, struct mbuf *m,
}
}
+ TAILQ_FOREACH(swpo, &sc->sc_swpo_list, swpo_list_next) {
+ if (swpo->swpo_port_no ==
+ swpld->swpld_swfcl->swfcl_in_port) {
+ protected = swpo->swpo_protected;
+ break;
+ }
+ }
+
switch (ntohl(oao->ao_port)) {
case OFP_PORT_CONTROLLER:
swofp_action_output_controller(sc, mc, swpld,
@@ -3521,7 +3530,8 @@ swofp_action_output(struct switch_softc *sc, struct mbuf *m,
case OFP_PORT_FLOOD:
TAILQ_FOREACH(swpo, &sc->sc_swpo_list, swpo_list_next) {
if (swpo->swpo_port_no !=
- swpld->swpld_swfcl->swfcl_in_port)
+ swpld->swpld_swfcl->swfcl_in_port &&
+ (protected & swpo->swpo_protected) == 0)
TAILQ_INSERT_HEAD(&swpld->swpld_fwdp_q, swpo,
swpo_fwdp_next);
}
@@ -3543,7 +3553,8 @@ swofp_action_output(struct switch_softc *sc, struct mbuf *m,
break;
case OFP_PORT_LOCAL:
TAILQ_FOREACH(swpo, &sc->sc_swpo_list, swpo_list_next) {
- if (swpo->swpo_flags & IFBIF_LOCAL) {
+ if ((swpo->swpo_flags & IFBIF_LOCAL) &&
+ (protected & swpo->swpo_protected) == 0) {
TAILQ_INSERT_HEAD(&swpld->swpld_fwdp_q, swpo,
swpo_fwdp_next);
break;
@@ -3552,7 +3563,8 @@ swofp_action_output(struct switch_softc *sc, struct mbuf *m,
break;
default:
TAILQ_FOREACH(swpo, &sc->sc_swpo_list, swpo_list_next) {
- if (swpo->swpo_port_no == ntohl(oao->ao_port))
+ if (swpo->swpo_port_no == ntohl(oao->ao_port) &&
+ (protected & swpo->swpo_protected) == 0)
TAILQ_INSERT_HEAD(&swpld->swpld_fwdp_q, swpo,
swpo_fwdp_next);
}