| 1898 | } |
| 1899 | |
| 1900 | int |
| 1901 | carp_attach(struct ifaddr *ifa, int vhid) |
| 1902 | { |
| 1903 | struct ifnet *ifp = ifa->ifa_ifp; |
| 1904 | struct carp_if *cif = ifp->if_carp; |
| 1905 | struct carp_softc *sc; |
| 1906 | int index, error; |
| 1907 | |
| 1908 | KASSERT(ifa->ifa_carp == NULL, ("%s: ifa %p attached", __func__, ifa)); |
| 1909 | |
| 1910 | switch (ifa->ifa_addr->sa_family) { |
| 1911 | #ifdef INET |
| 1912 | case AF_INET: |
| 1913 | #endif |
| 1914 | #ifdef INET6 |
| 1915 | case AF_INET6: |
| 1916 | #endif |
| 1917 | break; |
| 1918 | default: |
| 1919 | return (EPROTOTYPE); |
| 1920 | } |
| 1921 | |
| 1922 | sx_xlock(&carp_sx); |
| 1923 | if (ifp->if_carp == NULL) { |
| 1924 | sx_xunlock(&carp_sx); |
| 1925 | return (ENOPROTOOPT); |
| 1926 | } |
| 1927 | |
| 1928 | IFNET_FOREACH_CARP(ifp, sc) |
| 1929 | if (sc->sc_vhid == vhid) |
| 1930 | break; |
| 1931 | if (sc == NULL) { |
| 1932 | sx_xunlock(&carp_sx); |
| 1933 | return (ENOENT); |
| 1934 | } |
| 1935 | |
| 1936 | error = carp_multicast_setup(cif, ifa->ifa_addr->sa_family); |
| 1937 | if (error) { |
| 1938 | CIF_FREE(cif); |
| 1939 | sx_xunlock(&carp_sx); |
| 1940 | return (error); |
| 1941 | } |
| 1942 | |
| 1943 | index = sc->sc_naddrs + sc->sc_naddrs6 + 1; |
| 1944 | if (index > sc->sc_ifasiz / sizeof(struct ifaddr *)) |
| 1945 | carp_grow_ifas(sc); |
| 1946 | |
| 1947 | switch (ifa->ifa_addr->sa_family) { |
| 1948 | #ifdef INET |
| 1949 | case AF_INET: |
| 1950 | cif->cif_naddrs++; |
| 1951 | sc->sc_naddrs++; |
| 1952 | break; |
| 1953 | #endif |
| 1954 | #ifdef INET6 |
| 1955 | case AF_INET6: |
| 1956 | cif->cif_naddrs6++; |
| 1957 | sc->sc_naddrs6++; |
nothing calls this directly
no test coverage detected