diff options
author | thompsa <thompsa@FreeBSD.org> | 2005-09-13 18:02:39 +0000 |
---|---|---|
committer | thompsa <thompsa@FreeBSD.org> | 2005-09-13 18:02:39 +0000 |
commit | 12b6d396b7dad8b10fa114fc17de41bd07d6280d (patch) | |
tree | 78be1cf510396dcdde6433a2af92ed05804e0a6a /sys | |
parent | ca6608f3914b3f120d57ccb0f357f503bceed17a (diff) | |
download | FreeBSD-src-12b6d396b7dad8b10fa114fc17de41bd07d6280d.zip FreeBSD-src-12b6d396b7dad8b10fa114fc17de41bd07d6280d.tar.gz |
MFC: if_bridge.c, r1.21; if_ethersubr.c, r1.198; in6_ifattach.c, r1.28;
nd6.c, r1.55; nd6_nbr.c, r1.33
> Add support for multicast to the bridge and allow inet6 addresses to be
> assigned to the interface.
>
> IPv6 auto-configuration is disabled. An IPv6 link-local address has a
> link-local scope within one link, the spec is unclear for the bridge case and
> it may cause scope violation.
>
> An address can be assigned in the usual way;
> ifconfig bridge0 inet6 xxxx:...
>
> Tested by: bmah
> Reviewed by: ume (netinet6)
> Approved by: mlaier (mentor)
Approved by: re (kensmith), mlaier (mentor)
Diffstat (limited to 'sys')
-rw-r--r-- | sys/net/if_bridge.c | 32 | ||||
-rw-r--r-- | sys/net/if_ethersubr.c | 2 | ||||
-rw-r--r-- | sys/netinet6/in6_ifattach.c | 5 | ||||
-rw-r--r-- | sys/netinet6/nd6.c | 2 | ||||
-rw-r--r-- | sys/netinet6/nd6_nbr.c | 1 |
5 files changed, 32 insertions, 10 deletions
diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 1b68d19..e4812cb 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -447,6 +447,7 @@ bridge_clone_create(struct if_clone *ifc, int unit) ifp->if_softc = sc; if_initname(ifp, ifc->ifc_name, unit); ifp->if_mtu = ETHERMTU; + ifp->if_flags = IFF_MULTICAST; ifp->if_ioctl = bridge_ioctl; ifp->if_output = bridge_output; ifp->if_start = bridge_start; @@ -541,6 +542,10 @@ bridge_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) switch (cmd) { + case SIOCADDMULTI: + case SIOCDELMULTI: + break; + case SIOCGDRVSPEC: case SIOCSDRVSPEC: if (ifd->ifd_cmd >= bridge_control_table_size) { @@ -1664,12 +1669,15 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) { struct bridge_softc *sc = ifp->if_bridge; struct bridge_iflist *bif; + struct ifnet *bifp; struct ether_header *eh; - struct mbuf *mc; + struct mbuf *mc, *mc2; if ((sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return (m); + bifp = sc->sc_ifp; + BRIDGE_LOCK(sc); bif = bridge_lookup_member_if(sc, ifp); if (bif == NULL) { @@ -1679,7 +1687,7 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) eh = mtod(m, struct ether_header *); - if (memcmp(eh->ether_dhost, IFP2ENADDR(sc->sc_ifp), + if (memcmp(eh->ether_dhost, IFP2ENADDR(bifp), ETHER_ADDR_LEN) == 0) { /* * If the packet is for us, set the packets source as the @@ -1692,9 +1700,9 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) */ /* Mark the packet as arriving on the bridge interface */ - m->m_pkthdr.rcvif = sc->sc_ifp; - BPF_MTAP(sc->sc_ifp, m); - sc->sc_ifp->if_ipackets++; + m->m_pkthdr.rcvif = bifp; + BPF_MTAP(bifp, m); + bifp->if_ipackets++; BRIDGE_UNLOCK(sc); return (m); @@ -1735,6 +1743,20 @@ bridge_input(struct ifnet *ifp, struct mbuf *m) /* Perform the bridge forwarding function with the copy. */ bridge_forward(sc, mc); + /* + * Reinject the mbuf as arriving on the bridge so we have a + * chance at claiming multicast packets. We can not loop back + * here from ether_input as a bridge is never a member of a + * bridge. + */ + KASSERT(bifp->if_bridge == NULL, + ("loop created in bridge_input")); + mc2 = m_dup(m, M_DONTWAIT); + if (mc2 != NULL) { + mc2->m_pkthdr.rcvif = bifp; + (*bifp->if_input)(bifp, mc2); + } + /* Return the original packet for local processing. */ return (m); } diff --git a/sys/net/if_ethersubr.c b/sys/net/if_ethersubr.c index cb06573..86c9f96 100644 --- a/sys/net/if_ethersubr.c +++ b/sys/net/if_ethersubr.c @@ -668,7 +668,7 @@ ether_demux(struct ifnet *ifp, struct mbuf *m) goto post_stats; #endif - if (!(BDG_ACTIVE(ifp)) && + if (!(BDG_ACTIVE(ifp)) && !(ifp->if_bridge) && !((ether_type == ETHERTYPE_VLAN || m->m_flags & M_VLANTAG) && ifp->if_nvlans > 0)) { #ifdef DEV_CARP diff --git a/sys/netinet6/in6_ifattach.c b/sys/netinet6/in6_ifattach.c index 8837a91..deb6255 100644 --- a/sys/netinet6/in6_ifattach.c +++ b/sys/netinet6/in6_ifattach.c @@ -666,9 +666,6 @@ in6_ifattach(ifp, altifp) /* some of the interfaces are inherently not IPv6 capable */ switch (ifp->if_type) { -#ifdef IFT_BRIDGE /* OpenBSD 2.8, NetBSD 1.6 */ - case IFT_BRIDGE: -#endif case IFT_PFLOG: case IFT_PFSYNC: case IFT_CARP: @@ -718,7 +715,7 @@ in6_ifattach(ifp, altifp) /* * assign a link-local address, if there's none. */ - if (ip6_auto_linklocal) { + if (ip6_auto_linklocal && ifp->if_type != IFT_BRIDGE) { ia = in6ifa_ifpforlinklocal(ifp, 0); if (ia == NULL) { if (in6_ifattach_linklocal(ifp, altifp) == 0) { diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c index 4cfd94c..5ed0280 100644 --- a/sys/netinet6/nd6.c +++ b/sys/netinet6/nd6.c @@ -2029,6 +2029,7 @@ nd6_need_cache(ifp) case IFT_CARP: #endif case IFT_GIF: /* XXX need more cases? */ + case IFT_BRIDGE: return (1); default: return (0); @@ -2059,6 +2060,7 @@ nd6_storelladdr(ifp, rt0, m, dst, desten) #ifdef IFT_IEEE80211 case IFT_IEEE80211: #endif + case IFT_BRIDGE: case IFT_ISO88025: ETHER_MAP_IPV6_MULTICAST(&SIN6(dst)->sin6_addr, desten); diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c index 14aca28..56593e2 100644 --- a/sys/netinet6/nd6_nbr.c +++ b/sys/netinet6/nd6_nbr.c @@ -967,6 +967,7 @@ nd6_ifptomac(ifp) #ifdef IFT_CARP case IFT_CARP: #endif + case IFT_BRIDGE: case IFT_ISO88025: return IF_LLADDR(ifp); default: |