* bridge_delete_member: * * Delete the specified member interface. */
| 1043 | * Delete the specified member interface. |
| 1044 | */ |
| 1045 | static void |
| 1046 | bridge_delete_member(struct bridge_softc *sc, struct bridge_iflist *bif, |
| 1047 | int gone) |
| 1048 | { |
| 1049 | struct ifnet *ifs = bif->bif_ifp; |
| 1050 | struct ifnet *fif = NULL; |
| 1051 | struct bridge_iflist *bifl; |
| 1052 | |
| 1053 | BRIDGE_LOCK_ASSERT(sc); |
| 1054 | |
| 1055 | if (bif->bif_flags & IFBIF_STP) |
| 1056 | bstp_disable(&bif->bif_stp); |
| 1057 | |
| 1058 | ifs->if_bridge = NULL; |
| 1059 | CK_LIST_REMOVE(bif, bif_next); |
| 1060 | |
| 1061 | /* |
| 1062 | * If removing the interface that gave the bridge its mac address, set |
| 1063 | * the mac address of the bridge to the address of the next member, or |
| 1064 | * to its default address if no members are left. |
| 1065 | */ |
| 1066 | if (V_bridge_inherit_mac && sc->sc_ifaddr == ifs) { |
| 1067 | if (CK_LIST_EMPTY(&sc->sc_iflist)) { |
| 1068 | bcopy(&sc->sc_defaddr, |
| 1069 | IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); |
| 1070 | sc->sc_ifaddr = NULL; |
| 1071 | } else { |
| 1072 | bifl = CK_LIST_FIRST(&sc->sc_iflist); |
| 1073 | fif = bifl->bif_ifp; |
| 1074 | bcopy(IF_LLADDR(fif), |
| 1075 | IF_LLADDR(sc->sc_ifp), ETHER_ADDR_LEN); |
| 1076 | sc->sc_ifaddr = fif; |
| 1077 | } |
| 1078 | EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); |
| 1079 | } |
| 1080 | |
| 1081 | bridge_linkcheck(sc); |
| 1082 | bridge_mutecaps(sc); /* recalcuate now this interface is removed */ |
| 1083 | BRIDGE_RT_LOCK(sc); |
| 1084 | bridge_rtdelete(sc, ifs, IFBF_FLUSHALL); |
| 1085 | BRIDGE_RT_UNLOCK(sc); |
| 1086 | KASSERT(bif->bif_addrcnt == 0, |
| 1087 | ("%s: %d bridge routes referenced", __func__, bif->bif_addrcnt)); |
| 1088 | |
| 1089 | ifs->if_bridge_output = NULL; |
| 1090 | ifs->if_bridge_input = NULL; |
| 1091 | ifs->if_bridge_linkstate = NULL; |
| 1092 | if (!gone) { |
| 1093 | switch (ifs->if_type) { |
| 1094 | case IFT_ETHER: |
| 1095 | case IFT_L2VLAN: |
| 1096 | /* |
| 1097 | * Take the interface out of promiscuous mode, but only |
| 1098 | * if it was promiscuous in the first place. It might |
| 1099 | * not be if we're in the bridge_ioctl_add() error path. |
| 1100 | */ |
| 1101 | if (ifs->if_flags & IFF_PROMISC) |
| 1102 | (void) ifpromisc(ifs, 0); |
no test coverage detected