diff options
-rw-r--r-- | src/devices/nm-device.c | 3 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-client.c | 16 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-client.h | 1 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 11 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-manager.h | 3 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-utils.c | 25 | ||||
-rw-r--r-- | src/dhcp/nm-dhcp-utils.h | 1 | ||||
-rw-r--r-- | src/dhcp/tests/test-dhcp-utils.c | 36 | ||||
-rw-r--r-- | src/nm-iface-helper.c | 3 |
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, |