From 55d24ba94eb2378895d10350fb106762fbd241d8 Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Mon, 13 Aug 2018 18:37:02 +0200 Subject: [PATCH] dhcp: save root-path in the state file On networked boot we need to somehow communicate this to the early boot machinery. Sadly, no DBus there and we're running in configure-and-quit mode. Abusing the state file for this sounds almost reasonable and is reasonably straightforward thing to do. --- src/devices/nm-device.c | 5 +++++ src/dhcp/nm-dhcp-dhclient-utils.c | 1 + src/dhcp/nm-dhcp-systemd.c | 8 ++++++++ src/dhcp/tests/test-dhcp-dhclient.c | 22 +++++++++++++++++++++- src/nm-config.c | 15 ++++++++++++--- src/nm-config.h | 3 ++- src/nm-manager.c | 9 ++++++++- 7 files changed, 57 insertions(+), 6 deletions(-) diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index 7108a85c6e..437e0faa7d 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -464,6 +464,7 @@ typedef struct _NMDevicePrivate { gulong state_sigid; NMDhcp4Config * config; char * pac_url; + char * root_path; bool was_active; guint grace_id; } dhcp4; @@ -6953,6 +6954,7 @@ dhcp4_cleanup (NMDevice *self, CleanupType cleanup_type, gboolean release) nm_clear_g_source (&priv->dhcp4.grace_id); g_clear_pointer (&priv->dhcp4.pac_url, g_free); + g_clear_pointer (&priv->dhcp4.root_path, g_free); if (priv->dhcp4.client) { /* Stop any ongoing DHCP transaction on this device */ @@ -7326,6 +7328,9 @@ dhcp4_state_changed (NMDhcpClient *client, priv->dhcp4.pac_url = g_strdup (g_hash_table_lookup (options, "wpad")); nm_device_set_proxy_config (self, priv->dhcp4.pac_url); + g_free (priv->dhcp4.root_path); + priv->dhcp4.root_path = g_strdup (g_hash_table_lookup (options, "root_path")); + nm_dhcp4_config_set_options (priv->dhcp4.config, options); _notify (self, PROP_DHCP4_CONFIG); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index d8f8dd98d8..a2c3bfb65d 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -444,6 +444,7 @@ nm_dhcp_dhclient_create_config (const char *interface, add_request (reqs, "static-routes"); add_request (reqs, "wpad"); add_request (reqs, "ntp-servers"); + add_request (reqs, "root-path"); } else { add_hostname6 (new_contents, hostname); add_request (reqs, "dhcp6.name-servers"); diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index b51c6e7b24..c31b9c6174 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -121,6 +121,7 @@ static const ReqOption dhcp4_requests[] = { { SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, REQPREFIX "rfc3442_classless_static_routes", TRUE }, { SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, REQPREFIX "ms_classless_static_routes", TRUE }, { SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, REQPREFIX "wpad", TRUE }, + { SD_DHCP_OPTION_ROOT_PATH, REQPREFIX "root_path", TRUE }, /* Internal values */ { SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, REQPREFIX "expiry", FALSE }, @@ -432,6 +433,13 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx, add_option (options, dhcp4_requests, SD_DHCP_OPTION_NTP_SERVER, str->str); } + /* Root path */ + r = sd_dhcp_lease_get_root_path (lease, &s); + if (r >= 0) { + LOG_LEASE (LOGD_DHCP4, "root path '%s'", s); + add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROOT_PATH, s); + } + r = sd_dhcp_lease_get_vendor_specific (lease, &data, &data_len); if (r >= 0) metered = !!memmem (data, data_len, "ANDROID_METERED", NM_STRLEN ("ANDROID_METERED")); diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 14a1c78634..edac42572d 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -104,6 +104,7 @@ static const char *orig_missing_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -132,6 +133,7 @@ static const char *override_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -161,6 +163,7 @@ static const char *quote_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -190,6 +193,7 @@ static const char *quote_client_id_expected_2 = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -219,6 +223,7 @@ static const char *hex_zero_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -248,6 +253,7 @@ static const char *ascii_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -277,6 +283,7 @@ static const char *hex_single_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -310,6 +317,7 @@ static const char *existing_hex_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -347,6 +355,7 @@ static const char *existing_escaped_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -385,6 +394,7 @@ static const char *existing_ascii_client_id_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -419,7 +429,8 @@ static const char *fqdn_expected = \ "also request ms-classless-static-routes;\n" "also request static-routes;\n" "also request wpad;\n" - "also request ntp-servers;\n\n"; + "also request ntp-servers;\n" + "also request root-path;\n\n"; static void test_fqdn (void) @@ -455,6 +466,7 @@ static const char *fqdn_options_override_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n" "# FQDN options from /path/to/dhclient.conf\n" "send fqdn.encoded off;\n" @@ -492,6 +504,7 @@ static const char *override_hostname_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -580,6 +593,7 @@ static const char *existing_alsoreq_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -618,6 +632,7 @@ static const char *existing_req_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -657,6 +672,7 @@ static const char *existing_multiline_alsoreq_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -890,6 +906,7 @@ static const char *interface1_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -935,6 +952,7 @@ static const char *interface2_expected = \ "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; static void @@ -1030,6 +1048,7 @@ test_structured (void) "also request static-routes;\n" "also request wpad;\n" "also request ntp-servers;\n" + "also request root-path;\n" "\n"; new_client_id = g_bytes_new (bytes, sizeof (bytes) - 1); @@ -1085,6 +1104,7 @@ test_config_req_intf (void) "also request ms-classless-static-routes;\n" "also request static-routes;\n" "also request wpad;\n" + "also request root-path;\n" "\n"; test_config (orig, expected, diff --git a/src/nm-config.c b/src/nm-config.c index fb4e6a66b5..7a6ccd0c0d 100644 --- a/src/nm-config.c +++ b/src/nm-config.c @@ -1931,6 +1931,7 @@ _nm_config_state_set (NMConfig *self, #define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_NM_OWNED "nm-owned" #define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_ASPIRED "route-metric-default-aspired" #define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROUTE_METRIC_DEFAULT_EFFECTIVE "route-metric-default-effective" +#define DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH "root-path" NM_UTILS_LOOKUP_STR_DEFINE_STATIC (_device_state_managed_type_to_str, NMConfigDeviceStateManagedType, NM_UTILS_LOOKUP_DEFAULT_NM_ASSERT ("unknown"), @@ -2128,7 +2129,8 @@ nm_config_device_state_write (int ifindex, const char *connection_uuid, int nm_owned, guint32 route_metric_default_aspired, - guint32 route_metric_default_effective) + guint32 route_metric_default_effective, + const char *root_path) { char path[NM_STRLEN (NM_CONFIG_DEVICE_STATE_DIR) + 60]; GError *local = NULL; @@ -2182,19 +2184,26 @@ nm_config_device_state_write (int ifindex, route_metric_default_aspired); } } + if (root_path) { + g_key_file_set_string (kf, + DEVICE_RUN_STATE_KEYFILE_GROUP_DEVICE, + DEVICE_RUN_STATE_KEYFILE_KEY_DEVICE_ROOT_PATH, + root_path); + } if (!g_key_file_save_to_file (kf, path, &local)) { _LOGW ("device-state: write #%d (%s) failed: %s", ifindex, path, local->message); g_error_free (local); return FALSE; } - _LOGT ("device-state: write #%d (%s); managed=%s%s%s%s%s%s%s, route-metric-default=%"G_GUINT32_FORMAT"-%"G_GUINT32_FORMAT"", + _LOGT ("device-state: write #%d (%s); managed=%s%s%s%s%s%s%s, route-metric-default=%"G_GUINT32_FORMAT"-%"G_GUINT32_FORMAT"%s%s%s", ifindex, path, _device_state_managed_type_to_str (managed), NM_PRINT_FMT_QUOTED (connection_uuid, ", connection-uuid=", connection_uuid, "", ""), NM_PRINT_FMT_QUOTED (perm_hw_addr_fake, ", perm-hw-addr-fake=", perm_hw_addr_fake, "", ""), route_metric_default_aspired, - route_metric_default_effective); + route_metric_default_effective, + NM_PRINT_FMT_QUOTED (root_path, ", root-path=", root_path, "", "")); return TRUE; } diff --git a/src/nm-config.h b/src/nm-config.h index 1b013ff398..d05b4ecf64 100644 --- a/src/nm-config.h +++ b/src/nm-config.h @@ -236,7 +236,8 @@ gboolean nm_config_device_state_write (int ifindex, const char *connection_uuid, int nm_owned, guint32 route_metric_default_aspired, - guint32 route_metric_default_effective); + guint32 route_metric_default_effective, + const char *root_path); void nm_config_device_state_prune_unseen (GHashTable *seen_ifindexes); diff --git a/src/nm-manager.c b/src/nm-manager.c index 4f55276b3e..f3ec61a1ee 100644 --- a/src/nm-manager.c +++ b/src/nm-manager.c @@ -6101,6 +6101,8 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device) guint32 route_metric_default_aspired; guint32 route_metric_default_effective; int nm_owned; + NMDhcp4Config *dhcp4_config; + const char *root_path = NULL; ifindex = nm_device_get_ip_ifindex (device); if (ifindex <= 0) @@ -6135,13 +6137,18 @@ nm_manager_write_device_state (NMManager *self, NMDevice *device) route_metric_default_effective = _device_route_metric_get (self, ifindex, NM_DEVICE_TYPE_UNKNOWN, TRUE, &route_metric_default_aspired); + dhcp4_config = nm_device_get_dhcp4_config (device); + if (dhcp4_config) + root_path = nm_dhcp4_config_get_option (dhcp4_config, "root_path"); + return nm_config_device_state_write (ifindex, managed_type, perm_hw_addr_fake, uuid, nm_owned, route_metric_default_aspired, - route_metric_default_effective); + route_metric_default_effective, + root_path); } void