aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorAndrew Thompson <thompsa@FreeBSD.org>2008-03-06 19:02:37 +0000
committerAndrew Thompson <thompsa@FreeBSD.org>2008-03-06 19:02:37 +0000
commit56abdd33507adcc0f92017b04687137d05fd9c08 (patch)
tree141be2cc7e665dbac88690baad8a123b110a2e7a /sys
parentb75e2d0b7da0f7c24c2b74adf67bd80c082d5726 (diff)
downloadsrc-56abdd33507adcc0f92017b04687137d05fd9c08.tar.gz
src-56abdd33507adcc0f92017b04687137d05fd9c08.zip
Improve EtherIP interaction with the bridge
- Set M_BCAST|M_MCAST for incoming frames - Send the frame to a local interface if the bridge returns the mbuf Submitted by: Eugene Grosbein Tested by: Boris Kochergin
Notes
Notes: svn path=/head/; revision=176879
Diffstat (limited to 'sys')
-rw-r--r--sys/net/if_gif.c32
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c
index 4743a0568dff..63f3c7d99011 100644
--- a/sys/net/if_gif.c
+++ b/sys/net/if_gif.c
@@ -138,6 +138,14 @@ static int parallel_tunnels = 0;
SYSCTL_INT(_net_link_gif, OID_AUTO, parallel_tunnels, CTLFLAG_RW,
&parallel_tunnels, 0, "Allow parallel tunnels?");
+/* copy from src/sys/net/if_ethersubr.c */
+static const u_char etherbroadcastaddr[ETHER_ADDR_LEN] =
+ { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+#ifndef ETHER_IS_BROADCAST
+#define ETHER_IS_BROADCAST(addr) \
+ (bcmp(etherbroadcastaddr, (addr), ETHER_ADDR_LEN) == 0)
+#endif
+
static int
gif_clone_create(ifc, unit, params)
struct if_clone *ifc;
@@ -469,6 +477,8 @@ gif_input(m, af, ifp)
{
int isr, n;
struct etherip_header *eip;
+ struct ether_header *eh;
+ struct ifnet *oldifp;
if (ifp == NULL) {
/* just in case */
@@ -537,9 +547,27 @@ gif_input(m, af, ifp)
m->m_flags &= ~(M_BCAST|M_MCAST);
m->m_pkthdr.rcvif = ifp;
- if (ifp->if_bridge)
+ if (ifp->if_bridge) {
+ oldifp = ifp;
+ eh = mtod(m, struct ether_header *);
+ if (ETHER_IS_MULTICAST(eh->ether_dhost)) {
+ if (ETHER_IS_BROADCAST(eh->ether_dhost))
+ m->m_flags |= M_BCAST;
+ else
+ m->m_flags |= M_MCAST;
+ ifp->if_imcasts++;
+ }
BRIDGE_INPUT(ifp, m);
-
+
+ if (m != NULL && ifp != oldifp) {
+ /*
+ * The bridge gave us back itself or one of the
+ * members for which the frame is addressed.
+ */
+ ether_demux(ifp, m);
+ return;
+ }
+ }
if (m != NULL)
m_freem(m);
return;