summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2016-02-15 11:28:58 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2016-02-16 00:08:15 +0100
commit0f5c5ad44692d029eec60cdc7d8783b51ede59bb (patch)
tree42857ccf64878190a5a3c49921000bafe83dc9a2
parentdec3a7e58d00bcc8b95a5b02a8c55d2da7a0b2ee (diff)
downloadNetworkManager-0f5c5ad44692d029eec60cdc7d8783b51ede59bb.tar.gz
dhcp/systemd: accept default gateway in classless static routes option
RFC 3442 allows a default gateway to be specified in option 121 (Classless Static Routes) and override the Router option. Implement this in the internal DHCP client. https://bugzilla.gnome.org/show_bug.cgi?id=761268
-rw-r--r--src/dhcp-manager/nm-dhcp-systemd.c58
1 files changed, 39 insertions, 19 deletions
diff --git a/src/dhcp-manager/nm-dhcp-systemd.c b/src/dhcp-manager/nm-dhcp-systemd.c
index 3a40225861..3a6de91b2d 100644
--- a/src/dhcp-manager/nm-dhcp-systemd.c
+++ b/src/dhcp-manager/nm-dhcp-systemd.c
@@ -218,6 +218,7 @@ lease_to_ip4_config (const char *iface,
const void *data;
gsize data_len;
gboolean metered = FALSE;
+ gboolean static_default_gateway = FALSE;
g_return_val_if_fail (lease != NULL, NULL);
@@ -255,15 +256,6 @@ lease_to_ip4_config (const char *iface,
address.source = NM_IP_CONFIG_SOURCE_DHCP;
nm_ip4_config_add_address (ip4_config, &address);
- /* Gateway */
- r = sd_dhcp_lease_get_router (lease, &tmp_addr);
- if (r == 0) {
- nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr);
- str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL);
- LOG_LEASE (LOGD_DHCP4, " gateway %s", str);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, str);
- }
-
/* DNS Servers */
num = sd_dhcp_lease_get_dns (lease, &addr_list);
if (num > 0) {
@@ -325,20 +317,48 @@ lease_to_ip4_config (const char *iface,
continue;
route.gateway = a.s_addr;
- route.source = NM_IP_CONFIG_SOURCE_DHCP;
- route.metric = default_priority;
- nm_ip4_config_add_route (ip4_config, &route);
-
- str = nm_utils_inet4_ntop (route.network, buf);
- gw_str = nm_utils_inet4_ntop (route.gateway, NULL);
- LOG_LEASE (LOGD_DHCP4, " static route %s/%d gw %s", str, route.plen, gw_str);
-
- g_string_append_printf (l, "%s%s/%d %s", l->len ? " " : "", str, route.plen, gw_str);
+ if (route.plen) {
+ route.source = NM_IP_CONFIG_SOURCE_DHCP;
+ route.metric = default_priority;
+ nm_ip4_config_add_route (ip4_config, &route);
+
+ str = nm_utils_inet4_ntop (route.network, buf);
+ gw_str = nm_utils_inet4_ntop (route.gateway, NULL);
+ LOG_LEASE (LOGD_DHCP4, " static route %s/%d gw %s", str, route.plen, gw_str);
+
+ g_string_append_printf (l, "%s%s/%d %s", l->len ? " " : "", str, route.plen, gw_str);
+ } else {
+ if (!static_default_gateway) {
+ static_default_gateway = TRUE;
+ nm_ip4_config_set_gateway (ip4_config, route.gateway);
+
+ str = nm_utils_inet4_ntop (route.gateway, NULL);
+ LOG_LEASE (LOGD_DHCP4, " gateway %s", str);
+ add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, str);
+ }
+ }
}
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, l->str);
+ if (l->len)
+ add_option (options, dhcp4_requests, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, l->str);
g_string_free (l, TRUE);
}
+ /* If the DHCP server returns both a Classless Static Routes option and a
+ * Router option, the DHCP client MUST ignore the Router option [RFC 3442].
+ * Be more lenient and ignore the Router option only if Classless Static
+ * Routes contain a default gateway (as other DHCP backends do).
+ */
+ /* Gateway */
+ if (!static_default_gateway) {
+ r = sd_dhcp_lease_get_router (lease, &tmp_addr);
+ if (r == 0) {
+ nm_ip4_config_set_gateway (ip4_config, tmp_addr.s_addr);
+ str = nm_utils_inet4_ntop (tmp_addr.s_addr, NULL);
+ LOG_LEASE (LOGD_DHCP4, " gateway %s", str);
+ add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, str);
+ }
+ }
+
/* MTU */
r = sd_dhcp_lease_get_mtu (lease, &mtu);
if (r == 0 && mtu) {