FreeBSD Bugzilla – Attachment 178192 Details for
Bug 196361
Constrain IPv6 routes to each FIB (Consistent with IPv4 route behaviour)
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
Remember
[x]
|
Forgot Password
Login:
[x]
[patch]
Respect net.add_addr_allfibs=0 for inet6 (revision 1)
inet6-fib.patch (text/plain), 13.61 KB, created by
Erick Turnquist
on 2016-12-22 02:53:01 UTC
(
hide
)
Description:
Respect net.add_addr_allfibs=0 for inet6 (revision 1)
Filename:
MIME Type:
Creator:
Erick Turnquist
Created:
2016-12-22 02:53:01 UTC
Size:
13.61 KB
patch
obsolete
>diff --git a/sys/net/route.c b/sys/net/route.c >index 4b91e282780..947275b36ff 100644 >--- a/sys/net/route.c >+++ b/sys/net/route.c >@@ -2221,7 +2221,7 @@ rtinit(struct ifaddr *ifa, int cmd, int flags) > case AF_INET6: > case AF_INET: > /* We do support multiple FIBs. */ >- fib = RT_ALL_FIBS; >+ fib = rt_add_addr_allfibs ? RT_ALL_FIBS : ifa->ifa_ifp->if_fib; > break; > } > return (rtinit1(ifa, cmd, flags, fib)); >diff --git a/sys/netinet6/icmp6.c b/sys/netinet6/icmp6.c >index b6342e284d2..f5a5ec95d9f 100644 >--- a/sys/netinet6/icmp6.c >+++ b/sys/netinet6/icmp6.c >@@ -2064,6 +2064,7 @@ icmp6_reflect(struct mbuf *m, size_t off) > struct ifnet *outif = NULL; > int plen; > int type, code, hlim; >+ int fibnum; > > /* too short to reflect */ > if (off < sizeof(struct ip6_hdr)) { >@@ -2136,6 +2137,14 @@ icmp6_reflect(struct mbuf *m, size_t off) > ifa_free(&ia->ia_ifa); > } > >+ ia = in6ifa_ifwithaddr(&ip6->ip6_dst, 0 /* XXX */); >+ if (ia != NULL) { >+ fibnum = ia->ia_ifp->if_fib; >+ ifa_free(&ia->ia_ifa); >+ } else >+ fibnum = RT_DEFAULT_FIB; >+ M_SETFIB(m, fibnum); >+ > if (srcp == NULL) { > int error; > struct in6_addr dst6; >@@ -2147,7 +2156,7 @@ icmp6_reflect(struct mbuf *m, size_t off) > * source address of the erroneous packet. > */ > in6_splitscope(&ip6->ip6_src, &dst6, &scopeid); >- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6, >+ error = in6_selectsrc_addr(fibnum, &dst6, > scopeid, NULL, &src6, &hlim); > > if (error) { >@@ -2289,7 +2298,7 @@ icmp6_redirect_input(struct mbuf *m, int off) > uint32_t scopeid; > > in6_splitscope(&reddst6, &kdst, &scopeid); >- if (fib6_lookup_nh_basic(RT_DEFAULT_FIB, &kdst, scopeid, 0, 0,&nh6)==0){ >+ if (fib6_lookup_nh_basic(ifp->if_fib, &kdst, scopeid, 0, 0,&nh6)==0){ > if ((nh6.nh_flags & NHF_GATEWAY) == 0) { > nd6log((LOG_ERR, > "ICMP6 redirect rejected; no route " >diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c >index 8f1cae9f378..a0d8500f1b6 100644 >--- a/sys/netinet6/in6.c >+++ b/sys/netinet6/in6.c >@@ -159,6 +159,7 @@ in6_newaddrmsg(struct in6_ifaddr *ia, int cmd) > struct sockaddr_dl gateway; > struct sockaddr_in6 mask, addr; > struct rtentry rt; >+ int fibnum; > > /* > * initialize for rtmsg generation >@@ -176,8 +177,9 @@ in6_newaddrmsg(struct in6_ifaddr *ia, int cmd) > rt.rt_flags = RTF_HOST | RTF_STATIC; > if (cmd == RTM_ADD) > rt.rt_flags |= RTF_UP; >- /* Announce arrival of local address to all FIBs. */ >- rt_newaddrmsg(cmd, &ia->ia_ifa, 0, &rt); >+ fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : ia62ifa(ia)->ifa_ifp->if_fib; >+ /* Announce arrival of local address to this FIB. */ >+ rt_newaddrmsg_fib(cmd, &ia->ia_ifa, 0, &rt, fibnum); > } > > int >@@ -2115,15 +2117,15 @@ in6_lltable_rtcheck(struct ifnet *ifp, > uint32_t scopeid; > int error; > char ip6buf[INET6_ADDRSTRLEN]; >+ int fibnum; > > KASSERT(l3addr->sa_family == AF_INET6, > ("sin_family %d", l3addr->sa_family)); > >- /* Our local addresses are always only installed on the default FIB. */ >- > sin6 = (const struct sockaddr_in6 *)l3addr; > in6_splitscope(&sin6->sin6_addr, &dst, &scopeid); >- error = fib6_lookup_nh_basic(RT_DEFAULT_FIB, &dst, scopeid, 0, 0, &nh6); >+ fibnum = rt_add_addr_allfibs ? RT_DEFAULT_FIB : ifp->if_fib; >+ error = fib6_lookup_nh_basic(fibnum, &dst, scopeid, 0, 0, &nh6); > if (error != 0 || (nh6.nh_flags & NHF_GATEWAY) || nh6.nh_ifp != ifp) { > struct ifaddr *ifa; > /* >diff --git a/sys/netinet6/in6_src.c b/sys/netinet6/in6_src.c >index 54c0a0a90a2..22a27e9bf16 100644 >--- a/sys/netinet6/in6_src.c >+++ b/sys/netinet6/in6_src.c >@@ -297,7 +297,7 @@ in6_selectsrc(uint32_t fibnum, struct sockaddr_in6 *dstsock, > */ > /* get the outgoing interface */ > if ((error = in6_selectif(dstsock, opts, mopts, &ifp, oifp, >- (inp != NULL) ? inp->inp_inc.inc_fibnum : RT_DEFAULT_FIB)) != 0) >+ (inp != NULL) ? inp->inp_inc.inc_fibnum : fibnum)) != 0) > return (error); > > #ifdef DIAGNOSTIC >diff --git a/sys/netinet6/nd6.c b/sys/netinet6/nd6.c >index 0f565307998..54c0ecfa853 100644 >--- a/sys/netinet6/nd6.c >+++ b/sys/netinet6/nd6.c >@@ -157,6 +157,7 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) > struct sockaddr_dl gw; > struct ifnet *ifp; > int type; >+ int fibnum; > > LLE_WLOCK_ASSERT(lle); > >@@ -194,8 +195,9 @@ nd6_lle_event(void *arg __unused, struct llentry *lle, int evt) > rtinfo.rti_info[RTAX_DST] = (struct sockaddr *)&dst; > rtinfo.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&gw; > rtinfo.rti_addrs = RTA_DST | RTA_GATEWAY; >+ fibnum = rt_add_addr_allfibs ? RT_ALL_FIBS : ifp->if_fib; > rt_missmsg_fib(type, &rtinfo, RTF_HOST | RTF_LLDATA | ( >- type == RTM_ADD ? RTF_UP: 0), 0, RT_DEFAULT_FIB); >+ type == RTM_ADD ? RTF_UP: 0), 0, fibnum); > } > > /* >@@ -1204,7 +1206,7 @@ nd6_purge(struct ifnet *ifp) > > if (ND_IFINFO(ifp)->flags & ND6_IFF_ACCEPT_RTADV) { > /* Refresh default router list. */ >- defrouter_select(); >+ defrouter_select(ifp->if_fib); > } > } > >@@ -1290,9 +1292,7 @@ nd6_is_new_addr_neighbor(const struct sockaddr_in6 *addr, struct ifnet *ifp) > bzero(&rt_key, sizeof(rt_key)); > bzero(&info, sizeof(info)); > info.rti_info[RTAX_DST] = (struct sockaddr *)&rt_key; >- >- /* Always use the default FIB here. XXME - why? */ >- fibnum = RT_DEFAULT_FIB; >+ fibnum = ifp->if_fib; > > /* > * If the address matches one of our addresses, >@@ -1514,7 +1514,7 @@ nd6_free(struct llentry **lnp, int gc) > /* > * Refresh default router list. > */ >- defrouter_select(); >+ defrouter_select(dr->ifp->if_fib); > } > > /* >@@ -1770,7 +1770,8 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) > case SIOCSNDFLUSH_IN6: /* XXX: the ioctl name is confusing... */ > /* sync kernel routing table with the default router list */ > defrouter_reset(); >- defrouter_select(); >+ for (int fibnum = 0; fibnum < rt_numfibs; fibnum++) >+ defrouter_select(fibnum); > break; > case SIOCSPFXFLUSH_IN6: > { >@@ -1823,7 +1824,8 @@ nd6_ioctl(u_long cmd, caddr_t data, struct ifnet *ifp) > defrouter_del(dr); > } > >- defrouter_select(); >+ for (int fibnum = 0; fibnum < rt_numfibs; fibnum++) >+ defrouter_select(fibnum); > break; > } > case SIOCGNBRINFO_IN6: >@@ -2121,7 +2123,7 @@ nd6_cache_lladdr(struct ifnet *ifp, struct in6_addr *from, char *lladdr, > /* > * guaranteed recursion > */ >- defrouter_select(); >+ defrouter_select(ifp->if_fib); > } > } > >diff --git a/sys/netinet6/nd6.h b/sys/netinet6/nd6.h >index 9b9fa3d10ca..669187cbd67 100644 >--- a/sys/netinet6/nd6.h >+++ b/sys/netinet6/nd6.h >@@ -469,7 +469,7 @@ void nd6_dad_stop(struct ifaddr *); > void nd6_rs_input(struct mbuf *, int, int); > void nd6_ra_input(struct mbuf *, int, int); > void defrouter_reset(void); >-void defrouter_select(void); >+void defrouter_select(int fibnum); > void defrouter_ref(struct nd_defrouter *); > void defrouter_rele(struct nd_defrouter *); > bool defrouter_remove(struct in6_addr *, struct ifnet *); >diff --git a/sys/netinet6/nd6_nbr.c b/sys/netinet6/nd6_nbr.c >index eaa18d439a5..b05a4531277 100644 >--- a/sys/netinet6/nd6_nbr.c >+++ b/sys/netinet6/nd6_nbr.c >@@ -262,8 +262,7 @@ nd6_ns_input(struct mbuf *m, int off, int icmp6len) > bzero(&info, sizeof(info)); > info.rti_info[RTAX_GATEWAY] = (struct sockaddr *)&rt_gateway; > >- /* Always use the default FIB. */ >- if (rib_lookup_info(RT_DEFAULT_FIB, (struct sockaddr *)&dst6, >+ if (rib_lookup_info(ifp->if_fib, (struct sockaddr *)&dst6, > 0, 0, &info) == 0) { > if ((info.rti_flags & RTF_ANNOUNCE) != 0 && > rt_gateway.sdl_family == AF_LINK) { >@@ -485,7 +484,7 @@ nd6_ns_output_fib(struct ifnet *ifp, const struct in6_addr *saddr6, > uint32_t scopeid; > > in6_splitscope(&ip6->ip6_dst, &dst6, &scopeid); >- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6, >+ error = in6_selectsrc_addr(fibnum, &dst6, > scopeid, ifp, &src6, NULL); > if (error) { > char ip6buf[INET6_ADDRSTRLEN]; >@@ -982,7 +981,7 @@ nd6_na_output_fib(struct ifnet *ifp, const struct in6_addr *daddr6_0, > * Select a source whose scope is the same as that of the dest. > */ > in6_splitscope(&daddr6, &dst6, &scopeid); >- error = in6_selectsrc_addr(RT_DEFAULT_FIB, &dst6, >+ error = in6_selectsrc_addr(fibnum, &dst6, > scopeid, ifp, &src6, NULL); > if (error) { > char ip6buf[INET6_ADDRSTRLEN]; >diff --git a/sys/netinet6/nd6_rtr.c b/sys/netinet6/nd6_rtr.c >index f470f5200d5..ccead123d48 100644 >--- a/sys/netinet6/nd6_rtr.c >+++ b/sys/netinet6/nd6_rtr.c >@@ -500,7 +500,7 @@ defrouter_addreq(struct nd_defrouter *new) > > error = in6_rtrequest(RTM_ADD, (struct sockaddr *)&def, > (struct sockaddr *)&gate, (struct sockaddr *)&mask, >- RTF_GATEWAY, &newrt, RT_DEFAULT_FIB); >+ RTF_GATEWAY, &newrt, new->ifp->if_fib); > if (newrt) { > nd6_rtmsg(RTM_ADD, newrt); /* tell user process */ > RTFREE(newrt); >@@ -571,7 +571,7 @@ defrouter_delreq(struct nd_defrouter *dr) > > in6_rtrequest(RTM_DELETE, (struct sockaddr *)&def, > (struct sockaddr *)&gate, >- (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, RT_DEFAULT_FIB); >+ (struct sockaddr *)&mask, RTF_GATEWAY, &oldrt, dr->ifp->if_fib); > if (oldrt) { > nd6_rtmsg(RTM_DELETE, oldrt); > RTFREE(oldrt); >@@ -702,7 +702,7 @@ defrouter_del(struct nd_defrouter *dr) > * from the routing table. > */ > if (deldr) >- defrouter_select(); >+ defrouter_select(deldr->ifp->if_fib); > > /* > * Release the list reference. >@@ -732,7 +732,7 @@ defrouter_del(struct nd_defrouter *dr) > * complicated and the possibility of introducing bugs. > */ > void >-defrouter_select(void) >+defrouter_select(int fibnum) > { > struct nd_defrouter *dr, *selected_dr, *installed_dr; > struct llentry *ln = NULL; >@@ -755,7 +755,7 @@ defrouter_select(void) > selected_dr = installed_dr = NULL; > TAILQ_FOREACH(dr, &V_nd_defrouter, dr_entry) { > IF_AFDATA_RLOCK(dr->ifp); >- if (selected_dr == NULL && >+ if (selected_dr == NULL && dr->ifp->if_fib == fibnum && > (ln = nd6_lookup(&dr->rtaddr, 0, dr->ifp)) && > ND6_IS_LLINFO_PROBREACH(ln)) { > selected_dr = dr; >@@ -767,7 +767,7 @@ defrouter_select(void) > ln = NULL; > } > >- if (dr->installed) { >+ if (dr->installed && dr->ifp->if_fib == fibnum) { > if (installed_dr == NULL) { > installed_dr = dr; > defrouter_ref(installed_dr); >@@ -789,14 +789,23 @@ defrouter_select(void) > if (selected_dr == NULL) { > if (installed_dr == NULL || > TAILQ_NEXT(installed_dr, dr_entry) == NULL) >- selected_dr = TAILQ_FIRST(&V_nd_defrouter); >+ dr = TAILQ_FIRST(&V_nd_defrouter); > else >- selected_dr = TAILQ_NEXT(installed_dr, dr_entry); >- defrouter_ref(selected_dr); >+ dr = TAILQ_NEXT(installed_dr, dr_entry); >+ >+ /* Ensure we select a router for this FIB. */ >+ TAILQ_FOREACH_FROM(dr, &V_nd_defrouter, dr_entry) { >+ if (dr->ifp->if_fib == fibnum) { >+ selected_dr = dr; >+ defrouter_ref(selected_dr); >+ break; >+ } >+ } > } else if (installed_dr != NULL) { > IF_AFDATA_RLOCK(installed_dr->ifp); > if ((ln = nd6_lookup(&installed_dr->rtaddr, 0, installed_dr->ifp)) && > ND6_IS_LLINFO_PROBREACH(ln) && >+ installed_dr->ifp->if_fib == fibnum && > rtpref(selected_dr) <= rtpref(installed_dr)) { > defrouter_rele(selected_dr); > selected_dr = installed_dr; >@@ -808,18 +817,20 @@ defrouter_select(void) > ND6_RUNLOCK(); > > /* >- * If the selected router is different than the installed one, >- * remove the installed router and install the selected one. >- * Note that the selected router is never NULL here. >+ * If we selected a router for this FIB and it's different >+ * than the installed one, remove the installed router and >+ * install the selected one in its place. > */ > if (installed_dr != selected_dr) { > if (installed_dr != NULL) { > defrouter_delreq(installed_dr); > defrouter_rele(installed_dr); > } >- defrouter_addreq(selected_dr); >+ if (selected_dr != NULL) >+ defrouter_addreq(selected_dr); > } >- defrouter_rele(selected_dr); >+ if (selected_dr != NULL) >+ defrouter_rele(selected_dr); > } > > /* >@@ -942,7 +953,7 @@ restart: > V_nd6_list_genid++; > ND6_WUNLOCK(); > >- defrouter_select(); >+ defrouter_select(new->ifp->if_fib); > > return (n); > } >@@ -1733,7 +1744,7 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa) > struct rtentry *rt; > struct sockaddr_in6 mask6; > u_long rtflags; >- int error, a_failure, fibnum; >+ int error, a_failure, fibnum, maxfib; > > /* > * in6_ifinit() sets nd6_rtrequest to ifa_rtrequest for all ifaddrs. >@@ -1744,8 +1755,15 @@ nd6_prefix_onlink_rtrequest(struct nd_prefix *pr, struct ifaddr *ifa) > mask6.sin6_addr = pr->ndpr_mask; > rtflags = (ifa->ifa_flags & ~IFA_RTSELF) | RTF_UP; > >+ if(rt_add_addr_allfibs) { >+ fibnum = 0; >+ maxfib = rt_numfibs; >+ } else { >+ fibnum = ifa->ifa_ifp->if_fib; >+ maxfib = fibnum + 1; >+ } > a_failure = 0; >- for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { >+ for (; fibnum < maxfib; fibnum++) { > > rt = NULL; > error = in6_rtrequest(RTM_ADD, >@@ -1833,6 +1851,10 @@ nd6_prefix_onlink(struct nd_prefix *pr) > if ((opr->ndpr_stateflags & NDPRF_ONLINK) == 0) > continue; > >+ if (!rt_add_addr_allfibs && >+ opr->ndpr_ifp->if_fib != pr->ndpr_ifp->if_fib) >+ continue; >+ > if (opr->ndpr_plen == pr->ndpr_plen && > in6_are_prefix_equal(&pr->ndpr_prefix.sin6_addr, > &opr->ndpr_prefix.sin6_addr, pr->ndpr_plen)) { >@@ -1893,7 +1915,7 @@ nd6_prefix_offlink(struct nd_prefix *pr) > struct rtentry *rt; > char ip6buf[INET6_ADDRSTRLEN]; > uint64_t genid; >- int fibnum, a_failure; >+ int fibnum, maxfib, a_failure; > > ND6_ONLINK_LOCK_ASSERT(); > ND6_UNLOCK_ASSERT(); >@@ -1911,8 +1933,16 @@ nd6_prefix_offlink(struct nd_prefix *pr) > mask6.sin6_len = sizeof(sa6); > bcopy(&pr->ndpr_mask, &mask6.sin6_addr, sizeof(struct in6_addr)); > >+ if (rt_add_addr_allfibs) { >+ fibnum = 0; >+ maxfib = rt_numfibs; >+ } else { >+ fibnum = ifp->if_fib; >+ maxfib = fibnum + 1; >+ } >+ > a_failure = 0; >- for (fibnum = 0; fibnum < rt_numfibs; fibnum++) { >+ for (; fibnum < maxfib; fibnum++) { > rt = NULL; > error = in6_rtrequest(RTM_DELETE, (struct sockaddr *)&sa6, NULL, > (struct sockaddr *)&mask6, 0, &rt, fibnum);
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 196361
: 178192 |
178370