| 921 | } |
| 922 | |
| 923 | static int |
| 924 | lagg_port_destroy(struct lagg_port *lp, int rundelport) |
| 925 | { |
| 926 | struct lagg_softc *sc = lp->lp_softc; |
| 927 | struct lagg_port *lp_ptr, *lp0; |
| 928 | struct ifnet *ifp = lp->lp_ifp; |
| 929 | uint64_t *pval, vdiff; |
| 930 | int i; |
| 931 | |
| 932 | LAGG_XLOCK_ASSERT(sc); |
| 933 | |
| 934 | if (rundelport) |
| 935 | lagg_proto_delport(sc, lp); |
| 936 | |
| 937 | if (lp->lp_detaching == 0) |
| 938 | lagg_clrmulti(lp); |
| 939 | |
| 940 | /* Restore interface */ |
| 941 | ifp->if_type = lp->lp_iftype; |
| 942 | ifp->if_ioctl = lp->lp_ioctl; |
| 943 | ifp->if_output = lp->lp_output; |
| 944 | ifp->if_lagg = NULL; |
| 945 | |
| 946 | /* Update detached port counters */ |
| 947 | pval = lp->port_counters.val; |
| 948 | for (i = 0; i < IFCOUNTERS; i++, pval++) { |
| 949 | vdiff = ifp->if_get_counter(ifp, i) - *pval; |
| 950 | sc->detached_counters.val[i] += vdiff; |
| 951 | } |
| 952 | |
| 953 | /* Finally, remove the port from the lagg */ |
| 954 | CK_SLIST_REMOVE(&sc->sc_ports, lp, lagg_port, lp_entries); |
| 955 | sc->sc_count--; |
| 956 | |
| 957 | /* Update the primary interface */ |
| 958 | if (lp == sc->sc_primary) { |
| 959 | uint8_t lladdr[LAGG_ADDR_LEN]; |
| 960 | |
| 961 | if ((lp0 = CK_SLIST_FIRST(&sc->sc_ports)) == NULL) |
| 962 | bzero(&lladdr, LAGG_ADDR_LEN); |
| 963 | else |
| 964 | bcopy(lp0->lp_lladdr, lladdr, LAGG_ADDR_LEN); |
| 965 | sc->sc_primary = lp0; |
| 966 | if (sc->sc_destroying == 0) { |
| 967 | bcopy(lladdr, IF_LLADDR(sc->sc_ifp), sc->sc_ifp->if_addrlen); |
| 968 | lagg_proto_lladdr(sc); |
| 969 | EVENTHANDLER_INVOKE(iflladdr_event, sc->sc_ifp); |
| 970 | } |
| 971 | |
| 972 | /* |
| 973 | * Update lladdr for each port (new primary needs update |
| 974 | * as well, to switch from old lladdr to its 'real' one) |
| 975 | */ |
| 976 | CK_SLIST_FOREACH(lp_ptr, &sc->sc_ports, lp_entries) |
| 977 | if_setlladdr(lp_ptr->lp_ifp, lladdr, lp_ptr->lp_ifp->if_addrlen); |
| 978 | } |
| 979 | |
| 980 | if (lp->lp_ifflags) |
no test coverage detected