diff options
author | thompsa <thompsa@FreeBSD.org> | 2008-03-06 19:02:37 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2008-03-06 19:02:37 +0000 |
commit | 13c68a6bcda444d5e887d57e2848da12c51d0ff9 (patch) | |
tree | 141be2cc7e665dbac88690baad8a123b110a2e7a /sys/net/if_gif.c | |
parent | 92b09d60694767029d174f11c0e834bdb224a417 (diff) | |
download | FreeBSD-src-13c68a6bcda444d5e887d57e2848da12c51d0ff9.zip FreeBSD-src-13c68a6bcda444d5e887d57e2848da12c51d0ff9.tar.gz |
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
Diffstat (limited to 'sys/net/if_gif.c')
-rw-r--r-- | sys/net/if_gif.c | 32 |
1 files changed, 30 insertions, 2 deletions
diff --git a/sys/net/if_gif.c b/sys/net/if_gif.c index 4743a05..63f3c7d 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, ¶llel_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; |