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)
MFC after:	1 week
This commit is contained in:
Andrew Thompson 2005-09-06 21:11:59 +00:00
parent 4506b763e0
commit 59280079d3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=149829
5 changed files with 32 additions and 10 deletions

View File

@ -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);
}

View File

@ -672,7 +672,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

View File

@ -667,9 +667,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:
@ -719,7 +716,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) {

View File

@ -2014,6 +2014,7 @@ nd6_need_cache(ifp)
case IFT_CARP:
#endif
case IFT_GIF: /* XXX need more cases? */
case IFT_BRIDGE:
return (1);
default:
return (0);
@ -2044,6 +2045,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);

View File

@ -1028,6 +1028,7 @@ nd6_ifptomac(ifp)
#ifdef IFT_CARP
case IFT_CARP:
#endif
case IFT_BRIDGE:
case IFT_ISO88025:
return IF_LLADDR(ifp);
default: