summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2017-05-09 15:32:09 +0200
committerBeniamino Galvani <bgalvani@redhat.com>2017-05-09 15:48:10 +0200
commitb784360eff27aa71e1cd1180d9699cd295788a3d (patch)
tree5bd442f6ce838333b0675b5a4063d1ddc5e3da72
parentc8dbe90f428fbc58b22f1d86b29d63e565d2ed91 (diff)
downloadNetworkManager-bg/dhcp-server-route-rh1448987.tar.gz
-rw-r--r--src/devices/nm-device.c3
-rw-r--r--src/dhcp/nm-dhcp-client.c16
-rw-r--r--src/dhcp/nm-dhcp-client.h1
-rw-r--r--src/dhcp/nm-dhcp-manager.c11
-rw-r--r--src/dhcp/nm-dhcp-manager.h3
-rw-r--r--src/dhcp/nm-dhcp-utils.c25
-rw-r--r--src/dhcp/nm-dhcp-utils.h1
-rw-r--r--src/dhcp/tests/test-dhcp-utils.c36
-rw-r--r--src/nm-iface-helper.c3
9 files changed, 71 insertions, 28 deletions
diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c
index d105082f64..0aa4ce3beb 100644
--- a/src/devices/nm-device.c
+++ b/src/devices/nm-device.c
@@ -5829,7 +5829,8 @@ dhcp4_start (NMDevice *self,
nm_setting_ip4_config_get_dhcp_client_id (NM_SETTING_IP4_CONFIG (s_ip4)),
dhcp4_get_timeout (self, NM_SETTING_IP4_CONFIG (s_ip4)),
priv->dhcp_anycast_address,
- NULL);
+ NULL,
+ nm_setting_ip_config_get_never_default (s_ip4));
if (tmp)
g_byte_array_free (tmp, TRUE);
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index 0906f5beba..3830ce34e0 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -55,6 +55,7 @@ NM_GOBJECT_PROPERTIES_DEFINE_BASE (
PROP_UUID,
PROP_PRIORITY,
PROP_TIMEOUT,
+ PROP_NEVER_DEFAULT,
);
typedef struct _NMDhcpClientPrivate {
@@ -69,6 +70,7 @@ typedef struct _NMDhcpClientPrivate {
GBytes * client_id;
char * hostname;
gboolean use_fqdn;
+ gboolean never_default;
NMDhcpState state;
pid_t pid;
@@ -774,6 +776,7 @@ nm_dhcp_client_handle_event (gpointer unused,
ip_config = (GObject *) nm_dhcp_utils_ip4_config_from_options (priv->ifindex,
priv->iface,
str_options,
+ priv->never_default,
priv->priority);
}
}
@@ -834,6 +837,9 @@ get_property (GObject *object, guint prop_id,
case PROP_TIMEOUT:
g_value_set_uint (value, priv->timeout);
break;
+ case PROP_NEVER_DEFAULT:
+ g_value_set_boolean (value, priv->never_default);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -875,6 +881,10 @@ set_property (GObject *object, guint prop_id,
case PROP_TIMEOUT:
priv->timeout = g_value_get_uint (value);
break;
+ case PROP_NEVER_DEFAULT:
+ /* construct-only */
+ priv->never_default = g_value_get_boolean (value);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -982,6 +992,12 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class)
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
G_PARAM_STATIC_STRINGS);
+ obj_properties[PROP_NEVER_DEFAULT] =
+ g_param_spec_boolean (NM_DHCP_CLIENT_NEVER_DEFAULT, "", "",
+ FALSE,
+ G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
+ G_PARAM_STATIC_STRINGS);
+
g_object_class_install_properties (object_class, _PROPERTY_ENUMS_LAST, obj_properties);
signals[SIGNAL_STATE_CHANGED] =
diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h
index e41a59a265..33f10e8c1f 100644
--- a/src/dhcp/nm-dhcp-client.h
+++ b/src/dhcp/nm-dhcp-client.h
@@ -38,6 +38,7 @@
#define NM_DHCP_CLIENT_UUID "uuid"
#define NM_DHCP_CLIENT_PRIORITY "priority"
#define NM_DHCP_CLIENT_TIMEOUT "timeout"
+#define NM_DHCP_CLIENT_NEVER_DEFAULT "never-default"
#define NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED "state-changed"
#define NM_DHCP_CLIENT_SIGNAL_PREFIX_DELEGATED "prefix-delegated"
diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c
index fff9f9ec30..7efd793059 100644
--- a/src/dhcp/nm-dhcp-manager.c
+++ b/src/dhcp/nm-dhcp-manager.c
@@ -167,7 +167,8 @@ client_start (NMDhcpManager *self,
gboolean info_only,
NMSettingIP6ConfigPrivacy privacy,
const char *last_ip4_address,
- guint needed_prefixes)
+ guint needed_prefixes,
+ gboolean never_default)
{
NMDhcpManagerPrivate *priv;
NMDhcpClient *client;
@@ -202,6 +203,7 @@ client_start (NMDhcpManager *self,
NM_DHCP_CLIENT_UUID, uuid,
NM_DHCP_CLIENT_PRIORITY, priority,
NM_DHCP_CLIENT_TIMEOUT, timeout ? timeout : DHCP_TIMEOUT,
+ NM_DHCP_CLIENT_NEVER_DEFAULT, never_default,
NULL);
g_hash_table_insert (NM_DHCP_MANAGER_GET_PRIVATE (self)->clients, client, g_object_ref (client));
g_signal_connect (client, NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED, G_CALLBACK (client_state_changed), self);
@@ -233,7 +235,8 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr,
- const char *last_ip_address)
+ const char *last_ip_address,
+ gboolean never_default)
{
NMDhcpManagerPrivate *priv;
const char *hostname = NULL;
@@ -269,7 +272,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self,
return client_start (self, iface, ifindex, hwaddr, uuid, priority, FALSE, NULL,
dhcp_client_id, timeout, dhcp_anycast_addr, hostname,
- use_fqdn, FALSE, 0, last_ip_address, 0);
+ use_fqdn, FALSE, 0, last_ip_address, 0, never_default);
}
/* Caller owns a reference to the NMDhcpClient on return */
@@ -301,7 +304,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self,
}
return client_start (self, iface, ifindex, hwaddr, uuid, priority, TRUE,
ll_addr, NULL, timeout, dhcp_anycast_addr, hostname, TRUE, info_only,
- privacy, NULL, needed_prefixes);
+ privacy, NULL, needed_prefixes, FALSE);
}
void
diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h
index 66fdd145db..c6e5c3beff 100644
--- a/src/dhcp/nm-dhcp-manager.h
+++ b/src/dhcp/nm-dhcp-manager.h
@@ -57,7 +57,8 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager,
const char *dhcp_client_id,
guint32 timeout,
const char *dhcp_anycast_addr,
- const char *last_ip_address);
+ const char *last_ip_address,
+ gboolean never_default);
NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager,
const char *iface,
diff --git a/src/dhcp/nm-dhcp-utils.c b/src/dhcp/nm-dhcp-utils.c
index 9d644f6d2e..8807fbbd7c 100644
--- a/src/dhcp/nm-dhcp-utils.c
+++ b/src/dhcp/nm-dhcp-utils.c
@@ -386,6 +386,7 @@ NMIP4Config *
nm_dhcp_utils_ip4_config_from_options (int ifindex,
const char *iface,
GHashTable *options,
+ gboolean never_default,
guint32 priority)
{
NMIP4Config *ip4_config = NULL;
@@ -465,11 +466,29 @@ nm_dhcp_utils_ip4_config_from_options (int ifindex,
str = g_hash_table_lookup (options, "dhcp_server_identifier");
if (str) {
if (inet_pton (AF_INET, str, &tmp_addr) > 0) {
+ gboolean add_route = FALSE;
_LOG2I (LOGD_DHCP4, iface, " server identifier %s", str);
- if ( nm_utils_ip4_address_clear_host_address(tmp_addr, address.plen) != nm_utils_ip4_address_clear_host_address(address.address, address.plen)
- && !nm_ip4_config_get_route_for_host (ip4_config, tmp_addr, TRUE)) {
- /* DHCP server not on assigned subnet and the no direct route was returned. Add route */
+
+ if (nm_utils_ip4_address_clear_host_address (tmp_addr, address.plen) ==
+ nm_utils_ip4_address_clear_host_address (address.address, address.plen)) {
+ /* directly reachable, nothing to do */
+ } else if (gwaddr) {
+ if (never_default) {
+ /* we reach the server through a default route, but
+ * never-default is set and thus the route won't be
+ * installed
+ */
+ add_route = TRUE;
+ }
+ } else if (nm_ip4_config_get_route_for_host (ip4_config, tmp_addr, FALSE)) {
+ /* indirectly reachable, nothing to do */
+ } else {
+ /* no route to server, add a direct one */
+ add_route = TRUE;
+ }
+
+ if (add_route) {
NMPlatformIP4Route route = { 0 };
route.network = tmp_addr;
diff --git a/src/dhcp/nm-dhcp-utils.h b/src/dhcp/nm-dhcp-utils.h
index 05982b166d..69471b1c7d 100644
--- a/src/dhcp/nm-dhcp-utils.h
+++ b/src/dhcp/nm-dhcp-utils.h
@@ -27,6 +27,7 @@
NMIP4Config *nm_dhcp_utils_ip4_config_from_options (int ifindex,
const char *iface,
GHashTable *options,
+ gboolean never_default,
guint priority);
NMIP6Config *nm_dhcp_utils_ip6_config_from_options (int ifindex,
diff --git a/src/dhcp/tests/test-dhcp-utils.c b/src/dhcp/tests/test-dhcp-utils.c
index ffd6349361..ef1e12cc67 100644
--- a/src/dhcp/tests/test-dhcp-utils.c
+++ b/src/dhcp/tests/test-dhcp-utils.c
@@ -86,7 +86,7 @@ test_generic_options (void)
const char *expected_route2_gw = "10.1.1.1";
options = fill_table (generic_options, NULL);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 address */
@@ -157,7 +157,7 @@ test_wins_options (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 address */
@@ -184,7 +184,7 @@ test_vendor_option_metered (void)
};
options = fill_table (generic_options, NULL);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_assert (nm_ip4_config_get_metered (ip4_config) == FALSE);
g_hash_table_destroy (options);
@@ -192,7 +192,7 @@ test_vendor_option_metered (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_assert (nm_ip4_config_get_metered (ip4_config) == TRUE);
g_hash_table_destroy (options);
@@ -246,7 +246,7 @@ test_classless_static_routes_1 (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 routes */
@@ -274,7 +274,7 @@ test_classless_static_routes_2 (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 routes */
@@ -303,7 +303,7 @@ test_fedora_dhclient_classless_static_routes (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 routes */
@@ -335,7 +335,7 @@ test_dhclient_invalid_classless_routes_1 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -366,7 +366,7 @@ test_dhcpcd_invalid_classless_routes_1 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -399,7 +399,7 @@ test_dhclient_invalid_classless_routes_2 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -432,7 +432,7 @@ test_dhcpcd_invalid_classless_routes_2 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -465,7 +465,7 @@ test_dhclient_invalid_classless_routes_3 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*ignoring invalid classless static routes*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -493,7 +493,7 @@ test_dhcpcd_invalid_classless_routes_3 (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*DHCP provided invalid classless static route*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -547,7 +547,7 @@ test_dhcpcd_gw_in_classless_routes (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* IP4 routes */
@@ -575,7 +575,7 @@ test_escaped_domain_searches (void)
options = fill_table (generic_options, NULL);
options = fill_table (data, options);
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
/* domain searches */
@@ -602,7 +602,7 @@ test_invalid_escaped_domain_searches (void)
g_test_expect_message ("NetworkManager", G_LOG_LEVEL_MESSAGE,
"*invalid domain search*");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_test_assert_expected_messages ();
@@ -623,7 +623,7 @@ test_ip4_missing_prefix (const char *ip, guint32 expected_prefix)
g_hash_table_insert (options, "ip_address", (gpointer) ip);
g_hash_table_remove (options, "subnet_mask");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
@@ -668,7 +668,7 @@ test_ip4_prefix_classless (void)
g_hash_table_insert (options, "ip_address", "172.16.54.22");
g_hash_table_insert (options, "subnet_mask", "255.255.252.0");
- ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, 0);
+ ip4_config = nm_dhcp_utils_ip4_config_from_options (1, "eth0", options, FALSE, 0);
g_assert (ip4_config);
g_assert_cmpint (nm_ip4_config_get_num_addresses (ip4_config), ==, 1);
diff --git a/src/nm-iface-helper.c b/src/nm-iface-helper.c
index f8df2b9a7f..4ba777e222 100644
--- a/src/nm-iface-helper.c
+++ b/src/nm-iface-helper.c
@@ -480,7 +480,8 @@ main (int argc, char *argv[])
global_opt.dhcp4_clientid,
45,
NULL,
- global_opt.dhcp4_address);
+ global_opt.dhcp4_address,
+ FALSE);
g_assert (dhcp4_client);
g_signal_connect (dhcp4_client,
NM_DHCP_CLIENT_SIGNAL_STATE_CHANGED,