diff options
author | glebius <glebius@FreeBSD.org> | 2005-10-07 14:14:47 +0000 |
---|---|---|
committer | glebius <glebius@FreeBSD.org> | 2005-10-07 14:14:47 +0000 |
commit | 788a71efcfbc2eeb07a22892ddd7d2ec7d9ced52 (patch) | |
tree | 5e967075841a432161323228eda51649075759ce /sys/netgraph/ng_ether.c | |
parent | 453315627c100fe220f7b269154d97c7bb64acc3 (diff) | |
download | FreeBSD-src-788a71efcfbc2eeb07a22892ddd7d2ec7d9ced52.zip FreeBSD-src-788a71efcfbc2eeb07a22892ddd7d2ec7d9ced52.tar.gz |
A deja vu of:
http://lists.freebsd.org/pipermail/cvs-src/2004-October/033496.html
The same problem applies to if_bridge(4), too.
- Copy-and-paste the if_bridge(4) related block from
if_ethersubr.c to ng_ether.c
- Add XXXs, so that copy-and-paste would be noticed by
any future editors of this code.
- Also add XXXs near if_bridge(4) declarations.
Silence from: thompsa
Diffstat (limited to 'sys/netgraph/ng_ether.c')
-rw-r--r-- | sys/netgraph/ng_ether.c | 43 |
1 files changed, 41 insertions, 2 deletions
diff --git a/sys/netgraph/ng_ether.c b/sys/netgraph/ng_ether.c index ae1cb58..29a8348 100644 --- a/sys/netgraph/ng_ether.c +++ b/sys/netgraph/ng_ether.c @@ -103,6 +103,11 @@ static void ng_ether_link_state(struct ifnet *ifp, int state); static int ng_ether_rcv_lower(node_p node, struct mbuf *m); static int ng_ether_rcv_upper(node_p node, struct mbuf *m); +/* if_bridge(4) support. XXX: should go into some include. */ +extern struct mbuf *(*bridge_input_p)(struct ifnet *, struct mbuf *); +static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + /* Netgraph node methods */ static ng_constructor_t ng_ether_constructor; static ng_rcvmsg_t ng_ether_rcvmsg; @@ -640,10 +645,44 @@ static int ng_ether_rcv_upper(node_p node, struct mbuf *m) { const priv_p priv = NG_NODE_PRIVATE(node); + struct ifnet *ifp = priv->ifp; + + m->m_pkthdr.rcvif = ifp; + + /* + * XXX: This is a copy'and'paste from if_ethersubr.c:ether_input() + */ + if (ifp->if_bridge) { + struct ether_header *eh; + + KASSERT(bridge_input_p != NULL, + ("%s: if_bridge not loaded!", __func__)); - m->m_pkthdr.rcvif = priv->ifp; + eh = mtod(m, struct ether_header *); - /* XXX: if_bridge hook here? */ + /* Mark the packet as broadcast or multicast. This is also set + * further down the code in ether_demux() but since the bridge + * input routine rarely returns a mbuf for further processing, + * it is an acceptable duplication. + */ + if (ETHER_IS_MULTICAST(eh->ether_dhost)) { + if (bcmp(etherbroadcastaddr, eh->ether_dhost, + sizeof(etherbroadcastaddr)) == 0) + m->m_flags |= M_BCAST; + else + m->m_flags |= M_MCAST; + } + + m = (*bridge_input_p)(ifp, m); + if (m == NULL) + return (0); + /* + * Bridge has determined that the packet is for us. + * Update our interface pointer -- we may have had + * to "bridge" the packet locally. + */ + ifp = m->m_pkthdr.rcvif; + } /* Route packet back in */ ether_demux(priv->ifp, m); |