1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-17 10:26:15 +00:00

Remove one more unneeded reference to arpcom.ac_netgraph.

Tweak things so that ng_fec has a chance of working with things
other than ethernet. Use ifp->if_output of the underlying interfaces
and use IF_HANDOFF() rather than depending on ether_output() and
ether_output_frame() explicitly. Also, don't insist that underlying
devices be IFM_ETHER when checking their link states in the link
monitor code.

With these changes, I was able to create a two channel bundle
consisting of one ethernet interface and one 802.11 wireless
device (via ndis). Note that this only works because both devices
use the same if_output vector: ng_fec will not let you bundle
devices with different output vectors together (it really doesn't
make sense to do that).
This commit is contained in:
Bill Paul 2004-06-20 21:08:58 +00:00
parent dc8beb5358
commit 15a646e411
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=130815

View File

@ -130,8 +130,8 @@
* ifnet structure so that receive handling works. As far as I can
* tell, although there is an AF_NETGRAPH address family, it's only
* used to identify sockaddr_ng structures: there is no netgraph address
* family domain. This means the AF_NETGRAPH entry in ifp->if_afdata[]
* should be unused, so we can (ab)use it to hold our node context.
* family domain. This means the AF_NETGRAPH entry in ifp->if_afdata
* should be unused, so we can use to hold our node context.
*/
#define IFP2NG(ifp) (struct ng_node *)(ifp->if_afdata[AF_NETGRAPH])
#define FEC_INC(x, y) (x) = (x + 1) % y
@ -144,7 +144,8 @@
struct ng_fec_portlist {
struct ifnet *fec_if;
void (*fec_if_input) (struct ifnet *, struct mbuf *);
void (*fec_if_input) (struct ifnet *,
struct mbuf *);
int fec_idx;
int fec_ifstat;
struct ether_addr fec_mac;
@ -155,6 +156,10 @@ struct ng_fec_bundle {
TAILQ_HEAD(,ng_fec_portlist) ng_fec_ports;
int fec_ifcnt;
int fec_btype;
int (*fec_if_output) (struct ifnet *,
struct mbuf *,
struct sockaddr *,
struct rtentry *);
};
#define FEC_BTYPE_MAC 0x01
@ -362,6 +367,20 @@ ng_fec_addport(struct ng_fec_private *priv, char *iface)
}
}
/*
* All interfaces must use the same output vector. Once the
* user attaches an interface of one type, make all subsequent
* interfaces have the same output vector.
*/
if (b->fec_if_output != NULL) {
if (b->fec_if_output != bifp->if_output) {
printf("fec%d: iface %s is not the same type "
"as the other interface(s) already in "
"the bundle\n", priv->unit, iface);
return(EINVAL);
}
}
/* Allocate new list entry. */
MALLOC(new, struct ng_fec_portlist *,
sizeof(struct ng_fec_portlist), M_NETGRAPH, M_NOWAIT);
@ -408,6 +427,10 @@ ng_fec_addport(struct ng_fec_private *priv, char *iface)
/* Override it with our own */
bifp->if_input = ng_fec_input;
/* Save output vector too. */
if (b->fec_if_output == NULL)
b->fec_if_output = bifp->if_output;
/* Add to the queue */
new->fec_if = bifp;
TAILQ_INSERT_TAIL(&b->ng_fec_ports, new, fec_list);
@ -474,6 +497,9 @@ ng_fec_delport(struct ng_fec_private *priv, char *iface)
FREE(p, M_NETGRAPH);
b->fec_ifcnt--;
if (b->fec_ifcnt == 0)
b->fec_if_output = NULL;
return(0);
}
@ -581,8 +607,7 @@ ng_fec_tick(void *arg)
continue;
}
if (ifmr.ifm_status & IFM_AVALID &&
IFM_TYPE(ifmr.ifm_active) == IFM_ETHER) {
if (ifmr.ifm_status & IFM_AVALID) {
if (ifmr.ifm_status & IFM_ACTIVE) {
if (p->fec_ifstat == -1 ||
p->fec_ifstat == 0) {
@ -788,7 +813,7 @@ ng_fec_input(struct ifnet *ifp, struct mbuf *m0)
* Take a quick peek at the packet and see if it's ok for us to use
* the inet or inet6 hash methods on it, if they're enabled. We do
* this by setting flags in the mbuf header. Once we've made up our
* mind what to do, we pass the frame to ether_output() for further
* mind what to do, we pass the frame to output vector for further
* processing.
*/
@ -842,12 +867,12 @@ ng_fec_output(struct ifnet *ifp, struct mbuf *m,
}
/*
* Pass the frame to ether_output() for all the protocol
* Pass the frame to the output vector for all the protocol
* handling. This will put the ethernet header on the packet
* for us.
*/
priv->if_error = 0;
error = ether_output(ifp, m, dst, rt0);
error = (*b->fec_if_output)(ifp, m, dst, rt0);
if (priv->if_error && !error)
error = priv->if_error;
@ -1007,7 +1032,7 @@ ng_fec_start(struct ifnet *ifp)
}
ifp->if_opackets++;
priv->if_error = ether_output_frame(oifp, m0);
priv->if_error = IF_HANDOFF(&oifp->if_snd, m0, oifp) ? 0 : ENOBUFS;
return;
}
@ -1085,7 +1110,6 @@ ng_fec_constructor(node_p node)
/* Link together node and private info */
NG_NODE_SET_PRIVATE(node, priv);
priv->node = node;
priv->arpcom.ac_netgraph = node;
/* Initialize interface structure */
if_initname(ifp, NG_FEC_FEC_NAME, priv->unit);