Lines Matching +full:full +full:- +full:bridge

3 /*-
4 * SPDX-License-Identifier: BSD-4-Clause
69 * Network interface bridge support.
73 * - Currently only supports Ethernet-like interfaces (Ethernet,
75 * to bridge other types of interfaces (maybe consider
172 #define BRIDGE_RTHASH_MASK (BRIDGE_RTHASH_SIZE - 1)
207 * Bridge locking
209 * The bridge relies heavily on the epoch(9) system to protect its data
216 * - BRIDGE_RT_LOCK, for any change to bridge_rtnodes
217 * - BRIDGE_LOCK, for any other change
220 * calls to bridge member interfaces and these ioctl()s can sleep.
221 * The BRIDGE_RT_LOCK is a non-sleepable mutex, because it is sometimes
225 sx_init(&(_sc)->sc_sx, "if_bridge"); \
226 mtx_init(&(_sc)->sc_rt_mtx, "if_bridge rt", NULL, MTX_DEF); \
229 sx_destroy(&(_sc)->sc_sx); \
230 mtx_destroy(&(_sc)->sc_rt_mtx); \
232 #define BRIDGE_LOCK(_sc) sx_xlock(&(_sc)->sc_sx)
233 #define BRIDGE_UNLOCK(_sc) sx_xunlock(&(_sc)->sc_sx)
234 #define BRIDGE_LOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SX_XLOCKED)
236 MPASS(in_epoch(net_epoch_preempt) || sx_xlocked(&(_sc)->sc_sx))
237 #define BRIDGE_UNLOCK_ASSERT(_sc) sx_assert(&(_sc)->sc_sx, SX_UNLOCKED)
238 #define BRIDGE_RT_LOCK(_sc) mtx_lock(&(_sc)->sc_rt_mtx)
239 #define BRIDGE_RT_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_rt_mtx)
240 #define BRIDGE_RT_LOCK_ASSERT(_sc) mtx_assert(&(_sc)->sc_rt_mtx, MA_OWNED)
242 MPASS(in_epoch(net_epoch_preempt) || mtx_owned(&(_sc)->sc_rt_mtx))
247 * Bridge interface list entry.
252 struct bridge_softc *bif_sc; /* parent bridge */
266 * Bridge route node.
279 #define brt_ifp brt_dst->bif_ifp
282 * Software state for each bridge.
292 struct callout sc_brcallout; /* bridge callout */
304 ifbr_flags_t sc_flags; /* bridge flags */
442 * Use the "null" value from IEEE 802.1Q-2014 Table 9-2
446 ((_m->m_flags & M_VLANTAG) ? EVL_VLANOFTAG(_m->m_pkthdr.ether_vtag) : DOT1Q_VID_NULL)
454 static SYSCTL_NODE(_net_link, IFT_BRIDGE, bridge, CTLFLAG_RW | CTLFLAG_MPSAFE, 0,
455 "Bridge");
464 /* run pfil hooks on the bridge interface */
469 "Packet filter on the bridge interface");
503 /* share MAC with first bridge member */
508 "Inherit MAC address from the first bridge member");
514 "Allow overlap of link-local scope "
515 "zones of a bridge interface and the member interfaces");
524 /* allow IP addresses on bridge members */
529 "Allow layer 3 addresses on bridge members (deprecated)");
553 #define BC_F_SUSER 0x04 /* do super-user check */
677 static const char bridge_name[] = "bridge";
753 * handler for net.link.bridge.ipfw
769 * really wants both then they can re-enable pfil_bridge and/or in sysctl_pfil_ipfw()
770 * pfil_member. Also allow non-ip packets as ipfw can filter by in sysctl_pfil_ipfw()
791 struct bridge_softc *sc = ifp->if_softc; in bridge_reassign()
796 while ((bif = CK_LIST_FIRST(&sc->sc_iflist)) != NULL) in bridge_reassign()
799 while ((bif = CK_LIST_FIRST(&sc->sc_spanlist)) != NULL) { in bridge_reassign()
812 * Return the bridge softc for an ifnet.
821 bif = ifp->if_bridge; in bridge_get_softc()
824 return (bif->bif_sc); in bridge_get_softc()
830 * Return true if two interfaces are in the same bridge. This is only used by
843 return (bifa->bif_sc == bifb->bif_sc); in bridge_same()
849 * Create a new bridge instance.
859 ifp = sc->sc_ifp = if_alloc(IFT_ETHER); in bridge_clone_create()
862 sc->sc_brtmax = BRIDGE_RTABLE_MAX; in bridge_clone_create()
863 sc->sc_brttimeout = BRIDGE_RTABLE_TIMEOUT; in bridge_clone_create()
868 callout_init_mtx(&sc->sc_brcallout, &sc->sc_rt_mtx, 0); in bridge_clone_create()
870 CK_LIST_INIT(&sc->sc_iflist); in bridge_clone_create()
871 CK_LIST_INIT(&sc->sc_spanlist); in bridge_clone_create()
873 ifp->if_softc = sc; in bridge_clone_create()
874 if_initname(ifp, bridge_name, ifd->unit); in bridge_clone_create()
875 ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; in bridge_clone_create()
876 ifp->if_capabilities = ifp->if_capenable = IFCAP_VLAN_HWTAGGING; in bridge_clone_create()
877 ifp->if_ioctl = bridge_ioctl; in bridge_clone_create()
879 ifp->if_start = bridge_altq_start; in bridge_clone_create()
880 ifp->if_transmit = bridge_altq_transmit; in bridge_clone_create()
881 IFQ_SET_MAXLEN(&ifp->if_snd, ifqmaxlen); in bridge_clone_create()
882 ifp->if_snd.ifq_drv_maxlen = 0; in bridge_clone_create()
883 IFQ_SET_READY(&ifp->if_snd); in bridge_clone_create()
885 ifp->if_transmit = bridge_transmit; in bridge_clone_create()
887 ifp->if_qflush = bridge_qflush; in bridge_clone_create()
888 ifp->if_init = bridge_init; in bridge_clone_create()
889 ifp->if_type = IFT_BRIDGE; in bridge_clone_create()
891 ether_gen_addr(ifp, &sc->sc_defaddr); in bridge_clone_create()
893 bstp_attach(&sc->sc_stp, &bridge_ops); in bridge_clone_create()
894 ether_ifattach(ifp, sc->sc_defaddr.octet); in bridge_clone_create()
896 ifp->if_baudrate = 0; in bridge_clone_create()
898 ifp->if_reassign = bridge_reassign; in bridge_clone_create()
900 sc->sc_if_input = ifp->if_input; /* ether_input */ in bridge_clone_create()
901 ifp->if_input = bridge_inject; in bridge_clone_create()
904 * Allow BRIDGE_INPUT() to pass in packets originating from the bridge in bridge_clone_create()
908 ifp->if_bridge_input = bridge_input; in bridge_clone_create()
932 * Destroy a bridge instance.
937 struct bridge_softc *sc = ifp->if_softc; in bridge_clone_destroy()
944 ifp->if_flags &= ~IFF_UP; in bridge_clone_destroy()
946 while ((bif = CK_LIST_FIRST(&sc->sc_iflist)) != NULL) in bridge_clone_destroy()
949 while ((bif = CK_LIST_FIRST(&sc->sc_spanlist)) != NULL) { in bridge_clone_destroy()
960 callout_drain(&sc->sc_brcallout); in bridge_clone_destroy()
966 bstp_detach(&sc->sc_stp); in bridge_clone_destroy()
968 IFQ_PURGE(&ifp->if_snd); in bridge_clone_destroy()
975 NET_EPOCH_CALL(bridge_clone_destroy_cb, &sc->sc_epoch_ctx); in bridge_clone_destroy()
988 struct bridge_softc *sc = ifp->if_softc; in bridge_ioctl()
1014 if (ifd->ifd_cmd >= bridge_control_table_size) { in bridge_ioctl()
1018 bc = &bridge_control_table[ifd->ifd_cmd]; in bridge_ioctl()
1021 (bc->bc_flags & BC_F_COPYOUT) == 0) { in bridge_ioctl()
1028 (bc->bc_flags & BC_F_COPYOUT) != 0) { in bridge_ioctl()
1035 if (bc->bc_flags & BC_F_SUSER) { in bridge_ioctl()
1043 if (ifd->ifd_len != bc->bc_argsize || in bridge_ioctl()
1044 ifd->ifd_len > sizeof(args)) { in bridge_ioctl()
1050 if (bc->bc_flags & BC_F_COPYIN) { in bridge_ioctl()
1051 error = copyin(ifd->ifd_data, &args, ifd->ifd_len); in bridge_ioctl()
1056 oldmtu = ifp->if_mtu; in bridge_ioctl()
1057 error = (*bc->bc_func)(sc, &args); in bridge_ioctl()
1062 * Bridge MTU may change during addition of the first port. in bridge_ioctl()
1065 if (ifp->if_mtu != oldmtu) in bridge_ioctl()
1068 if (bc->bc_flags & BC_F_COPYOUT) in bridge_ioctl()
1069 error = copyout(&args, ifd->ifd_data, ifd->ifd_len); in bridge_ioctl()
1074 if (!(ifp->if_flags & IFF_UP) && in bridge_ioctl()
1075 (ifp->if_drv_flags & IFF_DRV_RUNNING)) { in bridge_ioctl()
1081 } else if ((ifp->if_flags & IFF_UP) && in bridge_ioctl()
1082 !(ifp->if_drv_flags & IFF_DRV_RUNNING)) { in bridge_ioctl()
1088 (*ifp->if_init)(sc); in bridge_ioctl()
1094 oldmtu = sc->sc_ifp->if_mtu; in bridge_ioctl()
1096 if (ifr->ifr_mtu < IF_MINMTU) { in bridge_ioctl()
1101 if (CK_LIST_EMPTY(&sc->sc_iflist)) { in bridge_ioctl()
1102 sc->sc_ifp->if_mtu = ifr->ifr_mtu; in bridge_ioctl()
1105 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl()
1106 error = (*bif->bif_ifp->if_ioctl)(bif->bif_ifp, in bridge_ioctl()
1110 " member %s\n", sc->sc_ifp->if_xname, in bridge_ioctl()
1111 ifr->ifr_mtu, in bridge_ioctl()
1112 bif->bif_ifp->if_xname); in bridge_ioctl()
1119 ifr->ifr_mtu = oldmtu; in bridge_ioctl()
1120 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl()
1121 (*bif->bif_ifp->if_ioctl)(bif->bif_ifp, in bridge_ioctl()
1127 sc->sc_ifp->if_mtu = ifr->ifr_mtu; in bridge_ioctl()
1162 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_mutecaps()
1164 mask &= bif->bif_savedcaps; in bridge_mutecaps()
1167 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_mutecaps()
1168 enabled = bif->bif_ifp->if_capenable; in bridge_mutecaps()
1180 struct ifnet *ifp = bif->bif_ifp; in bridge_set_ifcap()
1187 if (ifp->if_capenable != set) { in bridge_set_ifcap()
1188 error = (*ifp->if_ioctl)(ifp, SIOCSIFCAP, (caddr_t)&ifr); in bridge_set_ifcap()
1190 if_printf(sc->sc_ifp, in bridge_set_ifcap()
1192 ifp->if_xname, error); in bridge_set_ifcap()
1194 stuck = ifp->if_capenable & mask & ~set; in bridge_set_ifcap()
1196 if_printf(sc->sc_ifp, in bridge_set_ifcap()
1198 ifp->if_xname, stuck); in bridge_set_ifcap()
1205 * Lookup a bridge member interface.
1215 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_lookup_member()
1216 ifp = bif->bif_ifp; in bridge_lookup_member()
1217 if (strcmp(ifp->if_xname, name) == 0) in bridge_lookup_member()
1227 * Lookup a bridge member interface by ifnet*.
1233 return (member_ifp->if_bridge); in bridge_lookup_member_if()
1255 struct ifnet *ifs = bif->bif_ifp; in bridge_delete_member()
1261 if (bif->bif_flags & IFBIF_STP) in bridge_delete_member()
1262 bstp_disable(&bif->bif_stp); in bridge_delete_member()
1264 ifs->if_bridge = NULL; in bridge_delete_member()
1268 * If removing the interface that gave the bridge its mac address, set in bridge_delete_member()
1269 * the mac address of the bridge to the address of the next member, or in bridge_delete_member()
1272 if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) { in bridge_delete_member()
1273 if (CK_LIST_EMPTY(&sc->sc_iflist)) { in bridge_delete_member()
1274 bcopy(&sc->sc_defaddr, in bridge_delete_member()
1275 IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); in bridge_delete_member()
1276 sc->sc_ifaddr = NULL; in bridge_delete_member()
1278 bifl = CK_LIST_FIRST(&sc->sc_iflist); in bridge_delete_member()
1279 fif = bifl->bif_ifp; in bridge_delete_member()
1281 IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); in bridge_delete_member()
1282 sc->sc_ifaddr = fif; in bridge_delete_member()
1284 EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); in bridge_delete_member()
1292 KASSERT(bif->bif_addrcnt == 0, in bridge_delete_member()
1293 ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt)); in bridge_delete_member()
1295 ifs->if_bridge_output = NULL; in bridge_delete_member()
1296 ifs->if_bridge_input = NULL; in bridge_delete_member()
1297 ifs->if_bridge_linkstate = NULL; in bridge_delete_member()
1299 switch (ifs->if_type) { in bridge_delete_member()
1307 if (ifs->if_flags & IFF_PROMISC) in bridge_delete_member()
1320 /* Re-enable any interface capabilities */ in bridge_delete_member()
1321 bridge_set_ifcap(sc, bif, bif->bif_savedcaps); in bridge_delete_member()
1323 bstp_destroy(&bif->bif_stp); /* prepare to free */ in bridge_delete_member()
1325 NET_EPOCH_CALL(bridge_delete_member_cb, &bif->bif_epoch_ctx); in bridge_delete_member()
1338 KASSERT(bif->bif_ifp->if_bridge == NULL, in bridge_delete_span()
1343 NET_EPOCH_CALL(bridge_delete_member_cb, &bif->bif_epoch_ctx); in bridge_delete_span()
1354 ifs = ifunit(req->ifbr_ifsname); in bridge_ioctl_add()
1357 req->ifbr_ifsname)); in bridge_ioctl_add()
1358 if (ifs->if_ioctl == NULL) /* must be supported */ in bridge_ioctl_add()
1362 * If the new interface is a vlan(4), it could be a bridge SVI. in bridge_ioctl_add()
1365 if (ifs->if_type == IFT_L2VLAN) { in bridge_ioctl_add()
1376 is_bridge = (parent != NULL && parent->if_type == IFT_BRIDGE); in bridge_ioctl_add()
1381 "Bridge SVI cannot be added to a bridge")); in bridge_ioctl_add()
1385 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) in bridge_ioctl_add()
1386 if (ifs == bif->bif_ifp) in bridge_ioctl_add()
1390 if (ifs->if_bridge) { in bridge_ioctl_add()
1391 struct bridge_iflist *sbif = ifs->if_bridge; in bridge_ioctl_add()
1392 if (sbif->bif_sc == sc) in bridge_ioctl_add()
1394 "Interface is already a member of this bridge")); in bridge_ioctl_add()
1397 "Interface is already a member of another bridge")); in bridge_ioctl_add()
1400 switch (ifs->if_type) { in bridge_ioctl_add()
1412 * Two valid inet6 addresses with link-local scope must not be in bridge_ioctl_add()
1415 * of link-local scope zone. Attempts to add a member in bridge_ioctl_add()
1421 /* Check if the parent interface has a link-local scope addr. */ in bridge_ioctl_add()
1423 in6ifa_llaonifp(sc->sc_ifp) != NULL) { in bridge_ioctl_add()
1428 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl_add()
1429 if (in6ifa_llaonifp(bif->bif_ifp)) { in bridge_ioctl_add()
1430 in6_ifdetach(bif->bif_ifp); in bridge_ioctl_add()
1431 if_printf(sc->sc_ifp, in bridge_ioctl_add()
1435 bif->bif_ifp->if_xname); in bridge_ioctl_add()
1440 if_printf(sc->sc_ifp, in bridge_ioctl_add()
1444 ifs->if_xname); in bridge_ioctl_add()
1451 * assigned IP addresses to be added to a bridge. Skip this check in bridge_ioctl_add()
1453 * interface is separate from the bridge's Ethernet segment. in bridge_ioctl_add()
1455 if (ifs->if_type != IFT_GIF) { in bridge_ioctl_add()
1458 CK_STAILQ_FOREACH(ifa, &ifs->if_addrhead, ifa_link) { in bridge_ioctl_add()
1459 if (ifa->ifa_addr->sa_family != AF_INET && in bridge_ioctl_add()
1460 ifa->ifa_addr->sa_family != AF_INET6) in bridge_ioctl_add()
1464 if_printf(sc->sc_ifp, in bridge_ioctl_add()
1468 "release.\n", ifs->if_xname); in bridge_ioctl_add()
1479 if (CK_LIST_EMPTY(&sc->sc_iflist)) in bridge_ioctl_add()
1480 sc->sc_ifp->if_mtu = ifs->if_mtu; in bridge_ioctl_add()
1481 else if (sc->sc_ifp->if_mtu != ifs->if_mtu) { in bridge_ioctl_add()
1485 ifs->if_xname); in bridge_ioctl_add()
1486 ifr.ifr_mtu = sc->sc_ifp->if_mtu; in bridge_ioctl_add()
1488 error = (*ifs->if_ioctl)(ifs, in bridge_ioctl_add()
1492 " new member %s\n", sc->sc_ifp->if_xname, in bridge_ioctl_add()
1494 ifs->if_xname); in bridge_ioctl_add()
1504 bif->bif_sc = sc; in bridge_ioctl_add()
1505 bif->bif_ifp = ifs; in bridge_ioctl_add()
1506 bif->bif_flags = IFBIF_LEARNING | IFBIF_DISCOVER; in bridge_ioctl_add()
1507 bif->bif_savedcaps = ifs->if_capenable; in bridge_ioctl_add()
1508 bif->bif_vlanproto = ETHERTYPE_VLAN; in bridge_ioctl_add()
1509 bif->bif_pvid = sc->sc_defpvid; in bridge_ioctl_add()
1510 if (sc->sc_flags & IFBRF_DEFQINQ) in bridge_ioctl_add()
1511 bif->bif_flags |= IFBIF_QINQ; in bridge_ioctl_add()
1514 * Assign the interface's MAC address to the bridge if it's the first in bridge_ioctl_add()
1515 * member and the MAC address of the bridge has not been changed from in bridge_ioctl_add()
1518 if (V_bridge_inherit_mac && CK_LIST_EMPTY(&sc->sc_iflist) && in bridge_ioctl_add()
1519 !memcmp(IF_LLADDR(sc->sc_ifp), sc->sc_defaddr.octet, ETHER_ADDR_LEN)) { in bridge_ioctl_add()
1520 bcopy(IF_LLADDR(ifs), IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); in bridge_ioctl_add()
1521 sc->sc_ifaddr = ifs; in bridge_ioctl_add()
1522 EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); in bridge_ioctl_add()
1525 ifs->if_bridge = bif; in bridge_ioctl_add()
1526 ifs->if_bridge_output = bridge_output; in bridge_ioctl_add()
1527 ifs->if_bridge_input = bridge_input; in bridge_ioctl_add()
1528 ifs->if_bridge_linkstate = bridge_linkstate; in bridge_ioctl_add()
1529 bstp_create(&sc->sc_stp, &bif->bif_stp, bif->bif_ifp); in bridge_ioctl_add()
1535 CK_LIST_INSERT_HEAD(&sc->sc_iflist, bif, bif_next); in bridge_ioctl_add()
1542 switch (ifs->if_type) { in bridge_ioctl_add()
1560 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_del()
1562 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_del()
1576 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_gifflags()
1578 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_gifflags()
1580 bp = &bif->bif_stp; in bridge_ioctl_gifflags()
1581 req->ifbr_ifsflags = bif->bif_flags; in bridge_ioctl_gifflags()
1582 req->ifbr_state = bp->bp_state; in bridge_ioctl_gifflags()
1583 req->ifbr_priority = bp->bp_priority; in bridge_ioctl_gifflags()
1584 req->ifbr_path_cost = bp->bp_path_cost; in bridge_ioctl_gifflags()
1585 req->ifbr_portno = bif->bif_ifp->if_index & 0xfff; in bridge_ioctl_gifflags()
1586 req->ifbr_proto = bp->bp_protover; in bridge_ioctl_gifflags()
1587 req->ifbr_role = bp->bp_role; in bridge_ioctl_gifflags()
1588 req->ifbr_stpflags = bp->bp_flags; in bridge_ioctl_gifflags()
1589 req->ifbr_addrcnt = bif->bif_addrcnt; in bridge_ioctl_gifflags()
1590 req->ifbr_addrmax = bif->bif_addrmax; in bridge_ioctl_gifflags()
1591 req->ifbr_addrexceeded = bif->bif_addrexceeded; in bridge_ioctl_gifflags()
1592 req->ifbr_pvid = bif->bif_pvid; in bridge_ioctl_gifflags()
1593 req->ifbr_vlanproto = bif->bif_vlanproto; in bridge_ioctl_gifflags()
1596 if (bp->bp_operedge) in bridge_ioctl_gifflags()
1597 req->ifbr_ifsflags |= IFBIF_BSTP_EDGE; in bridge_ioctl_gifflags()
1598 if (bp->bp_flags & BSTP_PORT_AUTOEDGE) in bridge_ioctl_gifflags()
1599 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOEDGE; in bridge_ioctl_gifflags()
1600 if (bp->bp_ptp_link) in bridge_ioctl_gifflags()
1601 req->ifbr_ifsflags |= IFBIF_BSTP_PTP; in bridge_ioctl_gifflags()
1602 if (bp->bp_flags & BSTP_PORT_AUTOPTP) in bridge_ioctl_gifflags()
1603 req->ifbr_ifsflags |= IFBIF_BSTP_AUTOPTP; in bridge_ioctl_gifflags()
1604 if (bp->bp_flags & BSTP_PORT_ADMEDGE) in bridge_ioctl_gifflags()
1605 req->ifbr_ifsflags |= IFBIF_BSTP_ADMEDGE; in bridge_ioctl_gifflags()
1606 if (bp->bp_flags & BSTP_PORT_ADMCOST) in bridge_ioctl_gifflags()
1607 req->ifbr_ifsflags |= IFBIF_BSTP_ADMCOST; in bridge_ioctl_gifflags()
1620 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_sifflags()
1622 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifflags()
1623 bp = &bif->bif_stp; in bridge_ioctl_sifflags()
1625 if (req->ifbr_ifsflags & IFBIF_SPAN) in bridge_ioctl_sifflags()
1631 if (req->ifbr_ifsflags & IFBIF_STP) { in bridge_ioctl_sifflags()
1632 if ((bif->bif_flags & IFBIF_STP) == 0) { in bridge_ioctl_sifflags()
1633 error = bstp_enable(&bif->bif_stp); in bridge_ioctl_sifflags()
1641 if ((bif->bif_flags & IFBIF_STP) != 0) in bridge_ioctl_sifflags()
1642 bstp_disable(&bif->bif_stp); in bridge_ioctl_sifflags()
1646 bstp_set_edge(bp, req->ifbr_ifsflags & IFBIF_BSTP_EDGE ? 1 : 0); in bridge_ioctl_sifflags()
1647 bstp_set_autoedge(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOEDGE ? 1 : 0); in bridge_ioctl_sifflags()
1648 bstp_set_ptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_PTP ? 1 : 0); in bridge_ioctl_sifflags()
1649 bstp_set_autoptp(bp, req->ifbr_ifsflags & IFBIF_BSTP_AUTOPTP ? 1 : 0); in bridge_ioctl_sifflags()
1651 /* Save the bits relating to the bridge */ in bridge_ioctl_sifflags()
1652 bif->bif_flags = req->ifbr_ifsflags & IFBIFMASK; in bridge_ioctl_sifflags()
1664 sc->sc_brtmax = param->ifbrp_csize; in bridge_ioctl_scache()
1675 param->ifbrp_csize = sc->sc_brtmax; in bridge_ioctl_gcache()
1690 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) in bridge_ioctl_gifs()
1692 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) in bridge_ioctl_gifs()
1696 if (bifc->ifbic_len == 0) { in bridge_ioctl_gifs()
1697 bifc->ifbic_len = buflen; in bridge_ioctl_gifs()
1706 len = min(bifc->ifbic_len, buflen); in bridge_ioctl_gifs()
1708 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl_gifs()
1712 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname, in bridge_ioctl_gifs()
1721 len -= sizeof(breq); in bridge_ioctl_gifs()
1723 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { in bridge_ioctl_gifs()
1727 strlcpy(breq.ifbr_ifsname, bif->bif_ifp->if_xname, in bridge_ioctl_gifs()
1729 breq.ifbr_ifsflags = bif->bif_flags; in bridge_ioctl_gifs()
1730 breq.ifbr_portno = bif->bif_ifp->if_index & 0xfff; in bridge_ioctl_gifs()
1734 len -= sizeof(breq); in bridge_ioctl_gifs()
1737 bifc->ifbic_len = sizeof(breq) * count; in bridge_ioctl_gifs()
1738 error = copyout(outbuf, bifc->ifbic_req, bifc->ifbic_len); in bridge_ioctl_gifs()
1752 if (bac->ifbac_len == 0) in bridge_ioctl_rts()
1756 CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) in bridge_ioctl_rts()
1766 len = min(bac->ifbac_len, buflen); in bridge_ioctl_rts()
1768 CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { in bridge_ioctl_rts()
1771 strlcpy(bareq.ifba_ifsname, brt->brt_ifp->if_xname, in bridge_ioctl_rts()
1773 memcpy(bareq.ifba_dst, brt->brt_addr, sizeof(brt->brt_addr)); in bridge_ioctl_rts()
1774 bareq.ifba_vlan = brt->brt_vlan; in bridge_ioctl_rts()
1775 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && in bridge_ioctl_rts()
1776 time_uptime < brt->brt_expire) in bridge_ioctl_rts()
1777 bareq.ifba_expire = brt->brt_expire - time_uptime; in bridge_ioctl_rts()
1780 bareq.ifba_flags = brt->brt_flags; in bridge_ioctl_rts()
1785 len -= sizeof(bareq); in bridge_ioctl_rts()
1788 bac->ifbac_len = sizeof(bareq) * count; in bridge_ioctl_rts()
1789 error = copyout(outbuf, bac->ifbac_req, bac->ifbac_len); in bridge_ioctl_rts()
1803 bif = bridge_lookup_member(sc, req->ifba_ifsname); in bridge_ioctl_saddr()
1806 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_saddr()
1810 error = bridge_rtupdate(sc, req->ifba_dst, req->ifba_vlan, bif, 1, in bridge_ioctl_saddr()
1811 req->ifba_flags); in bridge_ioctl_saddr()
1822 sc->sc_brttimeout = param->ifbrp_ctime; in bridge_ioctl_sto()
1831 param->ifbrp_ctime = sc->sc_brttimeout; in bridge_ioctl_gto()
1839 int vlan = req->ifba_vlan; in bridge_ioctl_daddr()
1845 return (bridge_rtdaddr(sc, req->ifba_dst, vlan)); in bridge_ioctl_daddr()
1854 bridge_rtflush(sc, req->ifbr_ifsflags); in bridge_ioctl_flush()
1864 struct bstp_state *bs = &sc->sc_stp; in bridge_ioctl_gpri()
1866 param->ifbrp_prio = bs->bs_bridge_priority; in bridge_ioctl_gpri()
1875 return (bstp_set_priority(&sc->sc_stp, param->ifbrp_prio)); in bridge_ioctl_spri()
1882 struct bstp_state *bs = &sc->sc_stp; in bridge_ioctl_ght()
1884 param->ifbrp_hellotime = bs->bs_bridge_htime >> 8; in bridge_ioctl_ght()
1893 return (bstp_set_htime(&sc->sc_stp, param->ifbrp_hellotime)); in bridge_ioctl_sht()
1900 struct bstp_state *bs = &sc->sc_stp; in bridge_ioctl_gfd()
1902 param->ifbrp_fwddelay = bs->bs_bridge_fdelay >> 8; in bridge_ioctl_gfd()
1911 return (bstp_set_fdelay(&sc->sc_stp, param->ifbrp_fwddelay)); in bridge_ioctl_sfd()
1918 struct bstp_state *bs = &sc->sc_stp; in bridge_ioctl_gma()
1920 param->ifbrp_maxage = bs->bs_bridge_max_age >> 8; in bridge_ioctl_gma()
1929 return (bstp_set_maxage(&sc->sc_stp, param->ifbrp_maxage)); in bridge_ioctl_sma()
1938 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_sifprio()
1940 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifprio()
1942 return (bstp_set_port_priority(&bif->bif_stp, req->ifbr_priority)); in bridge_ioctl_sifprio()
1951 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_sifcost()
1953 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifcost()
1955 return (bstp_set_path_cost(&bif->bif_stp, req->ifbr_path_cost)); in bridge_ioctl_sifcost()
1964 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_sifmaxaddr()
1966 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifmaxaddr()
1968 bif->bif_addrmax = req->ifbr_addrmax; in bridge_ioctl_sifmaxaddr()
1978 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_sifpvid()
1980 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifpvid()
1982 if (req->ifbr_pvid > DOT1Q_VID_MAX) in bridge_ioctl_sifpvid()
1985 bif->bif_pvid = req->ifbr_pvid; in bridge_ioctl_sifpvid()
1995 if ((sc->sc_flags & IFBRF_VLANFILTER) == 0) in bridge_ioctl_sifvlanset()
1998 bif = bridge_lookup_member(sc, req->bv_ifname); in bridge_ioctl_sifvlanset()
2000 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_sifvlanset()
2003 if (BRVLAN_TEST(&req->bv_set, DOT1Q_VID_NULL) || in bridge_ioctl_sifvlanset()
2004 BRVLAN_TEST(&req->bv_set, DOT1Q_VID_RSVD_IMPL)) in bridge_ioctl_sifvlanset()
2007 switch (req->bv_op) { in bridge_ioctl_sifvlanset()
2010 BIT_COPY(BRVLAN_SETSIZE, &req->bv_set, &bif->bif_vlan_set); in bridge_ioctl_sifvlanset()
2015 BIT_OR(BRVLAN_SETSIZE, &bif->bif_vlan_set, &req->bv_set); in bridge_ioctl_sifvlanset()
2020 BIT_ANDNOT(BRVLAN_SETSIZE, &bif->bif_vlan_set, &req->bv_set); in bridge_ioctl_sifvlanset()
2038 bif = bridge_lookup_member(sc, req->bv_ifname); in bridge_ioctl_gifvlanset()
2040 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_gifvlanset()
2042 BIT_COPY(BRVLAN_SETSIZE, &bif->bif_vlan_set, &req->bv_set); in bridge_ioctl_gifvlanset()
2053 ifs = ifunit(req->ifbr_ifsname); in bridge_ioctl_addspan()
2057 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) in bridge_ioctl_addspan()
2058 if (ifs == bif->bif_ifp) in bridge_ioctl_addspan()
2062 if (ifs->if_bridge != NULL) in bridge_ioctl_addspan()
2064 "Interface is already a bridge member")); in bridge_ioctl_addspan()
2066 switch (ifs->if_type) { in bridge_ioctl_addspan()
2079 bif->bif_ifp = ifs; in bridge_ioctl_addspan()
2080 bif->bif_flags = IFBIF_SPAN; in bridge_ioctl_addspan()
2082 CK_LIST_INSERT_HEAD(&sc->sc_spanlist, bif, bif_next); in bridge_ioctl_addspan()
2094 ifs = ifunit(req->ifbr_ifsname); in bridge_ioctl_delspan()
2098 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) in bridge_ioctl_delspan()
2099 if (ifs == bif->bif_ifp) in bridge_ioctl_delspan()
2114 struct bstp_state *bs = &sc->sc_stp; in bridge_ioctl_gbparam()
2117 req->ifbop_maxage = bs->bs_bridge_max_age >> 8; in bridge_ioctl_gbparam()
2118 req->ifbop_hellotime = bs->bs_bridge_htime >> 8; in bridge_ioctl_gbparam()
2119 req->ifbop_fwddelay = bs->bs_bridge_fdelay >> 8; in bridge_ioctl_gbparam()
2121 root_port = bs->bs_root_port; in bridge_ioctl_gbparam()
2123 req->ifbop_root_port = 0; in bridge_ioctl_gbparam()
2125 req->ifbop_root_port = root_port->bp_ifp->if_index; in bridge_ioctl_gbparam()
2127 req->ifbop_holdcount = bs->bs_txholdcount; in bridge_ioctl_gbparam()
2128 req->ifbop_priority = bs->bs_bridge_priority; in bridge_ioctl_gbparam()
2129 req->ifbop_protocol = bs->bs_protover; in bridge_ioctl_gbparam()
2130 req->ifbop_root_path_cost = bs->bs_root_pv.pv_cost; in bridge_ioctl_gbparam()
2131 req->ifbop_bridgeid = bs->bs_bridge_pv.pv_dbridge_id; in bridge_ioctl_gbparam()
2132 req->ifbop_designated_root = bs->bs_root_pv.pv_root_id; in bridge_ioctl_gbparam()
2133 req->ifbop_designated_bridge = bs->bs_root_pv.pv_dbridge_id; in bridge_ioctl_gbparam()
2134 req->ifbop_last_tc_time.tv_sec = bs->bs_last_tc_time.tv_sec; in bridge_ioctl_gbparam()
2135 req->ifbop_last_tc_time.tv_usec = bs->bs_last_tc_time.tv_usec; in bridge_ioctl_gbparam()
2145 param->ifbrp_cexceeded = sc->sc_brtexceeded; in bridge_ioctl_grte()
2160 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl_gifsstp()
2161 if ((bif->bif_flags & IFBIF_STP) != 0) in bridge_ioctl_gifsstp()
2166 if (bifstp->ifbpstp_len == 0) { in bridge_ioctl_gifsstp()
2167 bifstp->ifbpstp_len = buflen; in bridge_ioctl_gifsstp()
2177 len = min(bifstp->ifbpstp_len, buflen); in bridge_ioctl_gifsstp()
2179 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_ioctl_gifsstp()
2183 if ((bif->bif_flags & IFBIF_STP) == 0) in bridge_ioctl_gifsstp()
2186 bp = &bif->bif_stp; in bridge_ioctl_gifsstp()
2187 bpreq.ifbp_portno = bif->bif_ifp->if_index & 0xfff; in bridge_ioctl_gifsstp()
2188 bpreq.ifbp_fwd_trans = bp->bp_forward_transitions; in bridge_ioctl_gifsstp()
2189 bpreq.ifbp_design_cost = bp->bp_desg_pv.pv_cost; in bridge_ioctl_gifsstp()
2190 bpreq.ifbp_design_port = bp->bp_desg_pv.pv_port_id; in bridge_ioctl_gifsstp()
2191 bpreq.ifbp_design_bridge = bp->bp_desg_pv.pv_dbridge_id; in bridge_ioctl_gifsstp()
2192 bpreq.ifbp_design_root = bp->bp_desg_pv.pv_root_id; in bridge_ioctl_gifsstp()
2197 len -= sizeof(bpreq); in bridge_ioctl_gifsstp()
2200 bifstp->ifbpstp_len = sizeof(bpreq) * count; in bridge_ioctl_gifsstp()
2201 error = copyout(outbuf, bifstp->ifbpstp_req, bifstp->ifbpstp_len); in bridge_ioctl_gifsstp()
2211 return (bstp_set_protocol(&sc->sc_stp, param->ifbrp_proto)); in bridge_ioctl_sproto()
2219 return (bstp_set_holdcount(&sc->sc_stp, param->ifbrp_txhc)); in bridge_ioctl_stxhc()
2227 param->ifbrp_flags = sc->sc_flags; in bridge_ioctl_gflags()
2237 sc->sc_flags = param->ifbrp_flags; in bridge_ioctl_sflags()
2247 param->ifbrp_defpvid = sc->sc_defpvid; in bridge_ioctl_gdefpvid()
2258 if (param->ifbrp_defpvid > DOT1Q_VID_MAX) in bridge_ioctl_sdefpvid()
2261 sc->sc_defpvid = param->ifbrp_defpvid; in bridge_ioctl_sdefpvid()
2272 bif = bridge_lookup_member(sc, req->ifbr_ifsname); in bridge_ioctl_svlanproto()
2274 return (EXTERROR(ENOENT, "Interface is not a bridge member")); in bridge_ioctl_svlanproto()
2276 if (req->ifbr_vlanproto != ETHERTYPE_VLAN && in bridge_ioctl_svlanproto()
2277 req->ifbr_vlanproto != ETHERTYPE_QINQ) in bridge_ioctl_svlanproto()
2280 bif->bif_vlanproto = req->ifbr_vlanproto; in bridge_ioctl_svlanproto()
2287 * Detach an interface from a bridge. Called when a member
2293 struct bridge_iflist *bif = ifp->if_bridge; in bridge_ifdetach()
2297 sc = bif->bif_sc; in bridge_ifdetach()
2299 if (ifp->if_flags & IFF_RENAMING) in bridge_ifdetach()
2308 /* Check if the interface is a bridge member */ in bridge_ifdetach()
2320 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) in bridge_ifdetach()
2321 if (ifp == bif->bif_ifp) { in bridge_ifdetach()
2334 * Initialize a bridge interface.
2340 struct ifnet *ifp = sc->sc_ifp; in bridge_init()
2342 if (ifp->if_drv_flags & IFF_DRV_RUNNING) in bridge_init()
2346 callout_reset(&sc->sc_brcallout, bridge_rtable_prune_period * hz, in bridge_init()
2349 ifp->if_drv_flags |= IFF_DRV_RUNNING; in bridge_init()
2350 bstp_init(&sc->sc_stp); /* Initialize Spanning Tree */ in bridge_init()
2358 * Stop the bridge interface.
2363 struct bridge_softc *sc = ifp->if_softc; in bridge_stop()
2367 if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_stop()
2371 callout_stop(&sc->sc_brcallout); in bridge_stop()
2373 bstp_stop(&sc->sc_stp); in bridge_stop()
2378 ifp->if_drv_flags &= ~IFF_DRV_RUNNING; in bridge_stop()
2384 * Enqueue a packet on a bridge member interface.
2396 * Find the bridge member port this packet is being sent on, if the in bridge_enqueue()
2402 /* Perhaps the interface was removed from the bridge */ in bridge_enqueue()
2415 m0 = m->m_nextpkt; in bridge_enqueue()
2416 m->m_nextpkt = NULL; in bridge_enqueue()
2417 len = m->m_pkthdr.len; in bridge_enqueue()
2418 mflags = m->m_flags; in bridge_enqueue()
2424 if (bif->bif_pvid != DOT1Q_VID_NULL && in bridge_enqueue()
2425 VLANTAGOF(m) == bif->bif_pvid) { in bridge_enqueue()
2426 m->m_flags &= ~M_VLANTAG; in bridge_enqueue()
2427 m->m_pkthdr.ether_vtag = 0; in bridge_enqueue()
2435 if ((m->m_flags & M_VLANTAG) && in bridge_enqueue()
2436 ((dst_ifp->if_capenable & IFCAP_VLAN_HWTAGGING) == 0 || in bridge_enqueue()
2437 bif->bif_vlanproto != ETHERTYPE_VLAN)) { in bridge_enqueue()
2438 m = ether_vlanencap_proto(m, m->m_pkthdr.ether_vtag, in bridge_enqueue()
2439 bif->bif_vlanproto); in bridge_enqueue()
2446 m->m_flags &= ~M_VLANTAG; in bridge_enqueue()
2454 if (dst_ifp->if_type == IFT_GIF) in bridge_enqueue()
2455 m->m_pkthdr.csum_data = AF_LINK; in bridge_enqueue()
2456 if ((err = dst_ifp->if_transmit(dst_ifp, m))) { in bridge_enqueue()
2460 m0 = m->m_nextpkt; in bridge_enqueue()
2463 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, n); in bridge_enqueue()
2467 if_inc_counter(sc->sc_ifp, IFCOUNTER_OPACKETS, 1); in bridge_enqueue()
2468 if_inc_counter(sc->sc_ifp, IFCOUNTER_OBYTES, len); in bridge_enqueue()
2470 if_inc_counter(sc->sc_ifp, IFCOUNTER_OMCASTS, 1); in bridge_enqueue()
2487 struct bridge_iflist *bif = ifp->if_bridge; in bridge_dummynet()
2491 sc = bif->bif_sc; in bridge_dummynet()
2504 if (bridge_pfil(&m, sc->sc_ifp, ifp, PFIL_OUT) != 0) in bridge_dummynet()
2516 * Send output from a bridge member interface. This
2535 if (m->m_len < ETHER_HDR_LEN) { in bridge_output()
2541 sbif = ifp->if_bridge; in bridge_output()
2542 sc = sbif->bif_sc; in bridge_output()
2543 bifp = sc->sc_ifp; in bridge_output()
2549 * If bridge is down, but the original output interface is up, in bridge_output()
2553 if ((bifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { in bridge_output()
2562 if (ETHER_IS_MULTICAST(eh->ether_dhost)) in bridge_output()
2565 dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan); in bridge_output()
2576 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_output()
2577 dst_if = bif->bif_ifp; in bridge_output()
2579 if (dst_if->if_type == IFT_GIF) in bridge_output()
2581 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_output()
2590 if (dst_if != ifp && (bif->bif_flags & IFBIF_STP) && in bridge_output()
2591 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) in bridge_output()
2618 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) { in bridge_output()
2630 * Do output on a bridge.
2642 sc = ifp->if_softc; in bridge_transmit()
2649 if (((m->m_flags & (M_BCAST|M_MCAST)) == 0) && in bridge_transmit()
2650 (dst_if = bridge_rtlookup(sc, eh->ether_dhost, vlan)) != NULL) { in bridge_transmit()
2662 struct ifaltq *ifq = &ifp->if_snd; in bridge_altq_start()
2679 if (ALTQ_IS_ENABLED(&ifp->if_snd)) { in bridge_altq_transmit()
2680 IFQ_ENQUEUE(&ifp->if_snd, m, err); in bridge_altq_transmit()
2691 * The ifp->if_qflush entry point for if_bridge(4) is no-op.
2701 * The forwarding function of the bridge.
2718 src_if = m->m_pkthdr.rcvif; in bridge_forward()
2719 ifp = sc->sc_ifp; in bridge_forward()
2723 if_inc_counter(ifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in bridge_forward()
2725 if ((sbif->bif_flags & IFBIF_STP) && in bridge_forward()
2726 sbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) in bridge_forward()
2730 dst = eh->ether_dhost; in bridge_forward()
2733 if (sbif->bif_flags & IFBIF_LEARNING) { in bridge_forward()
2734 error = bridge_rtupdate(sc, eh->ether_shost, vlan, in bridge_forward()
2740 if (error && sbif->bif_addrmax) in bridge_forward()
2744 if ((sbif->bif_flags & IFBIF_STP) != 0 && in bridge_forward()
2745 sbif->bif_stp.bp_state == BSTP_IFSTATE_LEARNING) in bridge_forward()
2753 if ((m->m_flags & M_BRIDGE_INJECT) == 0 && in bridge_forward()
2755 ifp->if_input(ifp, m); in bridge_forward()
2758 m->m_flags &= ~M_BRIDGE_INJECT; in bridge_forward()
2768 * "this" side of the bridge, drop it. in bridge_forward()
2770 if ((m->m_flags & (M_BCAST|M_MCAST)) == 0) { in bridge_forward()
2778 * bridge. in bridge_forward()
2779 * This is currently 01-80-C2-00-00-00 to 01-80-C2-00-00-0F in bridge_forward()
2792 * If we have a destination interface which is a member of our bridge, in bridge_forward()
2798 * firewall issues on the bridge. in bridge_forward()
2800 if (dst_if != NULL || (m->m_flags & (M_BCAST | M_MCAST)) == 0) in bridge_forward()
2820 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_forward()
2825 /* Not a member of the bridge (anymore?) */ in bridge_forward()
2829 if (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE) in bridge_forward()
2832 if ((dbif->bif_flags & IFBIF_STP) && in bridge_forward()
2833 dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) in bridge_forward()
2870 if (m->m_len < ETHER_HDR_LEN) { in bridge_input()
2873 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); in bridge_input()
2885 * This means if vlan(4) and bridge(4) are configured on the same in bridge_input()
2889 if (vlan != DOT1Q_VID_NULL && ifp->if_vlantrunk != NULL) in bridge_input()
2892 bif = ifp->if_bridge; in bridge_input()
2894 sc = bif->bif_sc; in bridge_input()
2898 * This packet originated from the bridge itself, so it must in bridge_input()
2903 KASSERT((m->m_flags & M_BRIDGE_INJECT) != 0, in bridge_input()
2904 ("%s: ifnet %p missing a bridge softc", __func__, ifp)); in bridge_input()
2906 ifp = bridge_rtlookup(sc, eh->ether_shost, vlan); in bridge_input()
2908 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); in bridge_input()
2912 m->m_pkthdr.rcvif = ifp; in bridge_input()
2914 bifp = sc->sc_ifp; in bridge_input()
2915 if ((bifp->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_input()
2919 * Implement support for bridge monitoring. If this flag has been in bridge_input()
2924 if ((bifp->if_flags & IFF_MONITOR) != 0) { in bridge_input()
2925 m->m_pkthdr.rcvif = bifp; in bridge_input()
2928 if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len); in bridge_input()
2935 if_inc_counter(sc->sc_ifp, IFCOUNTER_IERRORS, 1); in bridge_input()
2944 if (m->m_flags & (M_BCAST|M_MCAST)) { in bridge_input()
2946 if (memcmp(eh->ether_dhost, bstp_etheraddr, in bridge_input()
2948 bstp_input(&bif->bif_stp, ifp, m); /* consumes mbuf */ in bridge_input()
2952 if ((bif->bif_flags & IFBIF_STP) && in bridge_input()
2953 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) { in bridge_input()
2959 * for bridge processing; return the original packet for in bridge_input()
2967 /* Perform the bridge forwarding function with the copy. */ in bridge_input()
2976 (m->m_flags & M_BRIDGE_INJECT) == 0) { in bridge_input()
2983 * Reinject the mbuf as arriving on the bridge so we have a in bridge_input()
2985 * here from ether_input as a bridge is never a member of a in bridge_input()
2986 * bridge. in bridge_input()
2988 KASSERT(bifp->if_bridge == NULL, in bridge_input()
2993 int i = min(mc2->m_pkthdr.len, max_protohdr); in bridge_input()
2997 mc2->m_pkthdr.rcvif = bifp; in bridge_input()
2998 mc2->m_flags &= ~M_BRIDGE_INJECT; in bridge_input()
2999 sc->sc_if_input(bifp, mc2); in bridge_input()
3006 if ((bif->bif_flags & IFBIF_STP) && in bridge_input()
3007 bif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) { in bridge_input()
3013 ((iface)->if_carp && (*carp_forus_p)((iface), eh->ether_dhost)) in bridge_input()
3015 ((iface)->if_carp && (*carp_forus_p)((iface), eh->ether_shost)) in bridge_input()
3024 ((m)->m_flags & M_BRIDGE_INJECT) == 0) { \ in bridge_input()
3025 (ifp)->if_input(ifp, m); \ in bridge_input()
3034 if ((iface)->if_type == IFT_GIF) \ in bridge_input()
3037 if (memcmp(IF_LLADDR(iface), eh->ether_dhost, ETHER_ADDR_LEN) == 0 || \ in bridge_input()
3039 if (bif->bif_flags & IFBIF_LEARNING) { \ in bridge_input()
3040 error = bridge_rtupdate(sc, eh->ether_shost, \ in bridge_input()
3042 if (error && bif->bif_addrmax) { \ in bridge_input()
3047 m->m_pkthdr.rcvif = iface; \ in bridge_input()
3049 /* Skip bridge processing... src == dest */ \ in bridge_input()
3052 /* It's passing over or to the bridge, locally. */ \ in bridge_input()
3055 if_inc_counter(bifp, IFCOUNTER_IBYTES, m->m_pkthdr.len);\ in bridge_input()
3069 if (bifp->if_vlantrunk == NULL) { \ in bridge_input()
3080 if (memcmp(IF_LLADDR(iface), eh->ether_shost, ETHER_ADDR_LEN) == 0 || \ in bridge_input()
3087 * Unicast. Make sure it's not for the bridge. in bridge_input()
3099 CK_LIST_FOREACH(bif2, &sc->sc_iflist, bif_next) { in bridge_input()
3100 GRAB_OUR_PACKETS(bif2->bif_ifp) in bridge_input()
3109 /* Perform the bridge forwarding function. */ in bridge_input()
3118 * M_BRIDGE_INJECT flag ensures that the packet is re-routed to the bridge
3126 if (ifp->if_type == IFT_L2VLAN) { in bridge_inject()
3129 * bridge softc to get a pointer to ether_input to send the in bridge_inject()
3146 sc->sc_if_input(ifp, m); in bridge_inject()
3153 KASSERT((m->m_flags & M_BRIDGE_INJECT) == 0, in bridge_inject()
3156 m->m_flags |= M_BRIDGE_INJECT; in bridge_inject()
3158 sc->sc_if_input(ifp, m); in bridge_inject()
3165 * the bridge, except for the one on which the packet
3183 /* Filter on the bridge interface before broadcasting */ in bridge_broadcast()
3185 if (bridge_pfil(&m, sc->sc_ifp, NULL, PFIL_OUT) != 0) in bridge_broadcast()
3191 CK_LIST_FOREACH(dbif, &sc->sc_iflist, bif_next) { in bridge_broadcast()
3192 dst_if = dbif->bif_ifp; in bridge_broadcast()
3197 if (sbif && (sbif->bif_flags & dbif->bif_flags & IFBIF_PRIVATE)) in bridge_broadcast()
3200 if ((dbif->bif_flags & IFBIF_STP) && in bridge_broadcast()
3201 dbif->bif_stp.bp_state == BSTP_IFSTATE_DISCARDING) in bridge_broadcast()
3204 if ((dbif->bif_flags & IFBIF_DISCOVER) == 0 && in bridge_broadcast()
3205 (m->m_flags & (M_BCAST|M_MCAST)) == 0) in bridge_broadcast()
3208 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_broadcast()
3217 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); in bridge_broadcast()
3223 * Filter on the output interface. Pass a NULL bridge interface in bridge_broadcast()
3224 * pointer so we do not redundantly filter on the bridge for in bridge_broadcast()
3230 i = min(mc->m_pkthdr.len, max_protohdr); in bridge_broadcast()
3233 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); in bridge_broadcast()
3264 if (CK_LIST_EMPTY(&sc->sc_spanlist)) in bridge_span()
3267 CK_LIST_FOREACH(bif, &sc->sc_spanlist, bif_next) { in bridge_span()
3268 dst_if = bif->bif_ifp; in bridge_span()
3270 if ((dst_if->if_drv_flags & IFF_DRV_RUNNING) == 0) in bridge_span()
3275 if_inc_counter(sc->sc_ifp, IFCOUNTER_OERRORS, 1); in bridge_span()
3301 if ((sbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0) { in bridge_vfilter_in()
3303 sbif->bif_pvid != DOT1Q_VID_NULL) { in bridge_vfilter_in()
3304 m->m_pkthdr.ether_vtag = sbif->bif_pvid; in bridge_vfilter_in()
3305 m->m_flags |= M_VLANTAG; in bridge_vfilter_in()
3311 /* If Q-in-Q is disabled, check for stacked tags. */ in bridge_vfilter_in()
3312 if ((sbif->bif_flags & IFBIF_QINQ) == 0) { in bridge_vfilter_in()
3317 proto = ntohs(eh->ether_type); in bridge_vfilter_in()
3328 if (sbif->bif_pvid == DOT1Q_VID_NULL) in bridge_vfilter_in()
3335 m->m_pkthdr.ether_vtag = sbif->bif_pvid; in bridge_vfilter_in()
3336 m->m_flags |= M_VLANTAG; in bridge_vfilter_in()
3344 if (!BRVLAN_TEST(&sbif->bif_vlan_set, vlan)) in bridge_vfilter_in()
3370 if (dbif->bif_sc == NULL) in bridge_vfilter_out()
3374 if ((dbif->bif_sc->sc_flags & IFBRF_VLANFILTER) == 0) in bridge_vfilter_out()
3382 * a filtering bridge. in bridge_vfilter_out()
3384 * Tagged STP (Cisco PVST+) is a non-standard extension, so in bridge_vfilter_out()
3389 memcmp(eh->ether_dhost, bstp_etheraddr, ETHER_ADDR_LEN) == 0) in bridge_vfilter_out()
3404 if (vlan == dbif->bif_pvid) in bridge_vfilter_out()
3411 if (BRVLAN_TEST(&dbif->bif_vlan_set, vlan)) in bridge_vfilter_out()
3421 * Add a bridge routing entry.
3455 if (sc->sc_brtcnt >= sc->sc_brtmax) { in bridge_rtupdate()
3456 sc->sc_brtexceeded++; in bridge_rtupdate()
3458 return (EXTERROR(ENOSPC, "Address table is full")); in bridge_rtupdate()
3461 if (bif->bif_addrmax && bif->bif_addrcnt >= bif->bif_addrmax) { in bridge_rtupdate()
3462 bif->bif_addrexceeded++; in bridge_rtupdate()
3469 * Allocate a new bridge forwarding node, and in bridge_rtupdate()
3479 brt->brt_vnet = curvnet; in bridge_rtupdate()
3481 if (bif->bif_flags & IFBIF_STICKY) in bridge_rtupdate()
3482 brt->brt_flags = IFBAF_STICKY; in bridge_rtupdate()
3484 brt->brt_flags = IFBAF_DYNAMIC; in bridge_rtupdate()
3486 memcpy(brt->brt_addr, dst, ETHER_ADDR_LEN); in bridge_rtupdate()
3487 brt->brt_vlan = vlan; in bridge_rtupdate()
3489 brt->brt_dst = bif; in bridge_rtupdate()
3495 bif->bif_addrcnt++; in bridge_rtupdate()
3500 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC && in bridge_rtupdate()
3501 (obif = brt->brt_dst) != bif) { in bridge_rtupdate()
3505 brt->brt_dst->bif_addrcnt--; in bridge_rtupdate()
3506 brt->brt_dst = bif; in bridge_rtupdate()
3507 brt->brt_dst->bif_addrcnt++; in bridge_rtupdate()
3514 sc->sc_ifp->if_xname, in bridge_rtupdate()
3515 &brt->brt_addr[0], ":", in bridge_rtupdate()
3516 brt->brt_vlan, in bridge_rtupdate()
3517 obif->bif_ifp->if_xname, in bridge_rtupdate()
3518 bif->bif_ifp->if_xname); in bridge_rtupdate()
3523 brt->brt_expire = time_uptime + sc->sc_brttimeout; in bridge_rtupdate()
3525 brt->brt_flags = flags; in bridge_rtupdate()
3546 return (brt->brt_ifp); in bridge_rtlookup()
3565 if (sc->sc_brtcnt <= sc->sc_brtmax) in bridge_rttrim()
3570 if (sc->sc_brtcnt <= sc->sc_brtmax) in bridge_rttrim()
3573 CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { in bridge_rttrim()
3574 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { in bridge_rttrim()
3576 if (sc->sc_brtcnt <= sc->sc_brtmax) in bridge_rttrim()
3585 * Aging timer for the bridge.
3595 CURVNET_SET(sc->sc_ifp->if_vnet); in bridge_timer()
3598 if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) in bridge_timer()
3599 callout_reset(&sc->sc_brcallout, in bridge_timer()
3616 CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { in bridge_rtage()
3617 if ((brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) { in bridge_rtage()
3618 if (time_uptime >= brt->brt_expire) in bridge_rtage()
3627 * Remove all dynamic addresses from the bridge.
3630 bridge_rtflush(struct bridge_softc *sc, int full) in bridge_rtflush() argument
3636 CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { in bridge_rtflush()
3637 if (full || (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) in bridge_rtflush()
3676 bridge_rtdelete(struct bridge_softc *sc, struct ifnet *ifp, int full) in bridge_rtdelete() argument
3682 CK_LIST_FOREACH_SAFE(brt, &sc->sc_rtlist, brt_list, nbrt) { in bridge_rtdelete()
3683 if (brt->brt_ifp == ifp && (full || in bridge_rtdelete()
3684 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC)) in bridge_rtdelete()
3692 * Initialize the route table for this bridge.
3699 sc->sc_rthash = malloc(sizeof(*sc->sc_rthash) * BRIDGE_RTHASH_SIZE, in bridge_rtable_init()
3703 CK_LIST_INIT(&sc->sc_rthash[i]); in bridge_rtable_init()
3705 sc->sc_rthash_key = arc4random(); in bridge_rtable_init()
3706 CK_LIST_INIT(&sc->sc_rtlist); in bridge_rtable_init()
3712 * Deconstruct the route table for this bridge.
3718 KASSERT(sc->sc_brtcnt == 0, in bridge_rtable_fini()
3719 ("%s: %d bridge routes referenced", __func__, sc->sc_brtcnt)); in bridge_rtable_fini()
3720 free(sc->sc_rthash, M_DEVBUF); in bridge_rtable_fini()
3729 a -= b; a -= c; a ^= (c >> 13); \
3730 b -= c; b -= a; b ^= (a << 8); \
3731 c -= a; c -= b; c ^= (b >> 13); \
3732 a -= b; a -= c; a ^= (c >> 12); \
3733 b -= c; b -= a; b ^= (a << 16); \
3734 c -= a; c -= b; c ^= (b >> 5); \
3735 a -= b; a -= c; a ^= (c >> 3); \
3736 b -= c; b -= a; b ^= (a << 10); \
3737 c -= a; c -= b; c ^= (b >> 15); \
3743 uint32_t a = 0x9e3779b9, b = 0x9e3779b9, c = sc->sc_rthash_key; in bridge_rthash()
3765 d = ((int)a[i]) - ((int)b[i]); in bridge_rtnode_addr_cmp()
3774 * Look up a bridge route node for the specified destination. Compare the
3788 CK_LIST_FOREACH(brt, &sc->sc_rthash[hash], brt_hash) { in bridge_rtnode_lookup()
3789 dir = bridge_rtnode_addr_cmp(addr, brt->brt_addr); in bridge_rtnode_lookup()
3790 if (dir == 0 && (brt->brt_vlan == vlan || vlan == DOT1Q_VID_RSVD_IMPL)) in bridge_rtnode_lookup()
3802 * Insert the specified bridge node into the route table. We
3814 hash = bridge_rthash(sc, brt->brt_addr); in bridge_rtnode_insert()
3816 lbrt = CK_LIST_FIRST(&sc->sc_rthash[hash]); in bridge_rtnode_insert()
3818 CK_LIST_INSERT_HEAD(&sc->sc_rthash[hash], brt, brt_hash); in bridge_rtnode_insert()
3823 dir = bridge_rtnode_addr_cmp(brt->brt_addr, lbrt->brt_addr); in bridge_rtnode_insert()
3824 if (dir == 0 && brt->brt_vlan == lbrt->brt_vlan) in bridge_rtnode_insert()
3842 CK_LIST_INSERT_HEAD(&sc->sc_rtlist, brt, brt_list); in bridge_rtnode_insert()
3843 sc->sc_brtcnt++; in bridge_rtnode_insert()
3855 CURVNET_SET(brt->brt_vnet); in bridge_rtnode_destroy_cb()
3863 * Destroy a bridge rtnode.
3873 sc->sc_brtcnt--; in bridge_rtnode_destroy()
3874 brt->brt_dst->bif_addrcnt--; in bridge_rtnode_destroy()
3876 NET_EPOCH_CALL(bridge_rtnode_destroy_cb, &brt->brt_epoch_ctx); in bridge_rtnode_destroy()
3891 CURVNET_SET(ifp->if_vnet); in bridge_rtable_expire()
3893 bif = ifp->if_bridge; in bridge_rtable_expire()
3895 sc = bif->bif_sc; in bridge_rtable_expire()
3906 CK_LIST_FOREACH(brt, &sc->sc_rtlist, brt_list) { in bridge_rtable_expire()
3908 if (brt->brt_ifp == ifp && in bridge_rtable_expire()
3909 brt->brt_expire > time_uptime + age && in bridge_rtable_expire()
3910 (brt->brt_flags & IFBAF_TYPEMASK) == IFBAF_DYNAMIC) in bridge_rtable_expire()
3911 brt->brt_expire = time_uptime + age; in bridge_rtable_expire()
3926 struct bridge_iflist *bif = ifp->if_bridge; in bridge_state_change()
3927 struct bridge_softc *sc = bif->bif_sc; in bridge_state_change()
3937 CURVNET_SET(ifp->if_vnet); in bridge_state_change()
3940 sc->sc_ifp->if_xname, stpstates[state], ifp->if_xname); in bridge_state_change()
3945 * Send bridge packets through pfil if they are one of the types pfil can deal
3964 error = -1; /* Default error if not error == 0 */ in bridge_pfil()
3974 i = min((*mp)->m_pkthdr.len, max_protohdr); in bridge_pfil()
3975 if ((*mp)->m_len < i) { in bridge_pfil()
3979 return (-1); in bridge_pfil()
3984 ether_type = ntohs(eh1->ether_type); in bridge_pfil()
3992 if ((*mp)->m_len >= ETHER_HDR_LEN + 8 && in bridge_pfil()
3993 llc2->llc_dsap == LLC_SNAP_LSAP && in bridge_pfil()
3994 llc2->llc_ssap == LLC_SNAP_LSAP && in bridge_pfil()
3995 llc2->llc_control == LLC_UI) { in bridge_pfil()
3996 ether_type = htons(llc2->llc_un.type_snap.ether_type); in bridge_pfil()
4002 * If we're trying to filter bridge traffic, only look at traffic for in bridge_pfil()
4029 * non-IP packets, these will not be checked by pfil(9) in bridge_pfil()
4090 * Run pfil on the member interface and the bridge, both can in bridge_pfil()
4094 * in_if -> bridge_if -> out_if in bridge_pfil()
4118 i = (*mp)->m_pkthdr.len; in bridge_pfil()
4119 if (i > ifp->if_mtu) { in bridge_pfil()
4128 hlen = ip->ip_hl << 2; in bridge_pfil()
4131 if (hlen > (*mp)->m_len) { in bridge_pfil()
4138 ip->ip_sum = 0; in bridge_pfil()
4140 ip->ip_sum = in_cksum_hdr(ip); in bridge_pfil()
4142 ip->ip_sum = in_cksum(*mp, hlen); in bridge_pfil()
4178 error = -1; in bridge_pfil()
4207 * it for it. Cut-and-pasted from ip_input.c.
4225 return (-1); in bridge_ip_checkbasic()
4234 } else if (__predict_false(m->m_len < sizeof (struct ip))) { in bridge_ip_checkbasic()
4243 if (ip->ip_v != IPVERSION) { in bridge_ip_checkbasic()
4247 hlen = ip->ip_hl << 2; in bridge_ip_checkbasic()
4252 if (hlen > m->m_len) { in bridge_ip_checkbasic()
4261 if (m->m_pkthdr.csum_flags & CSUM_IP_CHECKED) { in bridge_ip_checkbasic()
4262 sum = !(m->m_pkthdr.csum_flags & CSUM_IP_VALID); in bridge_ip_checkbasic()
4276 len = ntohs(ip->ip_len); in bridge_ip_checkbasic()
4291 if (m->m_pkthdr.len < len) { in bridge_ip_checkbasic()
4302 return (-1); in bridge_ip_checkbasic()
4309 * Cut-and-pasted from ip6_input.c.
4325 struct ifnet *inifp = m->m_pkthdr.rcvif; in bridge_ip6_checkbasic()
4333 } else if (__predict_false(m->m_len < sizeof(struct ip6_hdr))) { in bridge_ip6_checkbasic()
4334 struct ifnet *inifp = m->m_pkthdr.rcvif; in bridge_ip6_checkbasic()
4344 if ((ip6->ip6_vfc & IPV6_VERSION_MASK) != IPV6_VERSION) { in bridge_ip6_checkbasic()
4346 in6_ifstat_inc(m->m_pkthdr.rcvif, ifs6_in_hdrerr); in bridge_ip6_checkbasic()
4356 return (-1); in bridge_ip6_checkbasic()
4372 int error = -1; in bridge_fragment()
4374 if (m->m_len < sizeof(struct ip) && in bridge_fragment()
4379 m->m_pkthdr.csum_flags |= CSUM_IP; in bridge_fragment()
4380 error = ip_fragment(ip, &m, ifp->if_mtu, ifp->if_hwassist); in bridge_fragment()
4385 * Walk the chain and re-add the Ethernet header for in bridge_fragment()
4388 for (mcur = m; mcur; mcur = mcur->m_nextpkt) { in bridge_fragment()
4389 nextpkt = mcur->m_nextpkt; in bridge_fragment()
4390 mcur->m_nextpkt = NULL; in bridge_fragment()
4396 mprev->m_nextpkt = nextpkt; in bridge_fragment()
4406 mprev->m_nextpkt = nextpkt; in bridge_fragment()
4416 mcur->m_nextpkt = nextpkt; in bridge_fragment()
4418 mprev->m_nextpkt = mcur; in bridge_fragment()
4431 for (mcur = *mp; mcur; mcur = m) { /* droping the full packet chain */ in bridge_fragment()
4432 m = mcur->m_nextpkt; in bridge_fragment()
4448 bif = ifp->if_bridge; in bridge_linkstate()
4450 sc = bif->bif_sc; in bridge_linkstate()
4454 bstp_linkstate(&bif->bif_stp); in bridge_linkstate()
4471 CK_LIST_FOREACH(bif, &sc->sc_iflist, bif_next) { in bridge_linkcheck()
4472 if (bif->bif_ifp->if_capabilities & IFCAP_LINKSTATE) in bridge_linkcheck()
4474 if (bif->bif_ifp->if_link_state == LINK_STATE_UP) { in bridge_linkcheck()
4479 if (!CK_LIST_EMPTY(&sc->sc_iflist) && !hasls) { in bridge_linkcheck()
4480 /* If no interfaces support link-state then we default to up */ in bridge_linkcheck()
4483 if_link_state_change(sc->sc_ifp, new_link); in bridge_linkcheck()