summaryrefslogtreecommitdiffstats
path: root/sys/netgraph
diff options
context:
space:
mode:
authorglebius <glebius@FreeBSD.org>2005-10-07 14:14:47 +0000
committerglebius <glebius@FreeBSD.org>2005-10-07 14:14:47 +0000
commit788a71efcfbc2eeb07a22892ddd7d2ec7d9ced52 (patch)
tree5e967075841a432161323228eda51649075759ce /sys/netgraph
parent453315627c100fe220f7b269154d97c7bb64acc3 (diff)
downloadFreeBSD-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')
-rw-r--r--sys/netgraph/ng_ether.c43
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);
OpenPOWER on IntegriCloud