summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Gwynne <dlg@cvs.openbsd.org>2020-07-22 00:29:01 +0000
committerDavid Gwynne <dlg@cvs.openbsd.org>2020-07-22 00:29:01 +0000
commit547bd856b3aefa801c25796cc7f187126a88b0b8 (patch)
treeafc62461275b4b7f592863ce075b7d18d7c83b50
parent67af9a0b189ec9b044e91b9d0b898f7e736d20a7 (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.c55
-rw-r--r--sys/netinet/if_ether.h15
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