summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authorthompsa <thompsa@FreeBSD.org>2005-09-13 18:02:39 +0000
committerthompsa <thompsa@FreeBSD.org>2005-09-13 18:02:39 +0000
commit12b6d396b7dad8b10fa114fc17de41bd07d6280d (patch)
tree78be1cf510396dcdde6433a2af92ed05804e0a6a /sys
parentca6608f3914b3f120d57ccb0f357f503bceed17a (diff)
downloadFreeBSD-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.c32
-rw-r--r--sys/net/if_ethersubr.c2
-rw-r--r--sys/netinet6/in6_ifattach.c5
-rw-r--r--sys/netinet6/nd6.c2
-rw-r--r--sys/netinet6/nd6_nbr.c1
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:
OpenPOWER on IntegriCloud