diff options
author | qingli <qingli@FreeBSD.org> | 2006-05-16 19:11:11 +0000 |
---|---|---|
committer | qingli <qingli@FreeBSD.org> | 2006-05-16 19:11:11 +0000 |
commit | 67e449174c4c617dd19d13aa9c7d685e71169149 (patch) | |
tree | 42c4b29aadd6b9379f546347a3cb7b8d74cefb19 /sys/net/route.c | |
parent | b55b40b0db0446e2f96ce1fdbfba93ee0b723777 (diff) | |
download | FreeBSD-src-67e449174c4c617dd19d13aa9c7d685e71169149.zip FreeBSD-src-67e449174c4c617dd19d13aa9c7d685e71169149.tar.gz |
The current routing code allows insertion of indirect routes that have
gateways which are unreachable except through the default router. For
example, assuming there is a default route configured, and inserting
a route
"route add 64.102.54.0/24 60.80.1.1"
is currently allowed even when 60.80.1.1 is only reachable through
the default route. However, an error is thrown when this route is
utilized, say,
"ping 64.102.54.1" will return an error
This type of route insertion should be disallowed becasue:
1) Let's say that somehow our code allowed this packet to flow to
the default router, and the default router knows the next hop is
60.80.1.1, then the question is why bother inserting this route in
the 1st place, just simply use the default route.
2) Since we're not talking about source routing here, the default
router could very well choose a different path than using 60.80.1.1
for the next hop, again it defeats the purpose of adding this route.
Reviewed by: ru, gnn, bz
Approved by: andre
Diffstat (limited to 'sys/net/route.c')
-rw-r--r-- | sys/net/route.c | 19 |
1 files changed, 19 insertions, 0 deletions
diff --git a/sys/net/route.c b/sys/net/route.c index ebfc640..0e1085a 100644 --- a/sys/net/route.c +++ b/sys/net/route.c @@ -435,6 +435,7 @@ struct ifaddr * ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway) { register struct ifaddr *ifa; + int not_found = 0; if ((flags & RTF_GATEWAY) == 0) { /* @@ -463,8 +464,26 @@ ifa_ifwithroute(int flags, struct sockaddr *dst, struct sockaddr *gateway) struct rtentry *rt = rtalloc1(gateway, 0, 0UL); if (rt == NULL) return (NULL); + /* + * dismiss a gateway that is reachable only + * through the default router + */ + switch (gateway->sa_family) { + case AF_INET: + if (satosin(rt_key(rt))->sin_addr.s_addr == INADDR_ANY) + not_found = 1; + break; + case AF_INET6: + if (IN6_IS_ADDR_UNSPECIFIED(&satosin6(rt_key(rt))->sin6_addr)) + not_found = 1; + break; + default: + break; + } RT_REMREF(rt); RT_UNLOCK(rt); + if (not_found) + return (NULL); if ((ifa = rt->rt_ifa) == NULL) return (NULL); } |