Index: sys/compat/linuxkpi/common/include/linux/inetdevice.h =================================================================== --- sys/compat/linuxkpi/common/include/linux/inetdevice.h +++ sys/compat/linuxkpi/common/include/linux/inetdevice.h @@ -47,7 +47,7 @@ sin.sin_family = AF_INET; NET_EPOCH_ENTER(et); CURVNET_SET_QUIET(vnet); - ifa = ifa_ifwithaddr((struct sockaddr *)&sin); + ifa = ifa_ifwithaddr((struct sockaddr *)&sin, RT_ALL_FIBS); CURVNET_RESTORE(); if (ifa) { ifp = ifa->ifa_ifp; @@ -78,7 +78,7 @@ } NET_EPOCH_ENTER(et); CURVNET_SET_QUIET(vnet); - ifa = ifa_ifwithaddr((struct sockaddr *)&sin6); + ifa = ifa_ifwithaddr((struct sockaddr *)&sin6, RT_ALL_FIBS); CURVNET_RESTORE(); if (ifa != NULL) { ifp = ifa->ifa_ifp; Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -1928,7 +1928,7 @@ */ /*ARGSUSED*/ struct ifaddr * -ifa_ifwithaddr(const struct sockaddr *addr) +ifa_ifwithaddr(const struct sockaddr *addr, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; @@ -1936,6 +1936,8 @@ NET_EPOCH_ASSERT(); CK_STAILQ_FOREACH(ifp, &V_ifnet, if_link) { + if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum)) + continue; CK_STAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != addr->sa_family) continue; @@ -1957,13 +1959,13 @@ } int -ifa_ifwithaddr_check(const struct sockaddr *addr) +ifa_ifwithaddr_check(const struct sockaddr *addr, int fibnum) { struct epoch_tracker et; int rc; NET_EPOCH_ENTER(et); - rc = (ifa_ifwithaddr(addr) != NULL); + rc = (ifa_ifwithaddr(addr, fibnum) != NULL); NET_EPOCH_EXIT(et); return (rc); } Index: sys/net/if_var.h =================================================================== --- sys/net/if_var.h +++ sys/net/if_var.h @@ -681,8 +681,8 @@ int ifa_del_loopback_route(struct ifaddr *, struct sockaddr *); int ifa_switch_loopback_route(struct ifaddr *, struct sockaddr *); -struct ifaddr *ifa_ifwithaddr(const struct sockaddr *); -int ifa_ifwithaddr_check(const struct sockaddr *); +struct ifaddr *ifa_ifwithaddr(const struct sockaddr *, int fibnum); +int ifa_ifwithaddr_check(const struct sockaddr *, int fibnum); struct ifaddr *ifa_ifwithbroadaddr(const struct sockaddr *, int); struct ifaddr *ifa_ifwithdstaddr(const struct sockaddr *, int); struct ifaddr *ifa_ifwithnet(const struct sockaddr *, int, int); Index: sys/net/route.c =================================================================== --- sys/net/route.c +++ sys/net/route.c @@ -562,7 +562,7 @@ if (flags & RTF_HOST) ifa = ifa_ifwithdstaddr(dst, fibnum); if (ifa == NULL) - ifa = ifa_ifwithaddr(gateway); + ifa = ifa_ifwithaddr(gateway, fibnum); } else { /* * If we are adding a route to a remote net @@ -937,7 +937,7 @@ * TODO: avoid enumerating all ifas on all interfaces. */ if (info->rti_ifa == NULL && ifaaddr != NULL) - info->rti_ifa = ifa_ifwithaddr(ifaaddr); + info->rti_ifa = ifa_ifwithaddr(ifaaddr, fibnum); if (info->rti_ifa == NULL) { const struct sockaddr *sa; Index: sys/netinet/in_pcb.c =================================================================== --- sys/netinet/in_pcb.c +++ sys/netinet/in_pcb.c @@ -922,7 +922,7 @@ * to any endpoint address, local or not. */ if ((inp->inp_flags & INP_BINDANY) == 0 && - ifa_ifwithaddr_check((struct sockaddr *)sin) == 0) + ifa_ifwithaddr_check((struct sockaddr *)sin, RT_ALL_FIBS) == 0) return (EADDRNOTAVAIL); } laddr = sin->sin_addr; @@ -1240,7 +1240,8 @@ ia = ifatoia(ifa_ifwithnet(sintosa(&dst), 0, inp->inp_socket->so_fibnum)); if (ia == NULL) - ia = ifatoia(ifa_ifwithaddr(sintosa(&dst))); + ia = ifatoia(ifa_ifwithaddr(sintosa(&dst), + inp->inp_socket->so_fibnum)); if (cred == NULL || !prison_flag(cred, PR_IP4)) { if (ia == NULL) { Index: sys/netinet/ip_divert.c =================================================================== --- sys/netinet/ip_divert.c +++ sys/netinet/ip_divert.c @@ -522,7 +522,7 @@ /* XXX: broken for IPv6 */ bzero(sin->sin_zero, sizeof(sin->sin_zero)); sin->sin_port = 0; - ifa = ifa_ifwithaddr((struct sockaddr *) sin); + ifa = ifa_ifwithaddr((struct sockaddr *) sin, RT_ALL_FIBS); if (ifa == NULL) return (EADDRNOTAVAIL); m->m_pkthdr.rcvif = ifa->ifa_ifp; Index: sys/netinet/ip_icmp.c =================================================================== --- sys/netinet/ip_icmp.c +++ sys/netinet/ip_icmp.c @@ -955,8 +955,7 @@ if ((ifa = ifa_ifwithnet((struct sockaddr *)gateway, 0, fibnum))==NULL) return (ENETUNREACH); - /* TODO: fib-aware. */ - if (ifa_ifwithaddr_check((struct sockaddr *)gateway)) + if (ifa_ifwithaddr_check((struct sockaddr *)gateway, fibnum)) return (EHOSTUNREACH); nh = fib4_lookup(fibnum, dst->sin_addr, 0, NHR_NONE, 0); Index: sys/netinet/ip_mroute.c =================================================================== --- sys/netinet/ip_mroute.c +++ sys/netinet/ip_mroute.c @@ -880,7 +880,7 @@ ifp = NULL; } else { sin.sin_addr = vifcp->vifc_lcl_addr; - ifa = ifa_ifwithaddr((struct sockaddr *)&sin); + ifa = ifa_ifwithaddr((struct sockaddr *)&sin, RT_ALL_FIBS); if (ifa == NULL) { VIF_UNLOCK(); return EADDRNOTAVAIL; Index: sys/netinet/ip_options.c =================================================================== --- sys/netinet/ip_options.c +++ sys/netinet/ip_options.c @@ -169,7 +169,7 @@ goto bad; } ipaddr.sin_addr = ip->ip_dst; - if (ifa_ifwithaddr_check((struct sockaddr *)&ipaddr) + if (ifa_ifwithaddr_check((struct sockaddr *)&ipaddr, RT_ALL_FIBS) == 0) { if (opt == IPOPT_SSRR) { type = ICMP_UNREACH; @@ -296,7 +296,7 @@ * destination, use the incoming interface (should be * same). */ - if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr)) != NULL) { + if ((ia = (INA)ifa_ifwithaddr((SA)&ipaddr, RT_ALL_FIBS)) != NULL) { memcpy(cp + off, &(IA_SIN(ia)->sin_addr), sizeof(struct in_addr)); } else if (fib4_lookup_nh_ext(M_GETFIB(m), @@ -365,7 +365,7 @@ } (void)memcpy(&ipaddr.sin_addr, sin, sizeof(struct in_addr)); - if (ifa_ifwithaddr_check((SA)&ipaddr) == 0) + if (ifa_ifwithaddr_check((SA)&ipaddr, RT_ALL_FIBS) == 0) continue; cp[IPOPT_OFFSET] += sizeof(struct in_addr); off += sizeof(struct in_addr); Index: sys/netinet/raw_ip.c =================================================================== --- sys/netinet/raw_ip.c +++ sys/netinet/raw_ip.c @@ -985,7 +985,7 @@ (addr->sin_family != AF_INET && addr->sin_family != AF_IMPLINK) || (addr->sin_addr.s_addr && (inp->inp_flags & INP_BINDANY) == 0 && - ifa_ifwithaddr_check((struct sockaddr *)addr) == 0)) + ifa_ifwithaddr_check((struct sockaddr *)addr, RT_ALL_FIBS) == 0)) return (EADDRNOTAVAIL); INP_INFO_WLOCK(&V_ripcbinfo); Index: sys/netinet6/in6_pcb.c =================================================================== --- sys/netinet6/in6_pcb.c +++ sys/netinet6/in6_pcb.c @@ -184,8 +184,8 @@ sin6->sin6_port = 0; /* yech... */ NET_EPOCH_ENTER(et); - if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6)) == - NULL && + if ((ifa = ifa_ifwithaddr((struct sockaddr *)sin6, + RT_ALL_FIBS)) == NULL && (inp->inp_flags & INP_BINDANY) == 0) { NET_EPOCH_EXIT(et); return (EADDRNOTAVAIL); Index: sys/netinet6/raw_ip6.c =================================================================== --- sys/netinet6/raw_ip6.c +++ sys/netinet6/raw_ip6.c @@ -756,7 +756,7 @@ NET_EPOCH_ENTER(et); if (!IN6_IS_ADDR_UNSPECIFIED(&addr->sin6_addr) && - (ifa = ifa_ifwithaddr((struct sockaddr *)addr)) == NULL) { + (ifa = ifa_ifwithaddr((struct sockaddr *)addr, RT_ALL_FIBS)) == NULL) { NET_EPOCH_EXIT(et); return (EADDRNOTAVAIL); }