From e034e82c56ef32db77eb6baeda78b78400a89709 Mon Sep 17 00:00:00 2001 From: Qing Li Date: Tue, 16 May 2006 19:11:11 +0000 Subject: [PATCH] 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 --- sys/net/route.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/sys/net/route.c b/sys/net/route.c index ebfc640ff32..0e1085a9b28 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); }