|
Lines 500-506
defrouter_addreq(struct nd_defrouter *new)
Link Here
|
| 500 |
|
500 |
|
| 501 |
error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def, |
501 |
error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def, |
| 502 |
(struct sockaddr *)&gate, (struct sockaddr *)&mask, |
502 |
(struct sockaddr *)&gate, (struct sockaddr *)&mask, |
| 503 |
RTF_GATEWAY, &newrt, RT_DEFAULT_FIB); |
503 |
RTF_GATEWAY, &newrt, new->ifp->if_fib); |
| 504 |
if (newrt) { |
504 |
if (newrt) { |
| 505 |
nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ |
505 |
nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ |
| 506 |
RTFREE(newrt); |
506 |
RTFREE(newrt); |
|
Lines 571-577
defrouter_delreq(struct nd_defrouter *dr)
Link Here
|
| 571 |
|
571 |
|
| 572 |
in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def, |
572 |
in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def, |
| 573 |
(struct sockaddr *)&gate, |
573 |
(struct sockaddr *)&gate, |
| 574 |
(struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, RT_DEFAULT_FIB); |
574 |
(struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, dr->ifp->if_fib); |
| 575 |
if (oldrt) { |
575 |
if (oldrt) { |
| 576 |
nd6_rtmsg(RTM_DELETE, oldrt); |
576 |
nd6_rtmsg(RTM_DELETE, oldrt); |
| 577 |
RTFREE(oldrt); |
577 |
RTFREE(oldrt); |
|
Lines 702-708
defrouter_del(struct nd_defrouter *dr)
Link Here
|
| 702 |
* from the routing table. |
702 |
* from the routing table. |
| 703 |
*/ |
703 |
*/ |
| 704 |
if (deldr) |
704 |
if (deldr) |
| 705 |
defrouter_select(); |
705 |
defrouter_select(deldr->ifp->if_fib); |
| 706 |
|
706 |
|
| 707 |
/* |
707 |
/* |
| 708 |
* Release the list reference. |
708 |
* Release the list reference. |
|
Lines 732-738
defrouter_del(struct nd_defrouter *dr)
Link Here
|
| 732 |
* complicated and the possibility of introducing bugs. |
732 |
* complicated and the possibility of introducing bugs. |
| 733 |
*/ |
733 |
*/ |
| 734 |
void |
734 |
void |
| 735 |
defrouter_select(void) |
735 |
defrouter_select(int fibnum) |
| 736 |
{ |
736 |
{ |
| 737 |
struct nd_defrouter *dr, *selected_dr, *installed_dr; |
737 |
struct nd_defrouter *dr, *selected_dr, *installed_dr; |
| 738 |
struct llentry *ln = NULL; |
738 |
struct llentry *ln = NULL; |
|
Lines 755-761
defrouter_select(void)
Link Here
|
| 755 |
selected_dr = installed_dr = NULL; |
755 |
selected_dr = installed_dr = NULL; |
| 756 |
TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) { |
756 |
TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) { |
| 757 |
IF_AFDATA_RLOCK(dr->ifp); |
757 |
IF_AFDATA_RLOCK(dr->ifp); |
| 758 |
if (selected_dr == NULL && |
758 |
if (selected_dr == NULL && dr->ifp->if_fib == fibnum && |
| 759 |
(ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) && |
759 |
(ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) && |
| 760 |
ND6_IS_LLINFO_PROBREACH(ln)) { |
760 |
ND6_IS_LLINFO_PROBREACH(ln)) { |
| 761 |
selected_dr = dr; |
761 |
selected_dr = dr; |
|
Lines 767-773
defrouter_select(void)
Link Here
|
| 767 |
ln = NULL; |
767 |
ln = NULL; |
| 768 |
} |
768 |
} |
| 769 |
|
769 |
|
| 770 |
if (dr->installed) { |
770 |
if (dr->installed && dr->ifp->if_fib == fibnum) { |
| 771 |
if (installed_dr == NULL) { |
771 |
if (installed_dr == NULL) { |
| 772 |
installed_dr = dr; |
772 |
installed_dr = dr; |
| 773 |
defrouter_ref(installed_dr); |
773 |
defrouter_ref(installed_dr); |
|
Lines 789-802
defrouter_select(void)
Link Here
|
| 789 |
if (selected_dr == NULL) { |
789 |
if (selected_dr == NULL) { |
| 790 |
if (installed_dr == NULL || |
790 |
if (installed_dr == NULL || |
| 791 |
TAILQ_NEXT(installed_dr, dr_entry) == NULL) |
791 |
TAILQ_NEXT(installed_dr, dr_entry) == NULL) |
| 792 |
selected_dr = TAILQ_FIRST(&V_nd_defrouter); |
792 |
dr = TAILQ_FIRST(&V_nd_defrouter); |
| 793 |
else |
793 |
else |
| 794 |
selected_dr = TAILQ_NEXT(installed_dr, dr_entry); |
794 |
dr = TAILQ_NEXT(installed_dr, dr_entry); |
| 795 |
defrouter_ref(selected_dr); |
795 |
|
|
|
796 |
/* Ensure we select a router for this FIB. */ |
| 797 |
TAILQ_FOREACH_FROM(dr, &V_nd_defrouter, dr_entry) { |
| 798 |
if (dr->ifp->if_fib == fibnum) { |
| 799 |
selected_dr = dr; |
| 800 |
defrouter_ref(selected_dr); |
| 801 |
break; |
| 802 |
} |
| 803 |
} |
| 796 |
} else if (installed_dr != NULL) { |
804 |
} else if (installed_dr != NULL) { |
| 797 |
IF_AFDATA_RLOCK(installed_dr->ifp); |
805 |
IF_AFDATA_RLOCK(installed_dr->ifp); |
| 798 |
if ((ln = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) && |
806 |
if ((ln = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) && |
| 799 |
ND6_IS_LLINFO_PROBREACH(ln) && |
807 |
ND6_IS_LLINFO_PROBREACH(ln) && |
|
|
808 |
installed_dr->ifp->if_fib == fibnum && |
| 800 |
rtpref(selected_dr) <= rtpref(installed_dr)) { |
809 |
rtpref(selected_dr) <= rtpref(installed_dr)) { |
| 801 |
defrouter_rele(selected_dr); |
810 |
defrouter_rele(selected_dr); |
| 802 |
selected_dr = installed_dr; |
811 |
selected_dr = installed_dr; |
|
Lines 808-825
defrouter_select(void)
Link Here
|
| 808 |
ND6_RUNLOCK(); |
817 |
ND6_RUNLOCK(); |
| 809 |
|
818 |
|
| 810 |
/* |
819 |
/* |
| 811 |
* If the selected router is different than the installed one, |
820 |
* If we selected a router for this FIB and it's different |
| 812 |
* remove the installed router and install the selected one. |
821 |
* than the installed one, remove the installed router and |
| 813 |
* Note that the selected router is never NULL here. |
822 |
* install the selected one in its place. |
| 814 |
*/ |
823 |
*/ |
| 815 |
if (installed_dr != selected_dr) { |
824 |
if (installed_dr != selected_dr) { |
| 816 |
if (installed_dr != NULL) { |
825 |
if (installed_dr != NULL) { |
| 817 |
defrouter_delreq(installed_dr); |
826 |
defrouter_delreq(installed_dr); |
| 818 |
defrouter_rele(installed_dr); |
827 |
defrouter_rele(installed_dr); |
| 819 |
} |
828 |
} |
| 820 |
defrouter_addreq(selected_dr); |
829 |
if (selected_dr != NULL) |
|
|
830 |
defrouter_addreq(selected_dr); |
| 821 |
} |
831 |
} |
| 822 |
defrouter_rele(selected_dr); |
832 |
if (selected_dr != NULL) |
|
|
833 |
defrouter_rele(selected_dr); |
| 823 |
} |
834 |
} |
| 824 |
|
835 |
|
| 825 |
/* |
836 |
/* |
|
Lines 942-948
restart:
Link Here
|
| 942 |
V_nd6_list_genid++; |
953 |
V_nd6_list_genid++; |
| 943 |
ND6_WUNLOCK(); |
954 |
ND6_WUNLOCK(); |
| 944 |
|
955 |
|
| 945 |
defrouter_select(); |
956 |
defrouter_select(new->ifp->if_fib); |
| 946 |
|
957 |
|
| 947 |
return (n); |
958 |
return (n); |
| 948 |
} |
959 |
} |
|
Lines 1733-1739
nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
Link Here
|
| 1733 |
struct rtentry *rt; |
1744 |
struct rtentry *rt; |
| 1734 |
struct sockaddr_in6 mask6; |
1745 |
struct sockaddr_in6 mask6; |
| 1735 |
u_long rtflags; |
1746 |
u_long rtflags; |
| 1736 |
int error, a_failure, fibnum; |
1747 |
int error, a_failure, fibnum, maxfib; |
| 1737 |
|
1748 |
|
| 1738 |
/* |
1749 |
/* |
| 1739 |
* in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. |
1750 |
* in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. |
|
Lines 1744-1751
nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa)
Link Here
|
| 1744 |
mask6.sin6_addr = pr->ndpr_mask; |
1755 |
mask6.sin6_addr = pr->ndpr_mask; |
| 1745 |
rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP; |
1756 |
rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP; |
| 1746 |
|
1757 |
|
|
|
1758 |
if(rt_add_addr_allfibs) { |
| 1759 |
fibnum = 0; |
| 1760 |
maxfib = rt_numfibs; |
| 1761 |
} else { |
| 1762 |
fibnum = ifa->ifa_ifp->if_fib; |
| 1763 |
maxfib = fibnum + 1; |
| 1764 |
} |
| 1747 |
a_failure = 0; |
1765 |
a_failure = 0; |
| 1748 |
for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { |
1766 |
for (; fibnum < maxfib; fibnum++) { |
| 1749 |
|
1767 |
|
| 1750 |
rt = NULL; |
1768 |
rt = NULL; |
| 1751 |
error = in6_rtrequest(RTM_ADD, |
1769 |
error = in6_rtrequest(RTM_ADD, |
|
Lines 1833-1838
nd6_prefix_onlink(struct nd_prefix *pr)
Link Here
|
| 1833 |
if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) |
1851 |
if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) |
| 1834 |
continue; |
1852 |
continue; |
| 1835 |
|
1853 |
|
|
|
1854 |
if (!rt_add_addr_allfibs && |
| 1855 |
opr->ndpr_ifp->if_fib != pr->ndpr_ifp->if_fib) |
| 1856 |
continue; |
| 1857 |
|
| 1836 |
if (opr->ndpr_plen == pr->ndpr_plen && |
1858 |
if (opr->ndpr_plen == pr->ndpr_plen && |
| 1837 |
in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, |
1859 |
in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, |
| 1838 |
&opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { |
1860 |
&opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { |
|
Lines 1893-1899
nd6_prefix_offlink(struct nd_prefix *pr)
Link Here
|
| 1893 |
struct rtentry *rt; |
1915 |
struct rtentry *rt; |
| 1894 |
char ip6buf[INET6_ADDRSTRLEN]; |
1916 |
char ip6buf[INET6_ADDRSTRLEN]; |
| 1895 |
uint64_t genid; |
1917 |
uint64_t genid; |
| 1896 |
int fibnum, a_failure; |
1918 |
int fibnum, maxfib, a_failure; |
| 1897 |
|
1919 |
|
| 1898 |
ND6_ONLINK_LOCK_ASSERT(); |
1920 |
ND6_ONLINK_LOCK_ASSERT(); |
| 1899 |
ND6_UNLOCK_ASSERT(); |
1921 |
ND6_UNLOCK_ASSERT(); |
|
Lines 1911-1918
nd6_prefix_offlink(struct nd_prefix *pr)
Link Here
|
| 1911 |
mask6.sin6_len = sizeof(sa6); |
1933 |
mask6.sin6_len = sizeof(sa6); |
| 1912 |
bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); |
1934 |
bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); |
| 1913 |
|
1935 |
|
|
|
1936 |
if (rt_add_addr_allfibs) { |
| 1937 |
fibnum = 0; |
| 1938 |
maxfib = rt_numfibs; |
| 1939 |
} else { |
| 1940 |
fibnum = ifp->if_fib; |
| 1941 |
maxfib = fibnum + 1; |
| 1942 |
} |
| 1943 |
|
| 1914 |
a_failure = 0; |
1944 |
a_failure = 0; |
| 1915 |
for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { |
1945 |
for (; fibnum < maxfib; fibnum++) { |
| 1916 |
rt = NULL; |
1946 |
rt = NULL; |
| 1917 |
error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, |
1947 |
error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, |
| 1918 |
(struct sockaddr *)&mask6, 0, &rt, fibnum); |
1948 |
(struct sockaddr *)&mask6, 0, &rt, fibnum); |