Re: RFC3442 - The Classless Static Routes



On Mon, 11 Aug 2008 16:20:42 +0300, "Nick Palamarchuk"
<lupinedreamer gmail com> wrote:
> We need to use classless static routes in my network. But a lot of users
> still using Windows in our network because of hard config of classless
> static routes in Linux. So...
> 
> How about implementing this feature in NM?
> 
> RFC 3442 - The Classless Static Route Option for Dynamic Host
> Configuration
> Protocol (DHCP) version 4:
> http://www.faqs.org/rfcs/rfc3442.html

Attached is a patch to make this happen :)
It requires use of the dhcpcd DHCP client (svn NM required + ./configure
--with-dhcp-client=dhcpcd)
Although it's possible with the stock ISC dhclient, NM would have to decode
and assemble the information from a byte string which would be very nasty.

Thanks

Roy
Index: src/dhcp-manager/nm-dhcp-manager.c
===================================================================
--- src/dhcp-manager/nm-dhcp-manager.c	(revision 3922)
+++ src/dhcp-manager/nm-dhcp-manager.c	(working copy)
@@ -746,21 +746,122 @@
 		nm_info ("  prefix %d (%s)", addr->prefix, str);
 	}
 
-	str = g_hash_table_lookup (device->options, "new_routers");
+	/* Classless static routes over-ride any static routes and routers
+	 * provided. We should also check for MS classless static routes as
+	 * they implemented the draft RFC using their own code :/ */
+	str = g_hash_table_lookup (device->options, "new_classless_static_routes");
+	if (!str)
+		str = g_hash_table_lookup (device->options, "new_ms_classless_static_routes");
 	if (str) {
-		char **routers = g_strsplit (str, " ", 0);
-		char **s;
+		char **routes = g_strsplit (str, " ", 0);
 
-		for (s = routers; *s; s++) {
-			/* FIXME: how to handle multiple routers? */
-			if (inet_pton (AF_INET, *s, &tmp_addr) > 0) {
-				addr->gateway = tmp_addr.s_addr;
-				nm_info ("  gateway %s", *s);
-				break;
-			} else
-				nm_warning ("Ignoring invalid gateway '%s'", *s);
+		routes = g_strsplit (str, " ", 0);
+		if ((g_strv_length (routes) %2) == 0) {
+			char **r;
+
+			for (r = routes; *r; r += 2) {
+				char *slash;
+				NMSettingIP4Route *route;
+				int rt_cidr = 32;
+				struct in_addr rt_addr;
+				struct in_addr rt_route;
+
+				slash = strchr(*r, '/');
+				if (slash) {
+					*slash = '\0';
+					errno = 0;
+					rt_cidr = strtol (slash + 1, NULL, 10);
+					if ((errno == EINVAL) || (errno == ERANGE)) {
+						nm_warning ("DHCP provided invalid classless static route cidr: '%s'", slash + 1);
+						continue;
+					}
+				}
+				if (inet_pton (AF_INET, *r, &rt_addr) <= 0) {
+					nm_warning ("DHCP provided invalid classless static route address: '%s'", *r);
+					continue;
+				}
+				if (inet_pton (AF_INET, *(r + 1), &rt_route) <= 0) {
+					nm_warning ("DHCP provided invalid classless static route gateway: '%s'", *(r + 1));
+					continue;
+				}
+
+				if (rt_cidr == 0 && rt_addr.s_addr == 0) {
+					/* FIXME: how to handle multiple routers? */
+					if (!addr->gateway) {
+						addr->gateway = rt_route.s_addr;
+						nm_info ("  gateway %s", *(r + 1));
+					}
+				} else {
+					route = g_malloc0 (sizeof (NMSettingIP4Route));
+					route->address = (guint32) rt_addr.s_addr;
+					route->prefix = rt_cidr;
+					route->next_hop = (guint32) rt_route.s_addr;
+
+					nm_ip4_config_take_route (ip4_config, route);
+					nm_info ("  classless static route %s/%d gw %s", *r, rt_cidr, *(r + 1));
+				}
+			}
+		} else {
+			nm_info ("  classless tatic routes provided, but invalid");
 		}
-		g_strfreev (routers);
+		g_strfreev (routes);
+	} else {
+		str = g_hash_table_lookup (device->options, "new_static_routes");
+		if (str) {
+			char **searches = g_strsplit (str, " ", 0);
+
+			nm_info ("in rout");
+			if ((g_strv_length (searches) % 2) == 0) {
+				char **s;
+
+				for (s = searches; *s; s += 2) {
+					NMSettingIP4Route *route;
+					struct in_addr rt_addr;
+					struct in_addr rt_route;
+
+					if (inet_pton (AF_INET, *s, &rt_addr) <= 0) {
+						nm_warning ("DHCP provided invalid static route address: '%s'", *s);
+						continue;
+					}
+					if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) {
+						nm_warning ("DHCP provided invalid static route gateway: '%s'", *(s + 1));
+						continue;
+					}
+
+					// FIXME: ensure the IP addresse and route are sane
+
+					route = g_malloc0 (sizeof (NMSettingIP4Route));
+					route->address = (guint32) rt_addr.s_addr;
+					route->prefix = 32; /* 255.255.255.255 */
+					route->next_hop = (guint32) rt_route.s_addr;
+
+					nm_ip4_config_take_route (ip4_config, route);
+					nm_info ("  static route %s gw %s", *s, *(s + 1));
+				}
+			} else {
+				nm_info ("  static routes provided, but invalid");
+			}
+			g_strfreev (searches);
+		}
+
+		str = g_hash_table_lookup (device->options, "new_routers");
+		if (str) {
+			char **routers = g_strsplit (str, " ", 0);
+			char **s;
+
+			for (s = routers; *s; s++) {
+				/* FIXME: how to handle multiple routers? */
+				if (inet_pton (AF_INET, *s, &tmp_addr) > 0) {
+					addr->gateway = tmp_addr.s_addr;
+					nm_info ("  gateway %s", *s);
+					break;
+				} else {
+					nm_info ("foo");
+					nm_warning ("Ignoring invalid gateway '%s'", *s);
+				}
+			}
+			g_strfreev (routers);
+		}
 	}
 
 	nm_ip4_config_take_address (ip4_config, addr);
@@ -811,43 +912,6 @@
 		g_strfreev (searches);
 	}
 
-	str = g_hash_table_lookup (device->options, "new_static_routes");
-	if (str) {
-		char **searches = g_strsplit (str, " ", 0);
-
-		if ((g_strv_length (searches) % 2) == 0) {
-			char **s;
-
-			for (s = searches; *s; s += 2) {
-				NMSettingIP4Route *route;
-				struct in_addr rt_addr;
-				struct in_addr rt_route;
-
-				if (inet_pton (AF_INET, *s, &rt_addr) <= 0) {
-					nm_warning ("DHCP provided invalid static route address: '%s'", *s);
-					continue;
-				}
-				if (inet_pton (AF_INET, *(s + 1), &rt_route) <= 0) {
-					nm_warning ("DHCP provided invalid static route gateway: '%s'", *(s + 1));
-					continue;
-				}
-
-				// FIXME: ensure the IP addresse and route are sane
-
-				route = g_malloc0 (sizeof (NMSettingIP4Route));
-				route->address = (guint32) rt_addr.s_addr;
-				route->prefix = 32; /* 255.255.255.255 */
-				route->next_hop = (guint32) rt_route.s_addr;
-
-				nm_ip4_config_take_route (ip4_config, route);
-				nm_info ("  static route %s gw %s", *s, *(s + 1));
-			}
-		} else {
-			nm_info ("  static routes provided, but invalid");
-		}
-		g_strfreev (searches);
-	}
-
 	str = g_hash_table_lookup (device->options, "new_interface_mtu");
 	if (str) {
 		int int_mtu;


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]