Masao Uebayashi
2009-03-29 13:29:02 UTC
I'm trying to use bridge(4) with tap(4) for emulator's network driver backend.
Multicast packets going from within emulator can reach addresses in the
bridge, but unicast packets "disappear" misteriously. I've tracked this and
found a suspicious code fragment in sys/net/if_bridge.c:bridge_input():
1494 /*
1495 * Unicast. Make sure it's not for us.
1496 */
1497 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1498 /* It is destined for us. */
1499 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost,
1500 ETHER_ADDR_LEN) == 0
1501 #if NCARP > 0
1502 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp,
1503 eh, IFT_ETHER, 0) != NULL)
1504 #endif /* NCARP > 0 */
1505 ) {
1506 if (bif->bif_flags & IFBIF_LEARNING)
1507 (void) bridge_rtupdate(sc,
1508 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1509 m->m_pkthdr.rcvif = bif->bif_ifp;
1510 return (m);
1511 }
1512
1513 /* We just received a packet that we sent out. */
1514 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), eh->ether_shost,
1515 ETHER_ADDR_LEN) == 0
1516 #if NCARP > 0
1517 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp,
1518 eh, IFT_ETHER, 1) != NULL)
1519 #endif /* NCARP > 0 */
1520 ) {
1521 m_freem(m);
1522 return (NULL);
1523 }
1524 }
This is a loop looking for a destination interface in a given bridge. The
first if () is to compare if_sadl with packet's eh->ether_dhost, which is
OK. But the 2nd if (), which is comparing a given interface's address with
packet's source address (eh->ether_shost), happens to match, the packet just
"disappears". I don't think that this is intended behaviour.
(Think of the case that if the next interface (bif) in the list is the inteface
which has the matching destination address. This LIST_FOREACH() behaviour
depends on the order of interfaces in the list.)
Masao
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de
Multicast packets going from within emulator can reach addresses in the
bridge, but unicast packets "disappear" misteriously. I've tracked this and
found a suspicious code fragment in sys/net/if_bridge.c:bridge_input():
1494 /*
1495 * Unicast. Make sure it's not for us.
1496 */
1497 LIST_FOREACH(bif, &sc->sc_iflist, bif_next) {
1498 /* It is destined for us. */
1499 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), eh->ether_dhost,
1500 ETHER_ADDR_LEN) == 0
1501 #if NCARP > 0
1502 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp,
1503 eh, IFT_ETHER, 0) != NULL)
1504 #endif /* NCARP > 0 */
1505 ) {
1506 if (bif->bif_flags & IFBIF_LEARNING)
1507 (void) bridge_rtupdate(sc,
1508 eh->ether_shost, ifp, 0, IFBAF_DYNAMIC);
1509 m->m_pkthdr.rcvif = bif->bif_ifp;
1510 return (m);
1511 }
1512
1513 /* We just received a packet that we sent out. */
1514 if (memcmp(CLLADDR(bif->bif_ifp->if_sadl), eh->ether_shost,
1515 ETHER_ADDR_LEN) == 0
1516 #if NCARP > 0
1517 || (bif->bif_ifp->if_carp && carp_ourether(bif->bif_ifp->if_carp,
1518 eh, IFT_ETHER, 1) != NULL)
1519 #endif /* NCARP > 0 */
1520 ) {
1521 m_freem(m);
1522 return (NULL);
1523 }
1524 }
This is a loop looking for a destination interface in a given bridge. The
first if () is to compare if_sadl with packet's eh->ether_dhost, which is
OK. But the 2nd if (), which is comparing a given interface's address with
packet's source address (eh->ether_shost), happens to match, the packet just
"disappears". I don't think that this is intended behaviour.
(Think of the case that if the next interface (bif) in the list is the inteface
which has the matching destination address. This LIST_FOREACH() behaviour
depends on the order of interfaces in the list.)
Masao
--
Posted automagically by a mail2news gateway at muc.de e.V.
Please direct questions, flames, donations, etc. to news-***@muc.de