Index: share/man/man9/ifnet.9 =================================================================== --- share/man/man9/ifnet.9 +++ share/man/man9/ifnet.9 @@ -77,9 +77,9 @@ .Ft "struct ifaddr *" .Fn ifa_ifwithaddr "struct sockaddr *addr" .Ft "struct ifaddr *" -.Fn ifa_ifwithdstaddr "struct sockaddr *addr" +.Fn ifa_ifwithdstaddr "struct sockaddr *addr" "int fib" .Ft "struct ifaddr *" -.Fn ifa_ifwithnet "struct sockaddr *addr" "int ignore_ptp" +.Fn ifa_ifwithnet "struct sockaddr *addr" "int ignore_ptp" "int fib" .Ft "struct ifaddr *" .Fn ifaof_ifpforaddr "struct sockaddr *addr" "struct ifnet *ifp" .Ft void @@ -1393,7 +1393,14 @@ remote .Pq Dq destination address is -.Fa addr . +.Fa addr +and a fib is +.Fa fib . +If +.Fa fib +is RT_ALL_FIBS, then the first interface address matching +.Fa addr +will be returned. .Pp .Fn ifa_ifwithnet returns the most specific interface address which matches the @@ -1405,7 +1412,10 @@ if one is found. If .Fa ignore_ptp -is true, skip point-to-point interface addresses. +is true, skip point-to-point interface addresses. The +.Fa fib +parameter is handled the same way as by +.Fn ifa_ifwithdstaddr . .Pp .Fn ifaof_ifpforaddr returns the most specific address configured on interface Index: sys/net/if.c =================================================================== --- sys/net/if.c +++ sys/net/if.c @@ -1620,13 +1620,15 @@ */ /* ARGSUSED */ struct ifaddr * -ifa_ifwithbroadaddr(struct sockaddr *addr) +ifa_ifwithbroadaddr(struct sockaddr *addr, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; IFNET_RLOCK_NOSLEEP(); TAILQ_FOREACH(ifp, &V_ifnet, if_link) { + if ((fibnum != RT_ALL_FIBS) && (ifp->if_fib != fibnum)) + continue; IF_ADDR_RLOCK(ifp); TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) { if (ifa->ifa_addr->sa_family != addr->sa_family) @@ -1653,7 +1655,7 @@ */ /*ARGSUSED*/ struct ifaddr * -ifa_ifwithdstaddr_fib(struct sockaddr *addr, int fibnum) +ifa_ifwithdstaddr(struct sockaddr *addr, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; @@ -1683,19 +1685,12 @@ return (ifa); } -struct ifaddr * -ifa_ifwithdstaddr(struct sockaddr *addr) -{ - - return (ifa_ifwithdstaddr_fib(addr, RT_ALL_FIBS)); -} - /* * Find an interface on a specific network. If many, choice * is most specific found. */ struct ifaddr * -ifa_ifwithnet_fib(struct sockaddr *addr, int ignore_ptp, int fibnum) +ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp, int fibnum) { struct ifnet *ifp; struct ifaddr *ifa; @@ -1806,13 +1801,6 @@ return (ifa); } -struct ifaddr * -ifa_ifwithnet(struct sockaddr *addr, int ignore_ptp) -{ - - return (ifa_ifwithnet_fib(addr, ignore_ptp, RT_ALL_FIBS)); -} - /* * Find an interface address specific to an interface best matching * a given address. Index: sys/net/if_var.h =================================================================== --- sys/net/if_var.h +++ sys/net/if_var.h @@ -500,13 +500,10 @@ struct ifaddr *ifa_ifwithaddr(struct sockaddr *); int ifa_ifwithaddr_check(struct sockaddr *); -struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *); -struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *); -struct ifaddr *ifa_ifwithdstaddr_fib(struct sockaddr *, int); -struct ifaddr *ifa_ifwithnet(struct sockaddr *, int); -struct ifaddr *ifa_ifwithnet_fib(struct sockaddr *, int, int); -struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *); -struct ifaddr *ifa_ifwithroute_fib(int, struct sockaddr *, struct sockaddr *, u_int); +struct ifaddr *ifa_ifwithbroadaddr(struct sockaddr *, int); +struct ifaddr *ifa_ifwithdstaddr(struct sockaddr *, int); +struct ifaddr *ifa_ifwithnet(struct sockaddr *, int, int); +struct ifaddr *ifa_ifwithroute(int, struct sockaddr *, struct sockaddr *, u_int); struct ifaddr *ifaof_ifpforaddr(struct sockaddr *, struct ifnet *); int ifa_preferred(struct ifaddr *, struct ifaddr *); Index: sys/net/route.c =================================================================== --- sys/net/route.c +++ sys/net/route.c @@ -570,7 +570,7 @@ } /* verify the gateway is directly reachable */ - if ((ifa = ifa_ifwithnet_fib(gateway, 0, fibnum)) == NULL) { + if ((ifa = ifa_ifwithnet(gateway, 0, fibnum)) == NULL) { error = ENETUNREACH; goto out; } @@ -700,18 +700,8 @@ #endif /* INET */ } -/* - * For both ifa_ifwithroute() routines, 'ifa' is returned referenced. - */ -struct ifaddr * -ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway) -{ - - return (ifa_ifwithroute_fib(flags, dst, gateway, RT_DEFAULT_FIB)); -} - struct ifaddr * -ifa_ifwithroute_fib(int flags, struct sockaddr *dst, struct sockaddr *gateway, +ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway, u_int fibnum) { struct ifaddr *ifa; @@ -727,7 +717,7 @@ */ ifa = NULL; if (flags & RTF_HOST) - ifa = ifa_ifwithdstaddr_fib(dst, fibnum); + ifa = ifa_ifwithdstaddr(dst, fibnum); if (ifa == NULL) ifa = ifa_ifwithaddr(gateway); } else { @@ -736,10 +726,10 @@ * or host, the gateway may still be on the * other end of a pt to pt link. */ - ifa = ifa_ifwithdstaddr_fib(gateway, fibnum); + ifa = ifa_ifwithdstaddr(gateway, fibnum); } if (ifa == NULL) - ifa = ifa_ifwithnet_fib(gateway, 0, fibnum); + ifa = ifa_ifwithnet(gateway, 0, fibnum); if (ifa == NULL) { struct rtentry *rt = rtalloc1_fib(gateway, 0, RTF_RNH_LOCKED, fibnum); if (rt == NULL) @@ -853,7 +843,7 @@ */ if (info->rti_ifp == NULL && ifpaddr != NULL && ifpaddr->sa_family == AF_LINK && - (ifa = ifa_ifwithnet_fib(ifpaddr, 0, fibnum)) != NULL) { + (ifa = ifa_ifwithnet(ifpaddr, 0, fibnum)) != NULL) { info->rti_ifp = ifa->ifa_ifp; ifa_free(ifa); } @@ -867,10 +857,10 @@ if (sa != NULL && info->rti_ifp != NULL) info->rti_ifa = ifaof_ifpforaddr(sa, info->rti_ifp); else if (dst != NULL && gateway != NULL) - info->rti_ifa = ifa_ifwithroute_fib(flags, dst, gateway, + info->rti_ifa = ifa_ifwithroute(flags, dst, gateway, fibnum); else if (sa != NULL) - info->rti_ifa = ifa_ifwithroute_fib(flags, sa, sa, + info->rti_ifa = ifa_ifwithroute(flags, sa, sa, fibnum); } if ((ifa = info->rti_ifa) != NULL) { Index: sys/net/rtsock.c =================================================================== --- sys/net/rtsock.c +++ sys/net/rtsock.c @@ -752,7 +752,8 @@ rt->rt_ifp->if_type == IFT_PROPVIRTUAL) { struct ifaddr *ifa; - ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1); + ifa = ifa_ifwithnet(info.rti_info[RTAX_DST], 1, + RT_ALL_FIBS); if (ifa != NULL) rt_maskedcopy(ifa->ifa_addr, &laddr, Index: sys/netinet/in_pcb.c =================================================================== --- sys/netinet/in_pcb.c +++ sys/netinet/in_pcb.c @@ -789,9 +789,11 @@ struct in_ifaddr *ia; struct ifnet *ifp; - ia = ifatoia(ifa_ifwithdstaddr((struct sockaddr *)sin)); + ia = ifatoia(ifa_ifwithdstaddr((struct sockaddr *)sin, + RT_ALL_FIBS)); if (ia == NULL) - ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin, 0)); + ia = ifatoia(ifa_ifwithnet((struct sockaddr *)sin, 0, + RT_ALL_FIBS)); if (ia == NULL) { error = ENETUNREACH; goto done; @@ -906,9 +908,10 @@ sain.sin_len = sizeof(struct sockaddr_in); sain.sin_addr.s_addr = faddr->s_addr; - ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain))); + ia = ifatoia(ifa_ifwithdstaddr(sintosa(&sain), RT_ALL_FIBS)); if (ia == NULL) - ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0)); + ia = ifatoia(ifa_ifwithnet(sintosa(&sain), 0, + RT_ALL_FIBS)); if (ia == NULL) ia = ifatoia(ifa_ifwithaddr(sintosa(&sain))); Index: sys/netinet/ip_options.c =================================================================== --- sys/netinet/ip_options.c +++ sys/netinet/ip_options.c @@ -227,8 +227,11 @@ if (opt == IPOPT_SSRR) { #define INA struct in_ifaddr * #define SA struct sockaddr * - if ((ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr)) == NULL) - ia = (INA)ifa_ifwithnet((SA)&ipaddr, 0); + ia = (INA)ifa_ifwithdstaddr((SA)&ipaddr, + RT_ALL_FIBS); + if (ia == NULL) + ia = (INA)ifa_ifwithnet((SA)&ipaddr, 0, + RT_ALL_FIBS); } else /* XXX MRT 0 for routing */ ia = ip_rtaddr(ipaddr.sin_addr, M_GETFIB(m)); Index: sys/netinet/ip_output.c =================================================================== --- sys/netinet/ip_output.c +++ sys/netinet/ip_output.c @@ -234,8 +234,10 @@ * or the destination address of a ptp interface. */ if (flags & IP_SENDONES) { - if ((ia = ifatoia(ifa_ifwithbroadaddr(sintosa(dst)))) == NULL && - (ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL) { + if ((ia = ifatoia(ifa_ifwithbroadaddr(sintosa(dst), + RT_ALL_FIBS))) == NULL && + (ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst), + RT_ALL_FIBS))) == NULL) { IPSTAT_INC(ips_noroute); error = ENETUNREACH; goto bad; @@ -247,8 +249,10 @@ ip->ip_ttl = 1; isbroadcast = 1; } else if (flags & IP_ROUTETOIF) { - if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst)))) == NULL && - (ia = ifatoia(ifa_ifwithnet(sintosa(dst), 0))) == NULL) { + if ((ia = ifatoia(ifa_ifwithdstaddr(sintosa(dst), + RT_ALL_FIBS))) == NULL && + (ia = ifatoia(ifa_ifwithnet(sintosa(dst), 0, + RT_ALL_FIBS))) == NULL) { IPSTAT_INC(ips_noroute); error = ENETUNREACH; goto bad; Index: sys/netinet6/nd6.c =================================================================== --- sys/netinet6/nd6.c +++ sys/netinet6/nd6.c @@ -945,7 +945,7 @@ * If the address is assigned on the node of the other side of * a p2p interface, the address should be a neighbor. */ - dstaddr = ifa_ifwithdstaddr((struct sockaddr *)addr); + dstaddr = ifa_ifwithdstaddr((struct sockaddr *)addr, RT_ALL_FIBS); if (dstaddr != NULL) { if (dstaddr->ifa_ifp == ifp) { ifa_free(dstaddr);