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
This commit is contained in:
+1
-2
@@ -221,7 +221,6 @@ static MALLOC_DEFINE(M_IFDESCR, "ifdescr", "ifnet descriptions");
|
|||||||
static struct sx ifdescr_sx;
|
static struct sx ifdescr_sx;
|
||||||
SX_SYSINIT(ifdescr_sx, &ifdescr_sx, "ifnet descr");
|
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 (*ng_ether_link_state_p)(struct ifnet *ifp, int state);
|
||||||
void (*lagg_linkstate_p)(struct ifnet *ifp, int state);
|
void (*lagg_linkstate_p)(struct ifnet *ifp, int state);
|
||||||
/* These are external hooks for CARP. */
|
/* These are external hooks for CARP. */
|
||||||
@@ -2318,7 +2317,7 @@ do_link_state_change(void *arg, int pending)
|
|||||||
if (ifp->if_carp)
|
if (ifp->if_carp)
|
||||||
(*carp_linkstate_p)(ifp);
|
(*carp_linkstate_p)(ifp);
|
||||||
if (ifp->if_bridge)
|
if (ifp->if_bridge)
|
||||||
(*bridge_linkstate_p)(ifp);
|
ifp->if_bridge_linkstate(ifp);
|
||||||
if (ifp->if_lagg)
|
if (ifp->if_lagg)
|
||||||
(*lagg_linkstate_p)(ifp, link_state);
|
(*lagg_linkstate_p)(ifp, link_state);
|
||||||
|
|
||||||
|
|||||||
+6
-7
@@ -340,7 +340,6 @@ static int bridge_fragment(struct ifnet *, struct mbuf **mp,
|
|||||||
static void bridge_linkstate(struct ifnet *ifp);
|
static void bridge_linkstate(struct ifnet *ifp);
|
||||||
static void bridge_linkcheck(struct bridge_softc *sc);
|
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) */
|
/* The default bridge vlan is 1 (IEEE 802.1Q-2003 Table 9-2) */
|
||||||
#define VLANTAGOF(_m) \
|
#define VLANTAGOF(_m) \
|
||||||
@@ -556,10 +555,7 @@ bridge_modevent(module_t mod, int type, void *data)
|
|||||||
bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
|
bridge_rtnode_zone = uma_zcreate("bridge_rtnode",
|
||||||
sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
|
sizeof(struct bridge_rtnode), NULL, NULL, NULL, NULL,
|
||||||
UMA_ALIGN_PTR, 0);
|
UMA_ALIGN_PTR, 0);
|
||||||
bridge_input_p = bridge_input;
|
|
||||||
bridge_output_p = bridge_output;
|
|
||||||
bridge_dn_p = bridge_dummynet;
|
bridge_dn_p = bridge_dummynet;
|
||||||
bridge_linkstate_p = bridge_linkstate;
|
|
||||||
bridge_detach_cookie = EVENTHANDLER_REGISTER(
|
bridge_detach_cookie = EVENTHANDLER_REGISTER(
|
||||||
ifnet_departure_event, bridge_ifdetach, NULL,
|
ifnet_departure_event, bridge_ifdetach, NULL,
|
||||||
EVENTHANDLER_PRI_ANY);
|
EVENTHANDLER_PRI_ANY);
|
||||||
@@ -568,10 +564,7 @@ bridge_modevent(module_t mod, int type, void *data)
|
|||||||
EVENTHANDLER_DEREGISTER(ifnet_departure_event,
|
EVENTHANDLER_DEREGISTER(ifnet_departure_event,
|
||||||
bridge_detach_cookie);
|
bridge_detach_cookie);
|
||||||
uma_zdestroy(bridge_rtnode_zone);
|
uma_zdestroy(bridge_rtnode_zone);
|
||||||
bridge_input_p = NULL;
|
|
||||||
bridge_output_p = NULL;
|
|
||||||
bridge_dn_p = NULL;
|
bridge_dn_p = NULL;
|
||||||
bridge_linkstate_p = NULL;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
return (EOPNOTSUPP);
|
return (EOPNOTSUPP);
|
||||||
@@ -1041,6 +1034,9 @@ bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif,
|
|||||||
KASSERT(bif->bif_addrcnt == 0,
|
KASSERT(bif->bif_addrcnt == 0,
|
||||||
("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt));
|
("%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);
|
BRIDGE_UNLOCK(sc);
|
||||||
if (!gone) {
|
if (!gone) {
|
||||||
switch (ifs->if_type) {
|
switch (ifs->if_type) {
|
||||||
@@ -1198,6 +1194,9 @@ bridge_ioctl_add(struct bridge_softc *sc, void *arg)
|
|||||||
}
|
}
|
||||||
|
|
||||||
ifs->if_bridge = sc;
|
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);
|
bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp);
|
||||||
/*
|
/*
|
||||||
* XXX: XLOCK HERE!?!
|
* XXX: XLOCK HERE!?!
|
||||||
|
|||||||
@@ -310,22 +310,19 @@ struct ifbpstpconf {
|
|||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BRIDGE_INPUT(_ifp, _m) do { \
|
#define BRIDGE_INPUT(_ifp, _m) do { \
|
||||||
KASSERT(bridge_input_p != NULL, \
|
KASSERT((_ifp)->if_bridge_input != NULL, \
|
||||||
("%s: if_bridge not loaded!", __func__)); \
|
("%s: if_bridge not loaded!", __func__)); \
|
||||||
_m = (*bridge_input_p)(_ifp, _m); \
|
_m = (*(_ifp)->if_bridge_input)(_ifp, _m); \
|
||||||
if (_m != NULL) \
|
if (_m != NULL) \
|
||||||
_ifp = _m->m_pkthdr.rcvif; \
|
_ifp = _m->m_pkthdr.rcvif; \
|
||||||
} while (0)
|
} while (0)
|
||||||
|
|
||||||
#define BRIDGE_OUTPUT(_ifp, _m, _err) do { \
|
#define BRIDGE_OUTPUT(_ifp, _m, _err) do { \
|
||||||
KASSERT(bridge_output_p != NULL, \
|
KASSERT((_ifp)->if_bridge_output != NULL, \
|
||||||
("%s: if_bridge not loaded!", __func__)); \
|
("%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)
|
} 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 *);
|
extern void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
|
||||||
|
|
||||||
#endif /* _KERNEL */
|
#endif /* _KERNEL */
|
||||||
|
|||||||
@@ -102,9 +102,6 @@ void (*ng_ether_detach_p)(struct ifnet *ifp);
|
|||||||
void (*vlan_input_p)(struct ifnet *, struct mbuf *);
|
void (*vlan_input_p)(struct ifnet *, struct mbuf *);
|
||||||
|
|
||||||
/* if_bridge(4) support */
|
/* 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 *);
|
void (*bridge_dn_p)(struct mbuf *, struct ifnet *);
|
||||||
|
|
||||||
/* if_lagg(4) support */
|
/* if_lagg(4) support */
|
||||||
|
|||||||
@@ -321,6 +321,10 @@ struct ifnet {
|
|||||||
struct route *);
|
struct route *);
|
||||||
void (*if_input) /* input routine (from h/w driver) */
|
void (*if_input) /* input routine (from h/w driver) */
|
||||||
(struct ifnet *, struct mbuf *);
|
(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_start_fn_t if_start; /* initiate output routine */
|
||||||
if_ioctl_fn_t if_ioctl; /* ioctl routine */
|
if_ioctl_fn_t if_ioctl; /* ioctl routine */
|
||||||
if_init_fn_t if_init; /* Init routine */
|
if_init_fn_t if_init; /* Init routine */
|
||||||
|
|||||||
Reference in New Issue
Block a user