Index: sys/net/if_mpe.c =================================================================== RCS file: /cvs/src/sys/net/if_mpe.c,v retrieving revision 1.80 diff -u -p -r1.80 if_mpe.c --- sys/net/if_mpe.c 11 Feb 2019 00:11:24 -0000 1.80 +++ sys/net/if_mpe.c 11 Feb 2019 01:07:40 -0000 @@ -130,7 +130,7 @@ mpe_clone_destroy(struct ifnet *ifp) if (sc->sc_smpls.smpls_label) { rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); } if_detach(ifp); @@ -316,12 +316,12 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd, if (sc->sc_smpls.smpls_label) { /* remove old MPLS route */ rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); } /* add new MPLS route */ sc->sc_smpls.smpls_label = shim.shim_label; error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); if (error) { sc->sc_smpls.smpls_label = 0; break; @@ -333,7 +333,7 @@ mpe_ioctl(struct ifnet *ifp, u_long cmd, if (ifr->ifr_rdomainid != ifp->if_rdomain) { if (sc->sc_smpls.smpls_label) { rt_ifa_add(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); } } /* return with ENOTTY so that the parent handler finishes */ Index: sys/net/if_mpw.c =================================================================== RCS file: /cvs/src/sys/net/if_mpw.c,v retrieving revision 1.33 diff -u -p -r1.33 if_mpw.c --- sys/net/if_mpw.c 11 Feb 2019 00:11:24 -0000 1.33 +++ sys/net/if_mpw.c 11 Feb 2019 01:07:40 -0000 @@ -120,7 +120,7 @@ mpw_clone_destroy(struct ifnet *ifp) if (sc->sc_smpls.smpls_label) { rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); } ether_ifdetach(ifp); @@ -166,7 +166,7 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, sin = (struct sockaddr_in *) &imr.imr_nexthop; if (sin->sin_addr.s_addr == 0) { if (rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)) == 0) + smplstosa(&sc->sc_smpls), 0) == 0) sc->sc_smpls.smpls_label = 0; memset(&sc->sc_rshim, 0, sizeof(sc->sc_rshim)); @@ -195,11 +195,11 @@ mpw_ioctl(struct ifnet *ifp, u_long cmd, if (sc->sc_smpls.smpls_label != imr.imr_lshim.shim_label) { if (sc->sc_smpls.smpls_label) rt_ifa_del(&sc->sc_ifa, RTF_MPLS, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); sc->sc_smpls.smpls_label = imr.imr_lshim.shim_label; error = rt_ifa_add(&sc->sc_ifa, RTF_MPLS|RTF_LOCAL, - smplstosa(&sc->sc_smpls)); + smplstosa(&sc->sc_smpls), 0); if (error != 0) { sc->sc_smpls.smpls_label = 0; break; Index: sys/net/route.c =================================================================== RCS file: /cvs/src/sys/net/route.c,v retrieving revision 1.380 diff -u -p -r1.380 route.c --- sys/net/route.c 10 Feb 2019 22:32:26 -0000 1.380 +++ sys/net/route.c 11 Feb 2019 01:07:40 -0000 @@ -1030,13 +1030,13 @@ rt_maskedcopy(struct sockaddr *src, stru } int -rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst) +rt_ifa_add(struct ifaddr *ifa, int flags, struct sockaddr *dst, + unsigned int rdomain) { struct ifnet *ifp = ifa->ifa_ifp; struct rtentry *rt; struct sockaddr_rtlabel sa_rl; struct rt_addrinfo info; - unsigned int rtableid = ifp->if_rdomain; uint8_t prio = ifp->if_priority + RTP_STATIC; int error; @@ -1048,14 +1048,16 @@ rt_ifa_add(struct ifaddr *ifa, int flags info.rti_info[RTAX_GATEWAY] = sdltosa(ifp->if_sadl); else info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; - info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl); + + KASSERT(rdomain == rtable_l2(rdomain)); + if (rdomain == rtable_l2(ifp->if_rtlabelid)) { + info.rti_info[RTAX_LABEL] = + rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl); + } #ifdef MPLS - if ((flags & RTF_MPLS) == RTF_MPLS) { + if ((flags & RTF_MPLS) == RTF_MPLS) info.rti_mpls = MPLS_OP_POP; - /* MPLS routes only exist in rdomain 0 */ - rtableid = 0; - } #endif /* MPLS */ if ((flags & RTF_HOST) == 0) @@ -1067,7 +1069,7 @@ rt_ifa_add(struct ifaddr *ifa, int flags if (flags & RTF_CONNECTED) prio = ifp->if_priority + RTP_CONNECTED; - error = rtrequest(RTM_ADD, &info, prio, &rt, rtableid); + error = rtrequest(RTM_ADD, &info, prio, &rt, rdomain); if (error == 0) { /* * A local route is created for every address configured @@ -1076,14 +1078,15 @@ rt_ifa_add(struct ifaddr *ifa, int flags */ if (flags & RTF_LOCAL) rtm_addr(RTM_NEWADDR, ifa); - rtm_send(rt, RTM_ADD, 0, rtableid); + rtm_send(rt, RTM_ADD, 0, rdomain); rtfree(rt); } return (error); } int -rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst) +rt_ifa_del(struct ifaddr *ifa, int flags, struct sockaddr *dst, + unsigned int rdomain) { struct ifnet *ifp = ifa->ifa_ifp; struct rtentry *rt; @@ -1091,16 +1094,9 @@ rt_ifa_del(struct ifaddr *ifa, int flags struct sockaddr *deldst; struct rt_addrinfo info; struct sockaddr_rtlabel sa_rl; - unsigned int rtableid = ifp->if_rdomain; uint8_t prio = ifp->if_priority + RTP_STATIC; int error; -#ifdef MPLS - if ((flags & RTF_MPLS) == RTF_MPLS) - /* MPLS routes only exist in rdomain 0 */ - rtableid = 0; -#endif /* MPLS */ - if ((flags & RTF_HOST) == 0 && ifa->ifa_netmask) { m = m_get(M_DONTWAIT, MT_SONAME); if (m == NULL) @@ -1116,7 +1112,12 @@ rt_ifa_del(struct ifaddr *ifa, int flags info.rti_info[RTAX_DST] = dst; if ((flags & RTF_LLINFO) == 0) info.rti_info[RTAX_GATEWAY] = ifa->ifa_addr; - info.rti_info[RTAX_LABEL] = rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl); + + KASSERT(rdomain == rtable_l2(rdomain)); + if (rdomain == rtable_l2(ifp->if_rtlabelid)) { + info.rti_info[RTAX_LABEL] = + rtlabel_id2sa(ifp->if_rtlabelid, &sa_rl); + } if ((flags & RTF_HOST) == 0) info.rti_info[RTAX_NETMASK] = ifa->ifa_netmask; @@ -1127,9 +1128,9 @@ rt_ifa_del(struct ifaddr *ifa, int flags if (flags & RTF_CONNECTED) prio = ifp->if_priority + RTP_CONNECTED; - error = rtrequest_delete(&info, prio, ifp, &rt, rtableid); + error = rtrequest_delete(&info, prio, ifp, &rt, rdomain); if (error == 0) { - rtm_send(rt, RTM_DELETE, 0, rtableid); + rtm_send(rt, RTM_DELETE, 0, rdomain); if (flags & RTF_LOCAL) rtm_addr(RTM_DELADDR, ifa); rtfree(rt); @@ -1145,6 +1146,7 @@ rt_ifa_del(struct ifaddr *ifa, int flags int rt_ifa_addlocal(struct ifaddr *ifa) { + struct ifnet *ifp = ifa->ifa_ifp; struct rtentry *rt; u_int flags = RTF_HOST|RTF_LOCAL; int error = 0; @@ -1171,13 +1173,15 @@ rt_ifa_addlocal(struct ifaddr *ifa) break; } - if (!ISSET(ifa->ifa_ifp->if_flags, (IFF_LOOPBACK|IFF_POINTOPOINT))) + if (!ISSET(ifp->if_flags, (IFF_LOOPBACK|IFF_POINTOPOINT))) flags |= RTF_LLINFO; /* If there is no local entry, allocate one. */ - rt = rtalloc(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain); - if (rt == NULL || ISSET(rt->rt_flags, flags) != flags) - error = rt_ifa_add(ifa, flags | RTF_MPATH, ifa->ifa_addr); + rt = rtalloc(ifa->ifa_addr, 0, ifp->if_rdomain); + if (rt == NULL || ISSET(rt->rt_flags, flags) != flags) { + error = rt_ifa_add(ifa, flags | RTF_MPATH, ifa->ifa_addr, + ifp->if_rdomain); + } rtfree(rt); return (error); @@ -1189,6 +1193,7 @@ rt_ifa_addlocal(struct ifaddr *ifa) int rt_ifa_dellocal(struct ifaddr *ifa) { + struct ifnet *ifp = ifa->ifa_ifp; struct rtentry *rt; u_int flags = RTF_HOST|RTF_LOCAL; int error = 0; @@ -1213,7 +1218,7 @@ rt_ifa_dellocal(struct ifaddr *ifa) break; } - if (!ISSET(ifa->ifa_ifp->if_flags, (IFF_LOOPBACK|IFF_POINTOPOINT))) + if (!ISSET(ifp->if_flags, (IFF_LOOPBACK|IFF_POINTOPOINT))) flags |= RTF_LLINFO; /* @@ -1224,9 +1229,11 @@ rt_ifa_dellocal(struct ifaddr *ifa) * a subnet-router anycast address on an interface attached * to a shared medium. */ - rt = rtalloc(ifa->ifa_addr, 0, ifa->ifa_ifp->if_rdomain); - if (rt != NULL && ISSET(rt->rt_flags, flags) == flags) - error = rt_ifa_del(ifa, flags, ifa->ifa_addr); + rt = rtalloc(ifa->ifa_addr, 0, ifp->if_rdomain); + if (rt != NULL && ISSET(rt->rt_flags, flags) == flags) { + error = rt_ifa_del(ifa, flags, ifa->ifa_addr, + ifp->if_rdomain); + } rtfree(rt); return (error); Index: sys/net/route.h =================================================================== RCS file: /cvs/src/sys/net/route.h,v retrieving revision 1.173 diff -u -p -r1.173 route.h --- sys/net/route.h 12 Nov 2018 16:36:54 -0000 1.173 +++ sys/net/route.h 11 Feb 2019 01:07:40 -0000 @@ -455,8 +455,8 @@ struct rtentry *rtalloc(struct sockaddr void rtref(struct rtentry *); void rtfree(struct rtentry *); -int rt_ifa_add(struct ifaddr *, int, struct sockaddr *); -int rt_ifa_del(struct ifaddr *, int, struct sockaddr *); +int rt_ifa_add(struct ifaddr *, int, struct sockaddr *, unsigned int); +int rt_ifa_del(struct ifaddr *, int, struct sockaddr *, unsigned int); void rt_ifa_purge(struct ifaddr *); int rt_ifa_addlocal(struct ifaddr *); int rt_ifa_dellocal(struct ifaddr *); Index: sys/netinet/in.c =================================================================== RCS file: /cvs/src/sys/netinet/in.c,v retrieving revision 1.161 diff -u -p -r1.161 in.c --- sys/netinet/in.c 10 Feb 2019 22:32:26 -0000 1.161 +++ sys/netinet/in.c 11 Feb 2019 01:07:40 -0000 @@ -694,13 +694,15 @@ in_purgeaddr(struct ifaddr *ifa) int in_addhost(struct in_ifaddr *ia, struct sockaddr_in *dst) { - return rt_ifa_add(&ia->ia_ifa, RTF_HOST | RTF_MPATH, sintosa(dst)); + return rt_ifa_add(&ia->ia_ifa, RTF_HOST | RTF_MPATH, + sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain); } int in_scrubhost(struct in_ifaddr *ia, struct sockaddr_in *dst) { - return rt_ifa_del(&ia->ia_ifa, RTF_HOST, sintosa(dst)); + return rt_ifa_del(&ia->ia_ifa, RTF_HOST, + sintosa(dst), ia->ia_ifa.ifa_ifp->if_rdomain); } /* @@ -713,13 +715,14 @@ in_insert_prefix(struct in_ifaddr *ia) int error; error = rt_ifa_add(ifa, RTF_CLONING | RTF_CONNECTED | RTF_MPATH, - ifa->ifa_addr); + ifa->ifa_addr, ifa->ifa_ifp->if_rdomain); if (error) return (error); - if (ia->ia_broadaddr.sin_addr.s_addr != 0) + if (ia->ia_broadaddr.sin_addr.s_addr != 0) { error = rt_ifa_add(ifa, RTF_HOST | RTF_BROADCAST | RTF_MPATH, - ifa->ifa_broadaddr); + ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain); + } return (error); } @@ -729,10 +732,13 @@ in_remove_prefix(struct in_ifaddr *ia) { struct ifaddr *ifa = &ia->ia_ifa; - rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, ifa->ifa_addr); + rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, + ifa->ifa_addr, ifa->ifa_ifp->if_rdomain); - if (ia->ia_broadaddr.sin_addr.s_addr != 0) - rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST, ifa->ifa_broadaddr); + if (ia->ia_broadaddr.sin_addr.s_addr != 0) { + rt_ifa_del(ifa, RTF_HOST | RTF_BROADCAST, + ifa->ifa_broadaddr, ifa->ifa_ifp->if_rdomain); + } } /* Index: sys/netinet/ip_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet/ip_mroute.c,v retrieving revision 1.124 diff -u -p -r1.124 ip_mroute.c --- sys/netinet/ip_mroute.c 10 Feb 2019 22:32:26 -0000 1.124 +++ sys/netinet/ip_mroute.c 11 Feb 2019 01:07:40 -0000 @@ -1308,7 +1308,8 @@ rt_mcast_add(struct ifnet *ifp, struct s return (NULL); } - rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, group); + rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, + group, ifp->if_rdomain); if (rv != 0) { DPRINTF("rt_ifa_add failed (%d)", rv); return (NULL); Index: sys/netinet6/in6.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6.c,v retrieving revision 1.229 diff -u -p -r1.229 in6.c --- sys/netinet6/in6.c 10 Feb 2019 22:32:26 -0000 1.229 +++ sys/netinet6/in6.c 11 Feb 2019 01:07:40 -0000 @@ -378,7 +378,7 @@ in6_ioctl_change_ifaddr(u_long cmd, cadd error = rt_ifa_add(&ia6->ia_ifa, RTF_CLONING | RTF_CONNECTED | RTF_MPATH, - ia6->ia_ifa.ifa_addr); + ia6->ia_ifa.ifa_addr, ifp->if_rdomain); if (error) { in6_purgeaddr(&ia6->ia_ifa); break; @@ -680,7 +680,8 @@ in6_update_ifa(struct ifnet *ifp, struct struct ifaddr *ifa = &ia6->ia_ifa; if ((ia6->ia_flags & IFA_ROUTE) != 0 && - rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr) != 0) { + rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr, + ifp->if_rdomain) != 0) { nd6log((LOG_ERR, "in6_update_ifa: failed to remove " "a route to the old destination: %s\n", inet_ntop(AF_INET6, &ia6->ia_addr.sin6_addr, @@ -888,7 +889,9 @@ in6_purgeaddr(struct ifaddr *ifa) ia6->ia_dstaddr.sin6_len != 0) { int e; - if ((e = rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr)) != 0) { + e = rt_ifa_del(ifa, RTF_HOST, ifa->ifa_dstaddr, + ifp->if_rdomain); + if (e != 0) { char addr[INET6_ADDRSTRLEN]; log(LOG_ERR, "in6_purgeaddr: failed to remove " "a route to the p2p destination: %s on %s, " @@ -929,7 +932,7 @@ in6_unlink_ifa(struct in6_ifaddr *ia6, s plen = in6_mask2len(&ia6->ia_prefixmask.sin6_addr, NULL); if ((ifp->if_flags & IFF_LOOPBACK) == 0 && plen != 128) { rt_ifa_del(ifa, RTF_CLONING | RTF_CONNECTED, - ifa->ifa_addr); + ifa->ifa_addr, ifp->if_rdomain); } rt_ifa_purge(ifa); @@ -984,7 +987,7 @@ in6_ifinit(struct ifnet *ifp, struct in6 ia6->ia_dstaddr.sin6_family == AF_INET6) { ifa = &ia6->ia_ifa; error = rt_ifa_add(ifa, RTF_HOST | RTF_MPATH, - ifa->ifa_dstaddr); + ifa->ifa_dstaddr, ifp->if_rdomain); if (error != 0) return (error); ia6->ia_flags |= IFA_ROUTE; Index: sys/netinet6/in6_ifattach.c =================================================================== RCS file: /cvs/src/sys/netinet6/in6_ifattach.c,v retrieving revision 1.112 diff -u -p -r1.112 in6_ifattach.c --- sys/netinet6/in6_ifattach.c 10 Feb 2019 22:32:26 -0000 1.112 +++ sys/netinet6/in6_ifattach.c 11 Feb 2019 01:07:40 -0000 @@ -378,7 +378,8 @@ in6_ifattach_linklocal(struct ifnet *ifp if ((ifp->if_flags & IFF_POINTOPOINT) == 0) flags |= RTF_CLONING; - error = rt_ifa_add(&ia6->ia_ifa, flags, ia6->ia_ifa.ifa_addr); + error = rt_ifa_add(&ia6->ia_ifa, flags, ia6->ia_ifa.ifa_addr, + ifp->if_rdomain); if (error) { in6_purgeaddr(&ia6->ia_ifa); return (error); Index: sys/netinet6/ip6_mroute.c =================================================================== RCS file: /cvs/src/sys/netinet6/ip6_mroute.c,v retrieving revision 1.117 diff -u -p -r1.117 ip6_mroute.c --- sys/netinet6/ip6_mroute.c 10 Feb 2019 22:32:26 -0000 1.117 +++ sys/netinet6/ip6_mroute.c 11 Feb 2019 01:07:40 -0000 @@ -1241,7 +1241,8 @@ mrt6_mcast6_add(struct ifnet *ifp, struc return NULL; } - rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, group); + rv = rt_ifa_add(ifa, RTF_HOST | RTF_MULTICAST | RTF_MPATH, group, + ifp->if_rdomain); if (rv != 0) { DPRINTF("rt_ifa_add failed %d", rv); return NULL; Index: share/man/man9/rt_ifa_add.9 =================================================================== RCS file: /cvs/src/share/man/man9/rt_ifa_add.9,v retrieving revision 1.5 diff -u -p -r1.5 rt_ifa_add.9 --- share/man/man9/rt_ifa_add.9 30 Oct 2015 09:48:03 -0000 1.5 +++ share/man/man9/rt_ifa_add.9 11 Feb 2019 01:07:40 -0000 @@ -29,9 +29,19 @@ .In net/if.h .In net/route.h .Ft int -.Fn rt_ifa_add "struct ifaddr *ifa" "int flags" "struct sockaddr *dst" +.Fo rt_ifa_add +.Fa "struct ifaddr *ifa" +.Fa "int flags" +.Fa "struct sockaddr *dst" +.Fa "unsigned int rdomain" +.Fc .Ft int -.Fn rt_ifa_del "struct ifaddr *ifa" "int flags" "struct sockaddr *dst" +.Fo rt_ifa_del +.Fa "struct ifaddr *ifa" +.Fa "int flags" +.Fa "struct sockaddr *dst" +.Fa "unsigned int rdomain" +.Fc .Ft int .Fn rt_ifa_addlocal "struct ifaddr *ifa" .Ft int @@ -42,7 +52,9 @@ stack and managed by the kernel. .Bl -tag -width rt_ifa_addlocalxx .It Fn rt_ifa_add Creates and associates a connected routing entry with -.Fa ifa . +.Fa ifa +in the routing domain specified by +.Fa rdomain . .Pp Connected routing entries represent routes to prefixes and should be created with @@ -65,7 +77,9 @@ Connected routing entries have a priorit .Dv RTP_CONNECTED . .It Fn rt_ifa_del Removes the connected routing entry associated with -.Fa ifa . +.Fa ifa +in the routing domain specified by +.Fa rdomain . .It Fn rt_ifa_addlocal Creates and associates a local routing entry with