From 31fe84e467732463eabc8f70c2a419008e7a227c Mon Sep 17 00:00:00 2001 From: Scott Shambarger Date: Thu, 9 Jan 2014 14:26:53 -0800 Subject: [PATCH] core: Add host route for DHCP4 server if outside assigned subnet (bgo #721767) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Some ISP's provide leases from central servers that are on different subnets that the address offered. If the host does not configure the interface as the default route, the dhcp server may not be reachable via unicast, and a host specific route is needed. https://bugzilla.gnome.org/show_bug.cgi?id=721767 https://bugzilla.redhat.com/show_bug.cgi?id=983325 Signed-off-by: Thomas Haller Signed-off-by: Jiří Klimeš --- src/dhcp-manager/nm-dhcp-client.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index edea8f8..75cd818 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -1200,8 +1200,8 @@ ip4_options_to_config (NMDHCPClient *self) for (s = routers; *s; s++) { /* FIXME: how to handle multiple routers? */ - if (inet_pton (AF_INET, *s, &tmp_addr) > 0) { - nm_ip4_config_set_gateway (ip4_config, tmp_addr); + if (inet_pton (AF_INET, *s, &gwaddr) > 0) { + nm_ip4_config_set_gateway (ip4_config, gwaddr); nm_log_info (LOGD_DHCP4, " gateway %s", *s); break; } else @@ -1211,6 +1211,41 @@ ip4_options_to_config (NMDHCPClient *self) } } + /* + * RFC 2132, section 9.7 + * DHCP clients use the contents of the 'server identifier' field + * as the destination address for any DHCP messages unicast to + * the DHCP server. + * + * Some ISP's provide leases from central servers that are on + * different subnets that the address offered. If the host + * does not configure the interface as the default route, the + * dhcp server may not be reachable via unicast, and a host + * specific route is needed. + **/ + str = g_hash_table_lookup (priv->options, "new_dhcp_server_identifier"); + if (str) { + if (inet_pton (AF_INET, str, &tmp_addr) > 0) { + NMPlatformIP4Route route; + guint32 mask = nm_utils_ip4_prefix_to_netmask (address.plen); + + nm_log_info (LOGD_DHCP4, " server identifier %s", str); + if ((tmp_addr & mask) != (address.address & mask)) { + /* DHCP server not on assigned subnet, route needed */ + memset (&route, 0, sizeof (route)); + route.network = tmp_addr; + route.plen = 32; + /* this will be a device route if gwaddr is 0 */ + route.gateway = gwaddr; + nm_ip4_config_add_route (ip4_config, &route); + nm_log_dbg (LOGD_IP, "adding route for server identifier: %s", + nm_platform_ip4_route_to_string (&route)); + } + } + else + nm_log_warn (LOGD_DHCP4, "ignoring invalid server identifier '%s'", str); + } + str = g_hash_table_lookup (priv->options, "new_dhcp_lease_time"); if (str) { address.lifetime = address.preferred = strtoul (str, NULL, 10); -- 1.7.11.7