Changeset View
Changeset View
Standalone View
Standalone View
sys/net/route.c
Show First 20 Lines • Show All 677 Lines • ▼ Show 20 Lines | |||||
#endif /* INET */ | #endif /* INET */ | ||||
} | } | ||||
struct ifaddr * | struct ifaddr * | ||||
ifa_ifwithroute(int flags, const struct sockaddr *dst, struct sockaddr *gateway, | ifa_ifwithroute(int flags, const struct sockaddr *dst, struct sockaddr *gateway, | ||||
u_int fibnum) | u_int fibnum) | ||||
{ | { | ||||
struct ifaddr *ifa; | struct ifaddr *ifa; | ||||
int not_found = 0; | |||||
NET_EPOCH_ASSERT(); | NET_EPOCH_ASSERT(); | ||||
if ((flags & RTF_GATEWAY) == 0) { | if ((flags & RTF_GATEWAY) == 0) { | ||||
/* | /* | ||||
* If we are adding a route to an interface, | * If we are adding a route to an interface, | ||||
* and the interface is a pt to pt link | * and the interface is a pt to pt link | ||||
* we should search for the destination | * we should search for the destination | ||||
* as our clue to the interface. Otherwise | * as our clue to the interface. Otherwise | ||||
Show All 10 Lines | if ((flags & RTF_GATEWAY) == 0) { | ||||
* or host, the gateway may still be on the | * or host, the gateway may still be on the | ||||
* other end of a pt to pt link. | * other end of a pt to pt link. | ||||
*/ | */ | ||||
ifa = ifa_ifwithdstaddr(gateway, fibnum); | ifa = ifa_ifwithdstaddr(gateway, fibnum); | ||||
} | } | ||||
if (ifa == NULL) | if (ifa == NULL) | ||||
ifa = ifa_ifwithnet(gateway, 0, fibnum); | ifa = ifa_ifwithnet(gateway, 0, fibnum); | ||||
if (ifa == NULL) { | if (ifa == NULL) { | ||||
struct rtentry *rt; | struct nhop_object *nh; | ||||
rt = rtalloc1_fib(gateway, 0, flags, fibnum); | nh = rib_lookup(fibnum, gateway, NHR_NONE, 0); | ||||
if (rt == NULL) | |||||
goto out; | |||||
/* | /* | ||||
* dismiss a gateway that is reachable only | * dismiss a gateway that is reachable only | ||||
* through the default router | * through the default router | ||||
*/ | */ | ||||
switch (gateway->sa_family) { | if ((nh == NULL) || (nh->nh_flags & NHF_DEFAULT)) | ||||
case AF_INET: | return (NULL); | ||||
if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY) | ifa = nh->nh_ifa; | ||||
not_found = 1; | |||||
break; | |||||
case AF_INET6: | |||||
if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr)) | |||||
not_found = 1; | |||||
break; | |||||
default: | |||||
break; | |||||
} | } | ||||
if (!not_found && rt->rt_nhop->nh_ifa != NULL) { | |||||
ifa = rt->rt_nhop->nh_ifa; | |||||
} | |||||
RT_REMREF(rt); | |||||
RT_UNLOCK(rt); | |||||
if (not_found || ifa == NULL) | |||||
goto out; | |||||
} | |||||
if (ifa->ifa_addr->sa_family != dst->sa_family) { | if (ifa->ifa_addr->sa_family != dst->sa_family) { | ||||
struct ifaddr *oifa = ifa; | struct ifaddr *oifa = ifa; | ||||
ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); | ifa = ifaof_ifpforaddr(dst, ifa->ifa_ifp); | ||||
if (ifa == NULL) | if (ifa == NULL) | ||||
ifa = oifa; | ifa = oifa; | ||||
} | } | ||||
out: | |||||
return (ifa); | return (ifa); | ||||
} | } | ||||
/* | /* | ||||
* Do appropriate manipulations of a routing tree given | * Do appropriate manipulations of a routing tree given | ||||
* all the bits of info needed | * all the bits of info needed | ||||
*/ | */ | ||||
int | int | ||||
▲ Show 20 Lines • Show All 1,525 Lines • Show Last 20 Lines |