View | Details | Raw Unified | Return to bug 196361 | Differences between
and this patch

Collapse All | Expand All

(-)b/sys/net/route.c (-1 / +1 lines)
Lines 2221-2227 rtinit(struct ifaddr *ifa, int cmd, int flags) Link Here
2221
	case AF_INET6:
2221
	case AF_INET6:
2222
	case AF_INET:
2222
	case AF_INET:
2223
		/* We do support multiple FIBs. */
2223
		/* We do support multiple FIBs. */
2224
		fib = RT_ALL_FIBS;
2224
		fib = rt_add_addr_allfibs ? RT_ALL_FIBS : ifa->ifa_ifp->if_fib;
2225
		break;
2225
		break;
2226
	}
2226
	}
2227
	return (rtinit1(ifa, cmd, flags, fib));
2227
	return (rtinit1(ifa, cmd, flags, fib));
(-)b/sys/netinet6/icmp6.c (-2 / +11 lines)
Lines 2064-2069 icmp6_reflect(struct mbuf *m, size_t off) Link Here
2064
	struct ifnet *outif = NULL;
2064
	struct ifnet *outif = NULL;
2065
	int plen;
2065
	int plen;
2066
	int type, code, hlim;
2066
	int type, code, hlim;
2067
	int fibnum;
2067
2068
2068
	/* too short to reflect */
2069
	/* too short to reflect */
2069
	if (off < sizeof(struct ip6_hdr)) {
2070
	if (off < sizeof(struct ip6_hdr)) {
Lines 2136-2141 icmp6_reflect(struct mbuf *m, size_t off) Link Here
2136
			ifa_free(&ia->ia_ifa);
2137
			ifa_free(&ia->ia_ifa);
2137
	}
2138
	}
2138
2139
2140
	ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */);
2141
	if (ia != NULL) {
2142
		fibnum = ia->ia_ifp->if_fib;
2143
		ifa_free(&ia->ia_ifa);
2144
	} else
2145
		fibnum = RT_DEFAULT_FIB;
2146
	M_SETFIB(m, fibnum);
2147
2139
	if (srcp == NULL) {
2148
	if (srcp == NULL) {
2140
		int error;
2149
		int error;
2141
		struct in6_addr dst6;
2150
		struct in6_addr dst6;
Lines 2147-2153 icmp6_reflect(struct mbuf *m, size_t off) Link Here
2147
		 * source address of the erroneous packet.
2156
		 * source address of the erroneous packet.
2148
		 */
2157
		 */
2149
		in6_splitscope(&ip6->ip6_src, &dst6, &scopeid);
2158
		in6_splitscope(&ip6->ip6_src, &dst6, &scopeid);
2150
		error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
2159
		error = in6_selectsrc_addr(fibnum, &dst6,
2151
		    scopeid, NULL, &src6, &hlim);
2160
		    scopeid, NULL, &src6, &hlim);
2152
2161
2153
		if (error) {
2162
		if (error) {
Lines 2289-2295 icmp6_redirect_input(struct mbuf *m, int off) Link Here
2289
	uint32_t scopeid;
2298
	uint32_t scopeid;
2290
2299
2291
	in6_splitscope(&reddst6, &kdst, &scopeid);
2300
	in6_splitscope(&reddst6, &kdst, &scopeid);
2292
	if (fib6_lookup_nh_basic(RT_DEFAULT_FIB, &kdst, scopeid, 0, 0,&nh6)==0){
2301
	if (fib6_lookup_nh_basic(ifp->if_fib, &kdst, scopeid, 0, 0,&nh6)==0){
2293
		if ((nh6.nh_flags & NHF_GATEWAY) == 0) {
2302
		if ((nh6.nh_flags & NHF_GATEWAY) == 0) {
2294
			nd6log((LOG_ERR,
2303
			nd6log((LOG_ERR,
2295
			    "ICMP6 redirect rejected; no route "
2304
			    "ICMP6 redirect rejected; no route "
(-)b/sys/netinet6/in6.c (-5 / +7 lines)
Lines 159-164 in6_newaddrmsg(struct in6_ifaddr *ia, int cmd) Link Here
159
	struct sockaddr_dl gateway;
159
	struct sockaddr_dl gateway;
160
	struct sockaddr_in6 mask, addr;
160
	struct sockaddr_in6 mask, addr;
161
	struct rtentry rt;
161
	struct rtentry rt;
162
	int fibnum;
162
163
163
	/*
164
	/*
164
	 * initialize for rtmsg generation
165
	 * initialize for rtmsg generation
Lines 176-183 in6_newaddrmsg(struct in6_ifaddr *ia, int cmd) Link Here
176
	rt.rt_flags = RTF_HOST | RTF_STATIC;
177
	rt.rt_flags = RTF_HOST | RTF_STATIC;
177
	if (cmd == RTM_ADD)
178
	if (cmd == RTM_ADD)
178
		rt.rt_flags |= RTF_UP;
179
		rt.rt_flags |= RTF_UP;
179
	/* Announce arrival of local address to all FIBs. */
180
	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : ia62ifa(ia)->ifa_ifp->if_fib;
180
	rt_newaddrmsg(cmd, &ia->ia_ifa, 0, &rt);
181
	/* Announce arrival of local address to this FIB. */
182
	rt_newaddrmsg_fib(cmd, &ia->ia_ifa, 0, &rt, fibnum);
181
}
183
}
182
184
183
int
185
int
Lines 2115-2129 in6_lltable_rtcheck(struct ifnet *ifp, Link Here
2115
	uint32_t scopeid;
2117
	uint32_t scopeid;
2116
	int error;
2118
	int error;
2117
	char ip6buf[INET6_ADDRSTRLEN];
2119
	char ip6buf[INET6_ADDRSTRLEN];
2120
	int fibnum;
2118
2121
2119
	KASSERT(l3addr->sa_family == AF_INET6,
2122
	KASSERT(l3addr->sa_family == AF_INET6,
2120
	    ("sin_family %d", l3addr->sa_family));
2123
	    ("sin_family %d", l3addr->sa_family));
2121
2124
2122
	/* Our local addresses are always only installed on the default FIB. */
2123
2124
	sin6 = (const struct sockaddr_in6 *)l3addr;
2125
	sin6 = (const struct sockaddr_in6 *)l3addr;
2125
	in6_splitscope(&sin6->sin6_addr, &dst, &scopeid);
2126
	in6_splitscope(&sin6->sin6_addr, &dst, &scopeid);
2126
	error = fib6_lookup_nh_basic(RT_DEFAULT_FIB, &dst, scopeid, 0, 0, &nh6);
2127
	fibnum = rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib;
2128
	error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6);
2127
	if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
2129
	if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) {
2128
		struct ifaddr *ifa;
2130
		struct ifaddr *ifa;
2129
		/*
2131
		/*
(-)b/sys/netinet6/in6_src.c (-1 / +1 lines)
Lines 297-303 in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, Link Here
297
	 */
297
	 */
298
	/* get the outgoing interface */
298
	/* get the outgoing interface */
299
	if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp,
299
	if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp,
300
	    (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0)
300
	    (inp != NULL) ? inp->inp_inc.inc_fibnum : fibnum)) != 0)
301
		return (error);
301
		return (error);
302
302
303
#ifdef DIAGNOSTIC
303
#ifdef DIAGNOSTIC
(-)b/sys/netinet6/nd6.c (-9 / +11 lines)
Lines 157-162 nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) Link Here
157
	struct sockaddr_dl gw;
157
	struct sockaddr_dl gw;
158
	struct ifnet *ifp;
158
	struct ifnet *ifp;
159
	int type;
159
	int type;
160
	int fibnum;
160
161
161
	LLE_WLOCK_ASSERT(lle);
162
	LLE_WLOCK_ASSERT(lle);
162
163
Lines 194-201 nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) Link Here
194
	rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst;
195
	rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst;
195
	rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
196
	rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw;
196
	rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY;
197
	rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY;
198
	fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : ifp->if_fib;
197
	rt_missmsg_fib(type, &rtinfo, RTF_HOST | RTF_LLDATA | (
199
	rt_missmsg_fib(type, &rtinfo, RTF_HOST | RTF_LLDATA | (
198
	    type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB);
200
	    type == RTM_ADD ? RTF_UP: 0), 0, fibnum);
199
}
201
}
200
202
201
/*
203
/*
Lines 1204-1210 nd6_purge(struct ifnet *ifp) Link Here
1204
1206
1205
	if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) {
1207
	if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) {
1206
		/* Refresh default router list. */
1208
		/* Refresh default router list. */
1207
		defrouter_select();
1209
		defrouter_select(ifp->if_fib);
1208
	}
1210
	}
1209
}
1211
}
1210
1212
Lines 1290-1298 nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) Link Here
1290
	bzero(&rt_key, sizeof(rt_key));
1292
	bzero(&rt_key, sizeof(rt_key));
1291
	bzero(&info, sizeof(info));
1293
	bzero(&info, sizeof(info));
1292
	info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key;
1294
	info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key;
1293
1295
	fibnum = ifp->if_fib;
1294
	/* Always use the default FIB here. XXME - why? */
1295
	fibnum = RT_DEFAULT_FIB;
1296
1296
1297
	/*
1297
	/*
1298
	 * If the address matches one of our addresses,
1298
	 * If the address matches one of our addresses,
Lines 1514-1520 nd6_free(struct llentry **lnp, int gc) Link Here
1514
			/*
1514
			/*
1515
			 * Refresh default router list.
1515
			 * Refresh default router list.
1516
			 */
1516
			 */
1517
			defrouter_select();
1517
			defrouter_select(dr->ifp->if_fib);
1518
		}
1518
		}
1519
1519
1520
		/*
1520
		/*
Lines 1770-1776 nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) Link Here
1770
	case SIOCSNDFLUSH_IN6:	/* XXX: the ioctl name is confusing... */
1770
	case SIOCSNDFLUSH_IN6:	/* XXX: the ioctl name is confusing... */
1771
		/* sync kernel routing table with the default router list */
1771
		/* sync kernel routing table with the default router list */
1772
		defrouter_reset();
1772
		defrouter_reset();
1773
		defrouter_select();
1773
		for (int fibnum = 0; fibnum < rt_numfibs; fibnum++)
1774
			defrouter_select(fibnum);
1774
		break;
1775
		break;
1775
	case SIOCSPFXFLUSH_IN6:
1776
	case SIOCSPFXFLUSH_IN6:
1776
	{
1777
	{
Lines 1823-1829 nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) Link Here
1823
			defrouter_del(dr);
1824
			defrouter_del(dr);
1824
		}
1825
		}
1825
1826
1826
		defrouter_select();
1827
		for (int fibnum = 0; fibnum < rt_numfibs; fibnum++)
1828
			defrouter_select(fibnum);
1827
		break;
1829
		break;
1828
	}
1830
	}
1829
	case SIOCGNBRINFO_IN6:
1831
	case SIOCGNBRINFO_IN6:
Lines 2121-2127 nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, Link Here
2121
		/*
2123
		/*
2122
		 * guaranteed recursion
2124
		 * guaranteed recursion
2123
		 */
2125
		 */
2124
		defrouter_select();
2126
		defrouter_select(ifp->if_fib);
2125
	}
2127
	}
2126
}
2128
}
2127
2129
(-)b/sys/netinet6/nd6.h (-1 / +1 lines)
Lines 469-475 void nd6_dad_stop(struct ifaddr *); Link Here
469
void nd6_rs_input(struct mbuf *, int, int);
469
void nd6_rs_input(struct mbuf *, int, int);
470
void nd6_ra_input(struct mbuf *, int, int);
470
void nd6_ra_input(struct mbuf *, int, int);
471
void defrouter_reset(void);
471
void defrouter_reset(void);
472
void defrouter_select(void);
472
void defrouter_select(int fibnum);
473
void defrouter_ref(struct nd_defrouter *);
473
void defrouter_ref(struct nd_defrouter *);
474
void defrouter_rele(struct nd_defrouter *);
474
void defrouter_rele(struct nd_defrouter *);
475
bool defrouter_remove(struct in6_addr *, struct ifnet *);
475
bool defrouter_remove(struct in6_addr *, struct ifnet *);
(-)b/sys/netinet6/nd6_nbr.c (-4 / +3 lines)
Lines 262-269 nd6_ns_input(struct mbuf *m, int off, int icmp6len) Link Here
262
		bzero(&info, sizeof(info));
262
		bzero(&info, sizeof(info));
263
		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
263
		info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway;
264
264
265
		/* Always use the default FIB. */
265
		if (rib_lookup_info(ifp->if_fib, (struct sockaddr *)&dst6,
266
		if (rib_lookup_info(RT_DEFAULT_FIB, (struct sockaddr *)&dst6,
267
		    0, 0, &info) == 0) {
266
		    0, 0, &info) == 0) {
268
			if ((info.rti_flags & RTF_ANNOUNCE) != 0 &&
267
			if ((info.rti_flags & RTF_ANNOUNCE) != 0 &&
269
			    rt_gateway.sdl_family == AF_LINK) {
268
			    rt_gateway.sdl_family == AF_LINK) {
Lines 485-491 nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, Link Here
485
			uint32_t scopeid;
484
			uint32_t scopeid;
486
485
487
			in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
486
			in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid);
488
			error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
487
			error = in6_selectsrc_addr(fibnum, &dst6,
489
			    scopeid, ifp, &src6, NULL);
488
			    scopeid, ifp, &src6, NULL);
490
			if (error) {
489
			if (error) {
491
				char ip6buf[INET6_ADDRSTRLEN];
490
				char ip6buf[INET6_ADDRSTRLEN];
Lines 982-988 nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, Link Here
982
	 * Select a source whose scope is the same as that of the dest.
981
	 * Select a source whose scope is the same as that of the dest.
983
	 */
982
	 */
984
	in6_splitscope(&daddr6, &dst6, &scopeid);
983
	in6_splitscope(&daddr6, &dst6, &scopeid);
985
	error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6,
984
	error = in6_selectsrc_addr(fibnum, &dst6,
986
	    scopeid, ifp, &src6, NULL);
985
	    scopeid, ifp, &src6, NULL);
987
	if (error) {
986
	if (error) {
988
		char ip6buf[INET6_ADDRSTRLEN];
987
		char ip6buf[INET6_ADDRSTRLEN];
(-)b/sys/netinet6/nd6_rtr.c (-19 / +49 lines)
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);

Return to bug 196361