| 1974 | } |
| 1975 | |
| 1976 | void |
| 1977 | carp_detach(struct ifaddr *ifa, bool keep_cif) |
| 1978 | { |
| 1979 | struct ifnet *ifp = ifa->ifa_ifp; |
| 1980 | struct carp_if *cif = ifp->if_carp; |
| 1981 | struct carp_softc *sc = ifa->ifa_carp; |
| 1982 | int i, index; |
| 1983 | |
| 1984 | KASSERT(sc != NULL, ("%s: %p not attached", __func__, ifa)); |
| 1985 | |
| 1986 | sx_xlock(&carp_sx); |
| 1987 | |
| 1988 | CARP_LOCK(sc); |
| 1989 | /* Shift array. */ |
| 1990 | index = sc->sc_naddrs + sc->sc_naddrs6; |
| 1991 | for (i = 0; i < index; i++) |
| 1992 | if (sc->sc_ifas[i] == ifa) |
| 1993 | break; |
| 1994 | KASSERT(i < index, ("%s: %p no backref", __func__, ifa)); |
| 1995 | for (; i < index - 1; i++) |
| 1996 | sc->sc_ifas[i] = sc->sc_ifas[i+1]; |
| 1997 | sc->sc_ifas[index - 1] = NULL; |
| 1998 | |
| 1999 | switch (ifa->ifa_addr->sa_family) { |
| 2000 | #ifdef INET |
| 2001 | case AF_INET: |
| 2002 | cif->cif_naddrs--; |
| 2003 | sc->sc_naddrs--; |
| 2004 | break; |
| 2005 | #endif |
| 2006 | #ifdef INET6 |
| 2007 | case AF_INET6: |
| 2008 | cif->cif_naddrs6--; |
| 2009 | sc->sc_naddrs6--; |
| 2010 | break; |
| 2011 | #endif |
| 2012 | } |
| 2013 | |
| 2014 | carp_ifa_delroute(ifa); |
| 2015 | carp_multicast_cleanup(cif, ifa->ifa_addr->sa_family); |
| 2016 | |
| 2017 | ifa->ifa_carp = NULL; |
| 2018 | ifa_free(ifa); |
| 2019 | |
| 2020 | carp_hmac_prepare(sc); |
| 2021 | carp_sc_state(sc); |
| 2022 | |
| 2023 | if (!keep_cif && sc->sc_naddrs == 0 && sc->sc_naddrs6 == 0) |
| 2024 | carp_destroy(sc); |
| 2025 | else |
| 2026 | CARP_UNLOCK(sc); |
| 2027 | |
| 2028 | if (!keep_cif) |
| 2029 | CIF_FREE(cif); |
| 2030 | |
| 2031 | sx_xunlock(&carp_sx); |
| 2032 | } |
| 2033 |
nothing calls this directly
no test coverage detected