* Check if each prefix in the prefix list has at least one available router * that advertised the prefix (a router is "available" if its neighbor cache * entry is reachable or probably reachable). * If the check fails, the prefix may be off-link, because, for example, * we have moved from the network but the lifetime of the prefix has not * expired yet. So we should not use the prefix if the
| 1840 | * is no router around us. |
| 1841 | */ |
| 1842 | void |
| 1843 | pfxlist_onlink_check(void) |
| 1844 | { |
| 1845 | struct nd_prefix *pr; |
| 1846 | struct in6_ifaddr *ifa; |
| 1847 | struct nd_defrouter *dr; |
| 1848 | struct nd_pfxrouter *pfxrtr = NULL; |
| 1849 | struct rm_priotracker in6_ifa_tracker; |
| 1850 | uint64_t genid; |
| 1851 | uint32_t flags; |
| 1852 | |
| 1853 | ND6_ONLINK_LOCK(); |
| 1854 | ND6_RLOCK(); |
| 1855 | |
| 1856 | /* |
| 1857 | * Check if there is a prefix that has a reachable advertising |
| 1858 | * router. |
| 1859 | */ |
| 1860 | LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) { |
| 1861 | if (pr->ndpr_raf_onlink && find_pfxlist_reachable_router(pr)) |
| 1862 | break; |
| 1863 | } |
| 1864 | |
| 1865 | /* |
| 1866 | * If we have no such prefix, check whether we still have a router |
| 1867 | * that does not advertise any prefixes. |
| 1868 | */ |
| 1869 | if (pr == NULL) { |
| 1870 | TAILQ_FOREACH(dr, &V_nd6_defrouter, dr_entry) { |
| 1871 | struct nd_prefix *pr0; |
| 1872 | |
| 1873 | LIST_FOREACH(pr0, &V_nd_prefix, ndpr_entry) { |
| 1874 | if ((pfxrtr = pfxrtr_lookup(pr0, dr)) != NULL) |
| 1875 | break; |
| 1876 | } |
| 1877 | if (pfxrtr != NULL) |
| 1878 | break; |
| 1879 | } |
| 1880 | } |
| 1881 | if (pr != NULL || (!TAILQ_EMPTY(&V_nd6_defrouter) && pfxrtr == NULL)) { |
| 1882 | /* |
| 1883 | * There is at least one prefix that has a reachable router, |
| 1884 | * or at least a router which probably does not advertise |
| 1885 | * any prefixes. The latter would be the case when we move |
| 1886 | * to a new link where we have a router that does not provide |
| 1887 | * prefixes and we configure an address by hand. |
| 1888 | * Detach prefixes which have no reachable advertising |
| 1889 | * router, and attach other prefixes. |
| 1890 | */ |
| 1891 | LIST_FOREACH(pr, &V_nd_prefix, ndpr_entry) { |
| 1892 | /* XXX: a link-local prefix should never be detached */ |
| 1893 | if (IN6_IS_ADDR_LINKLOCAL(&pr->ndpr_prefix.sin6_addr) || |
| 1894 | pr->ndpr_raf_onlink == 0 || |
| 1895 | pr->ndpr_raf_auto == 0) |
| 1896 | continue; |
| 1897 | |
| 1898 | if ((pr->ndpr_stateflags & NDPRF_DETACHED) == 0 && |
| 1899 | find_pfxlist_reachable_router(pr) == NULL) |
no test coverage detected