aboutsummaryrefslogtreecommitdiff
path: root/sys/net
diff options
context:
space:
mode:
authorMatt Macy <mmacy@FreeBSD.org>2018-05-11 05:00:40 +0000
committerMatt Macy <mmacy@FreeBSD.org>2018-05-11 05:00:40 +0000
commit5c30b378f02d1eea7ca6e4bad1fb13d8645f8354 (patch)
tree874029ff3241be796d0a6954ef06cea95a3e97bb /sys/net
parentb2cb28963be2e9c3afab679b2872c3c79f6d8add (diff)
downloadsrc-5c30b378f02d1eea7ca6e4bad1fb13d8645f8354.tar.gz
src-5c30b378f02d1eea7ca6e4bad1fb13d8645f8354.zip
Allow different bridge types to coexist
if_bridge has a lot of limitations that make it scale poorly to higher data rates. In my projects/VPC branch I leverage the bridge interface between layers for my high speed soft switch as well as for purposes of stacking in general. Reviewed by: sbruno@ Approved by: sbruno@ Differential Revision: https://reviews.freebsd.org/D15344
Notes
Notes: svn path=/head/; revision=333481
Diffstat (limited to 'sys/net')
-rw-r--r--sys/net/if.c3
-rw-r--r--sys/net/if_bridge.c13
-rw-r--r--sys/net/if_bridgevar.h13
-rw-r--r--sys/net/if_ethersubr.c3
-rw-r--r--sys/net/if_var.h4
5 files changed, 16 insertions, 20 deletions
diff --git a/sys/net/if.c b/sys/net/if.c
index 6c5d09db9ea8..b03b30dae839 100644
--- a/sys/net/if.c
+++ b/sys/net/if.c
@@ -221,7 +221,6 @@ static MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet descriptions");
static struct sx ifdescr_sx;
SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr");
-void (*bridge_linkstate_p)(struct ifnet *ifp);
void (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
void (*lagg_linkstate_p)(struct ifnet *ifp, int state);
/* These are external hooks for CARP. */
@@ -2318,7 +2317,7 @@ do_link_state_change(void *arg, int pending)
if (ifp->if_carp)
(*carp_linkstate_p)(ifp);
if (ifp->if_bridge)
- (*bridge_linkstate_p)(ifp);
+ ifp->if_bridge_linkstate(ifp);
if (ifp->if_lagg)
(*lagg_linkstate_p)(ifp, link_state);
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c
index b09541b5e164..6c84d760b717 100644
--- a/sys/net/if_bridge.c
+++ b/sys/net/if_bridge.c
@@ -340,7 +340,6 @@ static int bridge_fragment(struct ifnet *, struct mbuf **mp,
static void bridge_linkstate(struct ifnet *ifp);
static void bridge_linkcheck(struct bridge_softc *sc);
-extern void (*bridge_linkstate_p)(struct ifnet *ifp);
/* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */
#define VLANTAGOF(_m) \
@@ -556,10 +555,7 @@ bridge_modevent(module_t mod, int type, void *data)
bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
UMA_ALIGN_PTR, 0);
- bridge_input_p = bridge_input;
- bridge_output_p = bridge_output;
bridge_dn_p = bridge_dummynet;
- bridge_linkstate_p = bridge_linkstate;
bridge_detach_cookie = EVENTHANDLER_REGISTER(
ifnet_departure_event, bridge_ifdetach, NULL,
EVENTHANDLER_PRI_ANY);
@@ -568,10 +564,7 @@ bridge_modevent(module_t mod, int type, void *data)
EVENTHANDLER_DEREGISTER(ifnet_departure_event,
bridge_detach_cookie);
uma_zdestroy(bridge_rtnode_zone);
- bridge_input_p = NULL;
- bridge_output_p = NULL;
bridge_dn_p = NULL;
- bridge_linkstate_p = NULL;
break;
default:
return (EOPNOTSUPP);
@@ -1041,6 +1034,9 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
KASSERT(bif->bif_addrcnt == 0,
("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt));
+ ifs->if_bridge_output = NULL;
+ ifs->if_bridge_input = NULL;
+ ifs->if_bridge_linkstate = NULL;
BRIDGE_UNLOCK(sc);
if (!gone) {
switch (ifs->if_type) {
@@ -1198,6 +1194,9 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
}
ifs->if_bridge = sc;
+ ifs->if_bridge_output = bridge_output;
+ ifs->if_bridge_input = bridge_input;
+ ifs->if_bridge_linkstate = bridge_linkstate;
bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp);
/*
* XXX: XLOCK HERE!?!
diff --git a/sys/net/if_bridgevar.h b/sys/net/if_bridgevar.h
index 84ff8d21357d..f4f61706c65f 100644
--- a/sys/net/if_bridgevar.h
+++ b/sys/net/if_bridgevar.h
@@ -309,23 +309,20 @@ struct ifbpstpconf {
(_sc)->sc_iflist_xcnt--; \
} while (0)
-#define BRIDGE_INPUT(_ifp, _m) do { \
- KASSERT(bridge_input_p != NULL, \
+#define BRIDGE_INPUT(_ifp, _m) do { \
+ KASSERT((_ifp)->if_bridge_input != NULL, \
("%s: if_bridge not loaded!", __func__)); \
- _m = (*bridge_input_p)(_ifp, _m); \
+ _m = (*(_ifp)->if_bridge_input)(_ifp, _m); \
if (_m != NULL) \
_ifp = _m->m_pkthdr.rcvif; \
} while (0)
#define BRIDGE_OUTPUT(_ifp, _m, _err) do { \
- KASSERT(bridge_output_p != NULL, \
+ KASSERT((_ifp)->if_bridge_output != NULL, \
("%s: if_bridge not loaded!", __func__)); \
- _err = (*bridge_output_p)(_ifp, _m, NULL, NULL); \
+ _err = (*(_ifp)->if_bridge_output)(_ifp, _m, NULL, NULL); \
} while (0)
-extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
-extern int (*bridge_output_p)(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *);
extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
#endif /* _KERNEL */
diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c
index 7c3146ade4f0..c149214c8661 100644
--- a/sys/net/if_ethersubr.c
+++ b/sys/net/if_ethersubr.c
@@ -102,9 +102,6 @@ void (*ng_ether_detach_p)(struct ifnet *ifp);
void (*vlan_input_p)(struct ifnet *, struct mbuf *);
/* if_bridge(4) support */
-struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *);
-int (*bridge_output_p)(struct ifnet *, struct mbuf *,
- struct sockaddr *, struct rtentry *);
void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
/* if_lagg(4) support */
diff --git a/sys/net/if_var.h b/sys/net/if_var.h
index c72f637ac04f..adfadead633b 100644
--- a/sys/net/if_var.h
+++ b/sys/net/if_var.h
@@ -321,6 +321,10 @@ struct ifnet {
struct route *);
void (*if_input) /* input routine (from h/w driver) */
(struct ifnet *, struct mbuf *);
+ struct mbuf *(*if_bridge_input)(struct ifnet *, struct mbuf *);
+ int (*if_bridge_output)(struct ifnet *, struct mbuf *, struct sockaddr *,
+ struct rtentry *);
+ void (*if_bridge_linkstate)(struct ifnet *ifp);
if_start_fn_t if_start; /* initiate output routine */
if_ioctl_fn_t if_ioctl; /* ioctl routine */
if_init_fn_t if_init; /* Init routine */