diff options
author | David Gwynne <dlg@cvs.openbsd.org> | 2020-07-22 00:29:01 +0000 |
---|---|---|
committer | David Gwynne <dlg@cvs.openbsd.org> | 2020-07-22 00:29:01 +0000 |
commit | 547bd856b3aefa801c25796cc7f187126a88b0b8 (patch) | |
tree | afc62461275b4b7f592863ce075b7d18d7c83b50 | |
parent | 67af9a0b189ec9b044e91b9d0b898f7e736d20a7 (diff) |
add code to coordinate how bridges attach to ethernet interfaces.
this is the first step in refactoring how ethernet frames are demuxed
by virtual interfaces, and also in deprecating interface input list
handling.
we now have drivers for three types of virtual bridges, bridge(4),
switch(4), and tpmr(4), and it doesn't make sense for any of them
to be enabled on the same "port" interfaces at the same time.
currently you can add a port interface to multiple types of bridge,
but which one gets to steal the packets depends on the order in
which they were attached.
this creates an ether_brport structure that holds an input function
for the bridge, and optionally some per port state that the bridge
can use. arpcom has a single pointer to one of these structs that
will be used during normal ether_input processing to see if a packet
should be passed to a bridge, and will be used instead of an if
input handler. because it is a single pointer, it will make sure
only one bridge of any type is attached to a port at any one time.
this has been in snaps as part of a larger diff for over a week.
-rw-r--r-- | sys/net/if_ethersubr.c | 55 | ||||
-rw-r--r-- | sys/netinet/if_ether.h | 15 |
2 files changed, 68 insertions, 2 deletions
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index 322ffe34409..a46b86f74cd 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ethersubr.c,v 1.261 2019/11/24 07:50:55 claudio Exp $ */ +/* $OpenBSD: if_ethersubr.c,v 1.262 2020/07/22 00:29:00 dlg Exp $ */ /* $NetBSD: if_ethersubr.c,v 1.19 1996/05/07 02:40:30 thorpej Exp $ */ /* @@ -86,6 +86,7 @@ didn't get a copy, you may request one from <license@ipv6.nrl.navy.mil>. #include <sys/errno.h> #include <sys/syslog.h> #include <sys/timeout.h> +#include <sys/smr.h> #include <net/if.h> #include <net/netisr.h> @@ -465,6 +466,58 @@ dropanyway: return (1); } +int +ether_brport_isset(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + KERNEL_ASSERT_LOCKED(); + if (SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL) + return (EBUSY); + + return (0); +} + +void +ether_brport_set(struct ifnet *ifp, const struct ether_brport *eb) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + KERNEL_ASSERT_LOCKED(); + KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) == NULL, + "%s setting an already set brport", ifp->if_xname); + + SMR_PTR_SET_LOCKED(&ac->ac_brport, eb); +} + +void +ether_brport_clr(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + + KERNEL_ASSERT_LOCKED(); + KASSERTMSG(SMR_PTR_GET_LOCKED(&ac->ac_brport) != NULL, + "%s clearing an already clear brport", ifp->if_xname); + + SMR_PTR_SET_LOCKED(&ac->ac_brport, NULL); +} + +const struct ether_brport * +ether_brport_get(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + SMR_ASSERT_CRITICAL(); + return (SMR_PTR_GET(&ac->ac_brport)); +} + +const struct ether_brport * +ether_brport_get_locked(struct ifnet *ifp) +{ + struct arpcom *ac = (struct arpcom *)ifp; + KERNEL_ASSERT_LOCKED(); + return (SMR_PTR_GET_LOCKED(&ac->ac_brport)); +} + /* * Convert Ethernet address to printable (loggable) representation. */ diff --git a/sys/netinet/if_ether.h b/sys/netinet/if_ether.h index 934bbc97de8..5ae7228509f 100644 --- a/sys/netinet/if_ether.h +++ b/sys/netinet/if_ether.h @@ -1,4 +1,4 @@ -/* $OpenBSD: if_ether.h,v 1.76 2019/07/17 16:46:18 mpi Exp $ */ +/* $OpenBSD: if_ether.h,v 1.77 2020/07/22 00:29:00 dlg Exp $ */ /* $NetBSD: if_ether.h,v 1.22 1996/05/11 13:00:00 mycroft Exp $ */ /* @@ -199,6 +199,11 @@ do { \ #include <net/if_var.h> /* for "struct ifnet" */ +struct ether_brport { + struct mbuf *(*eb_input)(struct ifnet *, struct mbuf *, void *); + void *eb_port; +}; + /* * Structure shared between the ethernet driver modules and * the address resolution code. For example, each ec_softc or il_softc @@ -213,6 +218,7 @@ struct arpcom { int ac_multirangecnt; /* number of mcast ranges */ void *ac_trunkport; + const struct ether_brport *ac_brport; }; extern int arpt_keep; /* arp resolved cache expire */ @@ -258,6 +264,13 @@ int ether_output(struct ifnet *, struct mbuf *, struct sockaddr *, void ether_rtrequest(struct ifnet *, int, struct rtentry *); char *ether_sprintf(u_char *); +int ether_brport_isset(struct ifnet *); +void ether_brport_set(struct ifnet *, const struct ether_brport *); +void ether_brport_clr(struct ifnet *); +const struct ether_brport * + ether_brport_get(struct ifnet *); +const struct ether_brport * + ether_brport_get_locked(struct ifnet *); /* * Ethernet multicast address structure. There is one of these for each |