in6.c (1331bbc33fba4b3c6d9e3e1d93b166089b744e74) | in6.c (137f91e80f3802084bd96586d09961a846b91665) |
---|---|
1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 964 unchanged lines hidden (view full) --- 973 ia->ia_ifa.ifa_dstaddr = 974 (struct sockaddr *)&ia->ia_dstaddr; 975 } else { 976 ia->ia_ifa.ifa_dstaddr = NULL; 977 } 978 ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; 979 ia->ia_ifp = ifp; 980 ifa_ref(&ia->ia_ifa); /* if_addrhead */ | 1/*- 2 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project. 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 1. Redistributions of source code must retain the above copyright --- 964 unchanged lines hidden (view full) --- 973 ia->ia_ifa.ifa_dstaddr = 974 (struct sockaddr *)&ia->ia_dstaddr; 975 } else { 976 ia->ia_ifa.ifa_dstaddr = NULL; 977 } 978 ia->ia_ifa.ifa_netmask = (struct sockaddr *)&ia->ia_prefixmask; 979 ia->ia_ifp = ifp; 980 ifa_ref(&ia->ia_ifa); /* if_addrhead */ |
981 IF_ADDR_LOCK(ifp); | 981 IF_ADDR_WLOCK(ifp); |
982 TAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); | 982 TAILQ_INSERT_TAIL(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); |
983 IF_ADDR_UNLOCK(ifp); | 983 IF_ADDR_WUNLOCK(ifp); |
984 985 ifa_ref(&ia->ia_ifa); /* in6_ifaddrhead */ 986 IN6_IFADDR_WLOCK(); 987 TAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link); 988 IN6_IFADDR_WUNLOCK(); 989 } 990 991 /* update timestamp */ --- 338 unchanged lines hidden (view full) --- 1330 if (ifa->ifa_carp) 1331 (*carp_detach_p)(ifa); 1332 1333 /* 1334 * find another IPv6 address as the gateway for the 1335 * link-local and node-local all-nodes multicast 1336 * address routes 1337 */ | 984 985 ifa_ref(&ia->ia_ifa); /* in6_ifaddrhead */ 986 IN6_IFADDR_WLOCK(); 987 TAILQ_INSERT_TAIL(&V_in6_ifaddrhead, ia, ia_link); 988 IN6_IFADDR_WUNLOCK(); 989 } 990 991 /* update timestamp */ --- 338 unchanged lines hidden (view full) --- 1330 if (ifa->ifa_carp) 1331 (*carp_detach_p)(ifa); 1332 1333 /* 1334 * find another IPv6 address as the gateway for the 1335 * link-local and node-local all-nodes multicast 1336 * address routes 1337 */ |
1338 IF_ADDR_LOCK(ifp); | 1338 IF_ADDR_RLOCK(ifp); |
1339 TAILQ_FOREACH(ifa0, &ifp->if_addrhead, ifa_link) { 1340 if ((ifa0->ifa_addr->sa_family != AF_INET6) || 1341 memcmp(&satosin6(ifa0->ifa_addr)->sin6_addr, 1342 &ia->ia_addr.sin6_addr, 1343 sizeof(struct in6_addr)) == 0) 1344 continue; 1345 else 1346 break; 1347 } 1348 if (ifa0 != NULL) 1349 ifa_ref(ifa0); | 1339 TAILQ_FOREACH(ifa0, &ifp->if_addrhead, ifa_link) { 1340 if ((ifa0->ifa_addr->sa_family != AF_INET6) || 1341 memcmp(&satosin6(ifa0->ifa_addr)->sin6_addr, 1342 &ia->ia_addr.sin6_addr, 1343 sizeof(struct in6_addr)) == 0) 1344 continue; 1345 else 1346 break; 1347 } 1348 if (ifa0 != NULL) 1349 ifa_ref(ifa0); |
1350 IF_ADDR_UNLOCK(ifp); | 1350 IF_ADDR_RUNLOCK(ifp); |
1351 1352 /* 1353 * Remove the loopback route to the interface address. 1354 * The check for the current setting of "nd6_useloopback" 1355 * is not needed. 1356 */ 1357 if (ia->ia_flags & IFA_RTSELF) { 1358 error = ifa_del_loopback_route((struct ifaddr *)ia, --- 153 unchanged lines hidden (view full) --- 1512 in6_unlink_ifa(ia, ifp); 1513} 1514 1515static void 1516in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp) 1517{ 1518 int s = splnet(); 1519 | 1351 1352 /* 1353 * Remove the loopback route to the interface address. 1354 * The check for the current setting of "nd6_useloopback" 1355 * is not needed. 1356 */ 1357 if (ia->ia_flags & IFA_RTSELF) { 1358 error = ifa_del_loopback_route((struct ifaddr *)ia, --- 153 unchanged lines hidden (view full) --- 1512 in6_unlink_ifa(ia, ifp); 1513} 1514 1515static void 1516in6_unlink_ifa(struct in6_ifaddr *ia, struct ifnet *ifp) 1517{ 1518 int s = splnet(); 1519 |
1520 IF_ADDR_LOCK(ifp); | 1520 IF_ADDR_WLOCK(ifp); |
1521 TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); | 1521 TAILQ_REMOVE(&ifp->if_addrhead, &ia->ia_ifa, ifa_link); |
1522 IF_ADDR_UNLOCK(ifp); | 1522 IF_ADDR_WUNLOCK(ifp); |
1523 ifa_free(&ia->ia_ifa); /* if_addrhead */ 1524 1525 /* 1526 * Defer the release of what might be the last reference to the 1527 * in6_ifaddr so that it can't be freed before the remainder of the 1528 * cleanup. 1529 */ 1530 IN6_IFADDR_WLOCK(); --- 210 unchanged lines hidden (view full) --- 1741 in6_prefixlen2mask(&mask, 128); 1742 sin6 = (struct sockaddr_in6 *)&iflr->addr; 1743 bcopy(&sin6->sin6_addr, &match, sizeof(match)); 1744 1745 cmp = 1; 1746 } 1747 } 1748 | 1523 ifa_free(&ia->ia_ifa); /* if_addrhead */ 1524 1525 /* 1526 * Defer the release of what might be the last reference to the 1527 * in6_ifaddr so that it can't be freed before the remainder of the 1528 * cleanup. 1529 */ 1530 IN6_IFADDR_WLOCK(); --- 210 unchanged lines hidden (view full) --- 1741 in6_prefixlen2mask(&mask, 128); 1742 sin6 = (struct sockaddr_in6 *)&iflr->addr; 1743 bcopy(&sin6->sin6_addr, &match, sizeof(match)); 1744 1745 cmp = 1; 1746 } 1747 } 1748 |
1749 IF_ADDR_LOCK(ifp); | 1749 IF_ADDR_RLOCK(ifp); |
1750 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1751 if (ifa->ifa_addr->sa_family != AF_INET6) 1752 continue; 1753 if (!cmp) 1754 break; 1755 1756 /* 1757 * XXX: this is adhoc, but is necessary to allow --- 6 unchanged lines hidden (view full) --- 1764 candidate.s6_addr32[1] &= mask.s6_addr32[1]; 1765 candidate.s6_addr32[2] &= mask.s6_addr32[2]; 1766 candidate.s6_addr32[3] &= mask.s6_addr32[3]; 1767 if (IN6_ARE_ADDR_EQUAL(&candidate, &match)) 1768 break; 1769 } 1770 if (ifa != NULL) 1771 ifa_ref(ifa); | 1750 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1751 if (ifa->ifa_addr->sa_family != AF_INET6) 1752 continue; 1753 if (!cmp) 1754 break; 1755 1756 /* 1757 * XXX: this is adhoc, but is necessary to allow --- 6 unchanged lines hidden (view full) --- 1764 candidate.s6_addr32[1] &= mask.s6_addr32[1]; 1765 candidate.s6_addr32[2] &= mask.s6_addr32[2]; 1766 candidate.s6_addr32[3] &= mask.s6_addr32[3]; 1767 if (IN6_ARE_ADDR_EQUAL(&candidate, &match)) 1768 break; 1769 } 1770 if (ifa != NULL) 1771 ifa_ref(ifa); |
1772 IF_ADDR_UNLOCK(ifp); | 1772 IF_ADDR_RUNLOCK(ifp); |
1773 if (!ifa) 1774 return EADDRNOTAVAIL; 1775 ia = ifa2ia6(ifa); 1776 1777 if (cmd == SIOCGLIFADDR) { 1778 int error; 1779 1780 /* fill in the if_laddrreq structure */ --- 67 unchanged lines hidden (view full) --- 1848 int s = splimp(); 1849 struct ifaddr *ifa; 1850 1851 /* 1852 * Give the interface a chance to initialize 1853 * if this is its first address, 1854 * and to validate the address if necessary. 1855 */ | 1773 if (!ifa) 1774 return EADDRNOTAVAIL; 1775 ia = ifa2ia6(ifa); 1776 1777 if (cmd == SIOCGLIFADDR) { 1778 int error; 1779 1780 /* fill in the if_laddrreq structure */ --- 67 unchanged lines hidden (view full) --- 1848 int s = splimp(); 1849 struct ifaddr *ifa; 1850 1851 /* 1852 * Give the interface a chance to initialize 1853 * if this is its first address, 1854 * and to validate the address if necessary. 1855 */ |
1856 IF_ADDR_LOCK(ifp); | 1856 IF_ADDR_RLOCK(ifp); |
1857 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1858 if (ifa->ifa_addr->sa_family != AF_INET6) 1859 continue; 1860 ifacount++; 1861 } | 1857 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1858 if (ifa->ifa_addr->sa_family != AF_INET6) 1859 continue; 1860 ifacount++; 1861 } |
1862 IF_ADDR_UNLOCK(ifp); | 1862 IF_ADDR_RUNLOCK(ifp); |
1863 1864 ia->ia_addr = *sin6; 1865 1866 if (ifacount <= 1 && ifp->if_ioctl) { 1867 error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia); 1868 if (error) { 1869 splx(s); 1870 return (error); --- 54 unchanged lines hidden (view full) --- 1925 * Find an IPv6 interface link-local address specific to an interface. 1926 * ifaddr is returned referenced. 1927 */ 1928struct in6_ifaddr * 1929in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags) 1930{ 1931 struct ifaddr *ifa; 1932 | 1863 1864 ia->ia_addr = *sin6; 1865 1866 if (ifacount <= 1 && ifp->if_ioctl) { 1867 error = (*ifp->if_ioctl)(ifp, SIOCSIFADDR, (caddr_t)ia); 1868 if (error) { 1869 splx(s); 1870 return (error); --- 54 unchanged lines hidden (view full) --- 1925 * Find an IPv6 interface link-local address specific to an interface. 1926 * ifaddr is returned referenced. 1927 */ 1928struct in6_ifaddr * 1929in6ifa_ifpforlinklocal(struct ifnet *ifp, int ignoreflags) 1930{ 1931 struct ifaddr *ifa; 1932 |
1933 IF_ADDR_LOCK(ifp); | 1933 IF_ADDR_RLOCK(ifp); |
1934 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1935 if (ifa->ifa_addr->sa_family != AF_INET6) 1936 continue; 1937 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) { 1938 if ((((struct in6_ifaddr *)ifa)->ia6_flags & 1939 ignoreflags) != 0) 1940 continue; 1941 ifa_ref(ifa); 1942 break; 1943 } 1944 } | 1934 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1935 if (ifa->ifa_addr->sa_family != AF_INET6) 1936 continue; 1937 if (IN6_IS_ADDR_LINKLOCAL(IFA_IN6(ifa))) { 1938 if ((((struct in6_ifaddr *)ifa)->ia6_flags & 1939 ignoreflags) != 0) 1940 continue; 1941 ifa_ref(ifa); 1942 break; 1943 } 1944 } |
1945 IF_ADDR_UNLOCK(ifp); | 1945 IF_ADDR_RUNLOCK(ifp); |
1946 1947 return ((struct in6_ifaddr *)ifa); 1948} 1949 1950 1951/* 1952 * find the internet address corresponding to a given interface and address. 1953 * ifaddr is returned referenced. 1954 */ 1955struct in6_ifaddr * 1956in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr) 1957{ 1958 struct ifaddr *ifa; 1959 | 1946 1947 return ((struct in6_ifaddr *)ifa); 1948} 1949 1950 1951/* 1952 * find the internet address corresponding to a given interface and address. 1953 * ifaddr is returned referenced. 1954 */ 1955struct in6_ifaddr * 1956in6ifa_ifpwithaddr(struct ifnet *ifp, struct in6_addr *addr) 1957{ 1958 struct ifaddr *ifa; 1959 |
1960 IF_ADDR_LOCK(ifp); | 1960 IF_ADDR_RLOCK(ifp); |
1961 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1962 if (ifa->ifa_addr->sa_family != AF_INET6) 1963 continue; 1964 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) { 1965 ifa_ref(ifa); 1966 break; 1967 } 1968 } | 1961 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 1962 if (ifa->ifa_addr->sa_family != AF_INET6) 1963 continue; 1964 if (IN6_ARE_ADDR_EQUAL(addr, IFA_IN6(ifa))) { 1965 ifa_ref(ifa); 1966 break; 1967 } 1968 } |
1969 IF_ADDR_UNLOCK(ifp); | 1969 IF_ADDR_RUNLOCK(ifp); |
1970 1971 return ((struct in6_ifaddr *)ifa); 1972} 1973 1974/* 1975 * Convert IP6 address to printable (loggable) representation. Caller 1976 * has to make sure that ip6buf is at least INET6_ADDRSTRLEN long. 1977 */ --- 224 unchanged lines hidden (view full) --- 2202 dep[0] = dep[1] = NULL; 2203 2204 /* 2205 * We first look for addresses in the same scope. 2206 * If there is one, return it. 2207 * If two or more, return one which matches the dst longest. 2208 * If none, return one of global addresses assigned other ifs. 2209 */ | 1970 1971 return ((struct in6_ifaddr *)ifa); 1972} 1973 1974/* 1975 * Convert IP6 address to printable (loggable) representation. Caller 1976 * has to make sure that ip6buf is at least INET6_ADDRSTRLEN long. 1977 */ --- 224 unchanged lines hidden (view full) --- 2202 dep[0] = dep[1] = NULL; 2203 2204 /* 2205 * We first look for addresses in the same scope. 2206 * If there is one, return it. 2207 * If two or more, return one which matches the dst longest. 2208 * If none, return one of global addresses assigned other ifs. 2209 */ |
2210 IF_ADDR_LOCK(ifp); | 2210 IF_ADDR_RLOCK(ifp); |
2211 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2212 if (ifa->ifa_addr->sa_family != AF_INET6) 2213 continue; 2214 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 2215 continue; /* XXX: is there any case to allow anycast? */ 2216 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) 2217 continue; /* don't use this interface */ 2218 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED) --- 17 unchanged lines hidden (view full) --- 2236 besta = (struct in6_ifaddr *)ifa; 2237 } 2238 } else 2239 besta = (struct in6_ifaddr *)ifa; 2240 } 2241 } 2242 if (besta) { 2243 ifa_ref(&besta->ia_ifa); | 2211 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2212 if (ifa->ifa_addr->sa_family != AF_INET6) 2213 continue; 2214 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 2215 continue; /* XXX: is there any case to allow anycast? */ 2216 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_NOTREADY) 2217 continue; /* don't use this interface */ 2218 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DETACHED) --- 17 unchanged lines hidden (view full) --- 2236 besta = (struct in6_ifaddr *)ifa; 2237 } 2238 } else 2239 besta = (struct in6_ifaddr *)ifa; 2240 } 2241 } 2242 if (besta) { 2243 ifa_ref(&besta->ia_ifa); |
2244 IF_ADDR_UNLOCK(ifp); | 2244 IF_ADDR_RUNLOCK(ifp); |
2245 return (besta); 2246 } 2247 2248 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2249 if (ifa->ifa_addr->sa_family != AF_INET6) 2250 continue; 2251 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 2252 continue; /* XXX: is there any case to allow anycast? */ --- 4 unchanged lines hidden (view full) --- 2257 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) { 2258 if (V_ip6_use_deprecated) 2259 dep[1] = (struct in6_ifaddr *)ifa; 2260 continue; 2261 } 2262 2263 if (ifa != NULL) 2264 ifa_ref(ifa); | 2245 return (besta); 2246 } 2247 2248 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2249 if (ifa->ifa_addr->sa_family != AF_INET6) 2250 continue; 2251 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_ANYCAST) 2252 continue; /* XXX: is there any case to allow anycast? */ --- 4 unchanged lines hidden (view full) --- 2257 if (((struct in6_ifaddr *)ifa)->ia6_flags & IN6_IFF_DEPRECATED) { 2258 if (V_ip6_use_deprecated) 2259 dep[1] = (struct in6_ifaddr *)ifa; 2260 continue; 2261 } 2262 2263 if (ifa != NULL) 2264 ifa_ref(ifa); |
2265 IF_ADDR_UNLOCK(ifp); | 2265 IF_ADDR_RUNLOCK(ifp); |
2266 return (struct in6_ifaddr *)ifa; 2267 } | 2266 return (struct in6_ifaddr *)ifa; 2267 } |
2268 IF_ADDR_UNLOCK(ifp); | 2268 IF_ADDR_RUNLOCK(ifp); |
2269 2270 /* use the last-resort values, that are, deprecated addresses */ 2271 if (dep[0]) 2272 return dep[0]; 2273 if (dep[1]) 2274 return dep[1]; 2275 2276 return NULL; 2277} 2278 2279/* 2280 * perform DAD when interface becomes IFF_UP. 2281 */ 2282void 2283in6_if_up(struct ifnet *ifp) 2284{ 2285 struct ifaddr *ifa; 2286 struct in6_ifaddr *ia; 2287 | 2269 2270 /* use the last-resort values, that are, deprecated addresses */ 2271 if (dep[0]) 2272 return dep[0]; 2273 if (dep[1]) 2274 return dep[1]; 2275 2276 return NULL; 2277} 2278 2279/* 2280 * perform DAD when interface becomes IFF_UP. 2281 */ 2282void 2283in6_if_up(struct ifnet *ifp) 2284{ 2285 struct ifaddr *ifa; 2286 struct in6_ifaddr *ia; 2287 |
2288 IF_ADDR_LOCK(ifp); | 2288 IF_ADDR_RLOCK(ifp); |
2289 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2290 if (ifa->ifa_addr->sa_family != AF_INET6) 2291 continue; 2292 ia = (struct in6_ifaddr *)ifa; 2293 if (ia->ia6_flags & IN6_IFF_TENTATIVE) { 2294 /* 2295 * The TENTATIVE flag was likely set by hand 2296 * beforehand, implicitly indicating the need for DAD. 2297 * We may be able to skip the random delay in this 2298 * case, but we impose delays just in case. 2299 */ 2300 nd6_dad_start(ifa, 2301 arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz)); 2302 } 2303 } | 2289 TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { 2290 if (ifa->ifa_addr->sa_family != AF_INET6) 2291 continue; 2292 ia = (struct in6_ifaddr *)ifa; 2293 if (ia->ia6_flags & IN6_IFF_TENTATIVE) { 2294 /* 2295 * The TENTATIVE flag was likely set by hand 2296 * beforehand, implicitly indicating the need for DAD. 2297 * We may be able to skip the random delay in this 2298 * case, but we impose delays just in case. 2299 */ 2300 nd6_dad_start(ifa, 2301 arc4random() % (MAX_RTR_SOLICITATION_DELAY * hz)); 2302 } 2303 } |
2304 IF_ADDR_UNLOCK(ifp); | 2304 IF_ADDR_RUNLOCK(ifp); |
2305 2306 /* 2307 * special cases, like 6to4, are handled in in6_ifattach 2308 */ 2309 in6_ifattach(ifp, NULL); 2310} 2311 2312int --- 485 unchanged lines hidden --- | 2305 2306 /* 2307 * special cases, like 6to4, are handled in in6_ifattach 2308 */ 2309 in6_ifattach(ifp, NULL); 2310} 2311 2312int --- 485 unchanged lines hidden --- |