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 /sys/net/if_ethersubr.c | |
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.
Diffstat (limited to 'sys/net/if_ethersubr.c')
-rw-r--r-- | sys/net/if_ethersubr.c | 55 |
1 files changed, 54 insertions, 1 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. */ |