summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorFrancesco Giudici <fgiudici@redhat.com>2019-07-05 17:54:52 +0200
committerFrancesco Giudici <fgiudici@redhat.com>2019-07-05 17:54:52 +0200
commit7d8f20b00e461a5a494c15d649068c66897cae58 (patch)
treec802a778b88dff980fba33a6730ce25950d16dad
parentf3b831aba1b319867e4b118a01a4910a3c28563d (diff)
parentb3a5541111abaee748415b0c859eb259becb4dab (diff)
downloadNetworkManager-7d8f20b00e461a5a494c15d649068c66897cae58.tar.gz
dhcp: merge branch 'fg/dhcp_options2env-rh1663253'
https://bugzilla.redhat.com/show_bug.cgi?id=1663253 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/merge_requests/161
-rw-r--r--Makefile.am4
-rw-r--r--dispatcher/nm-dispatcher-utils.c37
-rw-r--r--src/dhcp/nm-dhcp-client.c50
-rw-r--r--src/dhcp/nm-dhcp-options.c276
-rw-r--r--src/dhcp/nm-dhcp-options.h202
-rw-r--r--src/dhcp/nm-dhcp-systemd.c404
-rw-r--r--src/meson.build1
-rw-r--r--src/systemd/meson.build1
-rw-r--r--src/systemd/nm-sd-utils-dhcp.c54
-rw-r--r--src/systemd/nm-sd-utils-dhcp.h34
10 files changed, 850 insertions, 213 deletions
diff --git a/Makefile.am b/Makefile.am
index 5589f0550d..85bdaefa27 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1836,6 +1836,8 @@ src_libnm_systemd_core_la_SOURCES = \
src/systemd/nm-sd-utils-core.h \
src/systemd/nm-sd.c \
src/systemd/nm-sd.h \
+ src/systemd/nm-sd-utils-dhcp.h \
+ src/systemd/nm-sd-utils-dhcp.c \
src/systemd/sd-adapt-core/condition.h \
src/systemd/sd-adapt-core/conf-parser.h \
src/systemd/sd-adapt-core/device-util.h \
@@ -1964,6 +1966,8 @@ src_libNetworkManagerBase_la_SOURCES = \
src/dhcp/nm-dhcp-nettools.c \
src/dhcp/nm-dhcp-utils.c \
src/dhcp/nm-dhcp-utils.h \
+ src/dhcp/nm-dhcp-options.c \
+ src/dhcp/nm-dhcp-options.h \
src/dhcp/nm-dhcp-systemd.c \
src/dhcp/nm-dhcp-manager.c \
src/dhcp/nm-dhcp-manager.h \
diff --git a/dispatcher/nm-dispatcher-utils.c b/dispatcher/nm-dispatcher-utils.c
index 2af5a57ab9..c09b8c8a1a 100644
--- a/dispatcher/nm-dispatcher-utils.c
+++ b/dispatcher/nm-dispatcher-utils.c
@@ -381,6 +381,8 @@ construct_device_dhcp_items (GPtrArray *items, int addr_family, GVariant *dhcp_c
const char *key;
GVariant *val;
char four_or_six;
+ gboolean found_unknown_245 = FALSE;
+ gs_unref_variant GVariant *private_245_val = NULL;
if (!dhcp_config)
return;
@@ -402,10 +404,43 @@ construct_device_dhcp_items (GPtrArray *items, int addr_family, GVariant *dhcp_c
four_or_six,
ucased,
g_variant_get_string (val, NULL));
+
+ /* MS Azure sends the server endpoint in the dhcp private
+ * option 245. cloud-init searches the Azure server endpoint
+ * value looking for the standard dhclient label used for
+ * that option, which is "unknown_245".
+ * The 11-dhclient script shipped with Fedora and RHEL dhcp
+ * package converts our dispatcher environment vars to the
+ * dhclient ones (new_<some_option>) and calls dhclient hook
+ * scripts.
+ * Let's make cloud-init happy and let's duplicate the dhcp
+ * option 245 with the legacy name of the default dhclient
+ * label also when using the internal client.
+ * Note however that the dhclient plugin will have unknown_
+ * labels represented as ascii string when possible, falling
+ * back to hex string otherwise.
+ * private_ labels instead are always in hex string format.
+ * This shouldn't affect the MS Azure server endpoint value,
+ * as it usually belongs to the 240.0.0.0/4 network and so
+ * is always represented as an hex string. Moreover, cloudinit
+ * code checks just for an hex value in unknown_245.
+ */
+ if (addr_family == AF_INET) {
+ if (nm_streq (key, "private_245"))
+ private_245_val = g_variant_ref (val);
+ else if (nm_streq (key, "unknown_245"))
+ found_unknown_245 = true;
+ }
}
}
g_variant_unref (val);
}
+
+ if (private_245_val != NULL && !found_unknown_245) {
+ _items_add_printf (items,
+ "DHCP4_UNKNOWN_245=%s",
+ g_variant_get_string (private_245_val, NULL));
+ }
}
/*****************************************************************************/
@@ -534,7 +569,7 @@ nm_dispatcher_utils_construct_envp (const char *action,
_items_add_key0 (items, NULL, "DEVICE_IP_IFACE", ip_iface);
}
- /* Device it's aren't valid if the device isn't activated */
+ /* Device items aren't valid if the device isn't activated */
if ( iface
&& dev_state == NM_DEVICE_STATE_ACTIVATED) {
construct_proxy_items (items, device_proxy_props, NULL);
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c
index e6ac217c56..9f585c5dc9 100644
--- a/src/dhcp/nm-dhcp-client.c
+++ b/src/dhcp/nm-dhcp-client.c
@@ -730,6 +730,23 @@ bytearray_variant_to_string (NMDhcpClient *self, GVariant *value, const char *ke
return converted;
}
+static int
+label_is_unknown_xyz (const char *label)
+{
+ if (!NM_STR_HAS_PREFIX (label, "unknown_"))
+ return -EINVAL;
+
+ label += NM_STRLEN ("unknown_");
+ if ( label[0] != '2'
+ || !g_ascii_isdigit (label[1])
+ || !g_ascii_isdigit (label[2])
+ || label[3] != '\0')
+ return -EINVAL;
+
+ return _nm_utils_ascii_str_to_int64 (label, 10, 224, 254, -EINVAL);
+}
+
+
#define OLD_TAG "old_"
#define NEW_TAG "new_"
@@ -753,14 +770,41 @@ maybe_add_option (NMDhcpClient *self,
"dhcp_message_type"))
return;
- if (g_str_has_prefix (key, NEW_TAG))
+ if (NM_STR_HAS_PREFIX (key, NEW_TAG))
key += NM_STRLEN (NEW_TAG);
- if (!key[0])
+ if (NM_STR_HAS_PREFIX (key, "private_") || !key[0])
return;
str_value = bytearray_variant_to_string (self, value, key);
- if (str_value)
+ if (str_value) {
+ int priv_opt_num;
+
g_hash_table_insert (hash, g_strdup (key), str_value);
+
+ /* dhclient has no special labels for private dhcp options: it uses "unknown_xyz"
+ * labels for that. We need to identify those to alias them to our "private_xyz"
+ * format unsed in the internal dchp plugins.
+ */
+ if ((priv_opt_num = label_is_unknown_xyz (key)) > 0) {
+ gs_free guint8 *check_val = NULL;
+ char *hex_str = NULL;
+ gsize len;
+
+ /* dhclient passes values from dhcp private options in its own "string" format:
+ * if the raw values are printable as ascii strings, it will pass the string
+ * representation; if the values are not printable as an ascii string, it will
+ * pass a string displaying the hex values (hex string). Try to enforce passing
+ * always an hex string, converting string representation if needed.
+ */
+ check_val = nm_utils_hexstr2bin_alloc (str_value, FALSE, TRUE, ":", 0, &len);
+ hex_str = nm_utils_bin2hexstr_full (check_val ?: (guint8 *) str_value,
+ check_val ? len : strlen (str_value),
+ ':', FALSE, NULL);
+ g_hash_table_insert (hash,
+ g_strdup_printf ("private_%d", priv_opt_num),
+ hex_str);
+ }
+ }
}
gboolean
diff --git a/src/dhcp/nm-dhcp-options.c b/src/dhcp/nm-dhcp-options.c
new file mode 100644
index 0000000000..503f6711d8
--- /dev/null
+++ b/src/dhcp/nm-dhcp-options.c
@@ -0,0 +1,276 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2019 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-dhcp-options.h"
+
+
+#define REQPREFIX "requested_"
+
+#define REQ(_num, _name, _include) \
+ { \
+ .name = REQPREFIX""_name, \
+ .option_num = _num, \
+ .include = _include, \
+ }
+
+const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = {
+ REQ (NM_DHCP_OPTION_DHCP4_SUBNET_MASK, "subnet_mask", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TIME_OFFSET, "time_offset", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, "domain_name_servers", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_HOST_NAME, "host_name", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, "domain_name", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_INTERFACE_MTU, "interface_mtu", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_BROADCAST, "broadcast_address", TRUE ),
+ /* RFC 3442: The Classless Static Routes option code MUST appear in the parameter
+ * request list prior to both the Router option code and the Static
+ * Routes option code, if present. */
+ REQ (NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE, "rfc3442_classless_static_routes", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ROUTER, "routers", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, "static_routes", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NIS_DOMAIN, "nis_domain", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NIS_SERVERS, "nis_servers", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NTP_SERVER, "ntp_servers", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SERVER_ID, "dhcp_server_identifier", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST, "domain_search", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE, "ms_classless_static_routes", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY, "wpad", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ROOT_PATH, "root_path", TRUE ),
+
+ REQ (NM_DHCP_OPTION_DHCP4_TIME_SERVERS, "time_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IEN116_NAME_SERVERS, "ien116_name_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_LOG_SERVERS, "log_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_COOKIE_SERVERS, "cookie_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_LPR_SERVERS, "lpr_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IMPRESS_SERVERS, "impress_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_RESOURCE_LOCATION_SERVERS, "resource_location_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_BOOT_FILE_SIZE, "boot_size", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_MERIT_DUMP, "merit_dump", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SWAP_SERVER, "swap_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_EXTENSIONS_PATH, "extensions_path", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ENABLE_IP_FORWARDING, "ip_forwarding", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ENABLE_SRC_ROUTING, "non_local_source_routing", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_POLICY_FILTER, "policy_filter", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_INTERFACE_MDR, "max_dgram_reassembly", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_INTERFACE_TTL, "default_ip_ttl", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_INTERFACE_MTU_AGING_TIMEOUT, "path_mtu_aging_timeout", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PATH_MTU_PLATEAU_TABLE, "path_mtu_plateau_table", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ALL_SUBNETS_LOCAL, "all_subnets_local", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PERFORM_MASK_DISCOVERY, "perform_mask_discovery", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_MASK_SUPPLIER, "mask_supplier", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ROUTER_DISCOVERY, "router_discovery", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ROUTER_SOLICITATION_ADDR, "router_solicitation_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TRAILER_ENCAPSULATION, "trailer_encapsulation", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ARP_CACHE_TIMEOUT, "arp_cache_timeout", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IEEE802_3_ENCAPSULATION, "ieee802_3_encapsulation", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_DEFAULT_TCP_TTL, "default_tcp_ttl", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_INTERVAL, "tcp_keepalive_internal", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_GARBAGE, "tcp_keepalive_garbage", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, "vendor_encapsulated_options", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER, "netbios_name_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NETBIOS_DD_SERVER, "netbios_dd_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_FONT_SERVERS, "font_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_X_DISPLAY_MANAGER, "x_display_manager", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME, "dhcp_lease_time", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_RENEWAL_T1_TIME, "dhcp_renewal_time", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_REBINDING_T2_TIME, "dhcp_rebinding_time", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE, "tcode", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NWIP_DOMAIN, "nwip_domain", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NWIP_SUBOPTIONS, "nwip_suboptions", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NISPLUS_DOMAIN, "nisplus_domain", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NISPLUS_SERVERS, "nisplus_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TFTP_SERVER_NAME, "tftp_server_name", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME, "bootfile_name", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_MOBILE_IP_HOME_AGENT, "mobile_ip_home_agent", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SMTP_SERVER, "smtp_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_POP_SERVER, "pop_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NNTP_SERVER, "nntp_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_WWW_SERVER, "www_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_FINGER_SERVER, "finger_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IRC_SERVER, "irc_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_STREETTALK_SERVER, "streettalk_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_STREETTALK_DIR_ASSIST_SERVER, "streettalk_directory_assistance_server", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SLP_DIRECTORY_AGENT, "slp_directory_agent", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SLP_SERVICE_SCOPE, "slp_service_scope", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_RELAY_AGENT_INFORMATION, "relay_agent_information", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NDS_SERVERS, "nds_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NDS_TREE_NAME, "nds_tree_name", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NDS_CONTEXT, "nds_context", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_BCMS_CONTROLLER_NAMES, "bcms_controller_names", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_BCMS_CONTROLLER_ADDRESS, "bcms_controller_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_CLIENT_LAST_TRANSACTION, "client_last_transaction_time", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_ASSOCIATED_IP, "associated_ip", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PXE_SYSTEM_TYPE, "pxe_system_type", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PXE_INTERFACE_ID, "pxe_interface_id", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PXE_CLIENT_ID, "pxe_client_id", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_UAP_SERVERS, "uap_servers", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_GEOCONF_CIVIC, "geoconf_civic", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_ADDRESS, "netinfo_server_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_TAG, "netinfo_server_tag", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_DEFAULT_URL, "default_url", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_AUTO_CONFIG, "auto_config", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NAME_SERVICE_SEARCH, "name_service_search", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SUBNET_SELECTION, "subnet_selection", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_VIVCO, "vivco", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_VIVSO, "vivso", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PANA_AGENT, "pana_agent", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_V4_LOST, "v4_lost", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_SIP_UA_CS_DOMAINS, "sip_ua_cs_domains", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_IPV4_ADDRESS_ANDSF, "ipv4_address_andsf", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_RDNSS_SELECTION, "rndss_selection", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_TFTP_SERVER_ADDRESS, "tftp_server_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_V4_PORTPARAMS, "v4_portparams", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_V4_CAPTIVE_PORTAL, "v4_captive_portal", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_LOADER_CONFIGFILE, "loader_configfile", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_LOADER_PATHPREFIX, "loader_pathprefix", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_LOADER_REBOOTTIME, "loader_reboottime", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_OPTION_6RD, "option_6rd", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_V4_ACCESS_DOMAIN, "v4_access_domain", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_224, "private_224", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_225, "private_225", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_226, "private_226", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_227, "private_227", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_228, "private_228", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_229, "private_229", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_230, "private_230", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_231, "private_231", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_232, "private_232", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_233, "private_233", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_234, "private_234", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_235, "private_235", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_236, "private_236", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_237, "private_237", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_238, "private_238", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_239, "private_239", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_240, "private_240", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_241, "private_241", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_242, "private_242", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_243, "private_243", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_244, "private_244", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_245, "private_245", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_246, "private_246", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_247, "private_247", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_248, "private_248", FALSE ),
+ /* DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE */
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_250, "private_250", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_251, "private_251", FALSE ),
+ /* DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY */
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_253, "private_253", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_PRIVATE_254, "private_254", FALSE ),
+
+ /* Internal values */
+ REQ (NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, "ip_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP4_NM_EXPIRY, "expiry", FALSE ),
+
+ { 0 }
+};
+
+const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = {
+ REQ (NM_DHCP_OPTION_DHCP6_CLIENTID, "dhcp6_client_id", FALSE ),
+
+ /* Don't request server ID by default; some servers don't reply to
+ * Information Requests that request the Server ID.
+ */
+ REQ (NM_DHCP_OPTION_DHCP6_SERVERID, "dhcp6_server_id", FALSE ),
+
+ REQ (NM_DHCP_OPTION_DHCP6_DNS_SERVERS, "dhcp6_name_servers", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP6_DOMAIN_LIST, "dhcp6_domain_search", TRUE ),
+ REQ (NM_DHCP_OPTION_DHCP6_SNTP_SERVERS, "dhcp6_sntp_servers", TRUE ),
+
+ /* Internal values */
+ REQ (NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, "ip6_address", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_PREFIXLEN, "ip6_prefixlen", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_PREFERRED_LIFE, "preferred_life", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_MAX_LIFE, "max_life", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_STARTS, "starts", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_LIFE_STARTS, "life_starts", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_RENEW, "renew", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_REBIND, "rebind", FALSE ),
+ REQ (NM_DHCP_OPTION_DHCP6_NM_IAID, "iaid", FALSE ),
+
+ { 0 }
+};
+
+
+const char *
+nm_dhcp_option_request_string (const NMDhcpOption *requests, guint option)
+{
+ guint i = 0;
+
+ while (requests[i].name) {
+ if (requests[i].option_num == option)
+ return requests[i].name + NM_STRLEN (REQPREFIX);
+ i++;
+ }
+
+ /* Option should always be found */
+ nm_assert_not_reached ();
+ return NULL;
+}
+
+void
+nm_dhcp_option_take_option (GHashTable *options,
+ const NMDhcpOption *requests,
+ guint option,
+ char *value)
+{
+ nm_assert (options);
+ nm_assert (requests);
+ nm_assert (value);
+
+ g_hash_table_insert (options,
+ (gpointer) nm_dhcp_option_request_string (requests, option),
+ value);
+}
+
+void
+nm_dhcp_option_add_option (GHashTable *options, const NMDhcpOption *requests, guint option, const char *value)
+{
+ if (options)
+ nm_dhcp_option_take_option (options, requests, option, g_strdup (value));
+}
+
+void
+nm_dhcp_option_add_option_u64 (GHashTable *options, const NMDhcpOption *requests, guint option, guint64 value)
+{
+ if (options)
+ nm_dhcp_option_take_option (options, requests, option, g_strdup_printf ("%" G_GUINT64_FORMAT, value));
+}
+
+void
+nm_dhcp_option_add_requests_to_options (GHashTable *options, const NMDhcpOption *requests)
+{
+ guint i;
+
+ if (!options)
+ return;
+
+ for (i = 0; requests[i].name; i++) {
+ if (requests[i].include)
+ g_hash_table_insert (options, (gpointer) requests[i].name, g_strdup ("1"));
+ }
+}
+
+GHashTable *
+nm_dhcp_option_create_options_dict (void)
+{
+ return g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free);
+}
+
diff --git a/src/dhcp/nm-dhcp-options.h b/src/dhcp/nm-dhcp-options.h
new file mode 100644
index 0000000000..4e6c431abf
--- /dev/null
+++ b/src/dhcp/nm-dhcp-options.h
@@ -0,0 +1,202 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2019 Red Hat, Inc.
+ */
+
+#ifndef __NM_DHCP_OPTIONS_H__
+#define __NM_DHCP_OPTIONS_H__
+
+typedef enum {
+ NM_DHCP_OPTION_DHCP4_PAD = 0,
+ NM_DHCP_OPTION_DHCP4_SUBNET_MASK = 1,
+ NM_DHCP_OPTION_DHCP4_TIME_OFFSET = 2,
+ NM_DHCP_OPTION_DHCP4_ROUTER = 3,
+ NM_DHCP_OPTION_DHCP4_TIME_SERVERS = 4,
+ NM_DHCP_OPTION_DHCP4_IEN116_NAME_SERVERS = 5,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER = 6,
+ NM_DHCP_OPTION_DHCP4_LOG_SERVERS = 7,
+ NM_DHCP_OPTION_DHCP4_COOKIE_SERVERS = 8,
+ NM_DHCP_OPTION_DHCP4_LPR_SERVERS = 9,
+ NM_DHCP_OPTION_DHCP4_IMPRESS_SERVERS = 10,
+ NM_DHCP_OPTION_DHCP4_RESOURCE_LOCATION_SERVERS = 11,
+ NM_DHCP_OPTION_DHCP4_HOST_NAME = 12,
+ NM_DHCP_OPTION_DHCP4_BOOT_FILE_SIZE = 13,
+ NM_DHCP_OPTION_DHCP4_MERIT_DUMP = 14,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_NAME = 15,
+ NM_DHCP_OPTION_DHCP4_SWAP_SERVER = 16,
+ NM_DHCP_OPTION_DHCP4_ROOT_PATH = 17,
+ NM_DHCP_OPTION_DHCP4_EXTENSIONS_PATH = 18,
+ NM_DHCP_OPTION_DHCP4_ENABLE_IP_FORWARDING = 19,
+ NM_DHCP_OPTION_DHCP4_ENABLE_SRC_ROUTING = 20,
+ NM_DHCP_OPTION_DHCP4_POLICY_FILTER = 21,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_MDR = 22,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_TTL = 23,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_MTU_AGING_TIMEOUT = 24,
+ NM_DHCP_OPTION_DHCP4_PATH_MTU_PLATEAU_TABLE = 25,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_MTU = 26,
+ NM_DHCP_OPTION_DHCP4_ALL_SUBNETS_LOCAL = 27,
+ NM_DHCP_OPTION_DHCP4_BROADCAST = 28,
+ NM_DHCP_OPTION_DHCP4_PERFORM_MASK_DISCOVERY = 29,
+ NM_DHCP_OPTION_DHCP4_MASK_SUPPLIER = 30,
+ NM_DHCP_OPTION_DHCP4_ROUTER_DISCOVERY = 31,
+ NM_DHCP_OPTION_DHCP4_ROUTER_SOLICITATION_ADDR = 32,
+ NM_DHCP_OPTION_DHCP4_STATIC_ROUTE = 33,
+ NM_DHCP_OPTION_DHCP4_TRAILER_ENCAPSULATION = 34,
+ NM_DHCP_OPTION_DHCP4_ARP_CACHE_TIMEOUT = 35,
+ NM_DHCP_OPTION_DHCP4_IEEE802_3_ENCAPSULATION = 36,
+ NM_DHCP_OPTION_DHCP4_DEFAULT_TCP_TTL = 37,
+ NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_INTERVAL = 38,
+ NM_DHCP_OPTION_DHCP4_TCP_KEEPALIVE_GARBAGE = 39,
+ NM_DHCP_OPTION_DHCP4_NIS_DOMAIN = 40,
+ NM_DHCP_OPTION_DHCP4_NIS_SERVERS = 41,
+ NM_DHCP_OPTION_DHCP4_NTP_SERVER = 42,
+ NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC = 43,
+ NM_DHCP_OPTION_DHCP4_NETBIOS_NAMESERVER = 44,
+ NM_DHCP_OPTION_DHCP4_NETBIOS_DD_SERVER = 45,
+ NM_DHCP_OPTION_DHCP4_FONT_SERVERS = 48,
+ NM_DHCP_OPTION_DHCP4_X_DISPLAY_MANAGER = 49,
+ NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME = 51,
+ NM_DHCP_OPTION_DHCP4_SERVER_ID = 54,
+ NM_DHCP_OPTION_DHCP4_RENEWAL_T1_TIME = 58,
+ NM_DHCP_OPTION_DHCP4_REBINDING_T2_TIME = 59,
+ NM_DHCP_OPTION_DHCP4_NWIP_DOMAIN = 62,
+ NM_DHCP_OPTION_DHCP4_NWIP_SUBOPTIONS = 63,
+ NM_DHCP_OPTION_DHCP4_NISPLUS_DOMAIN = 64,
+ NM_DHCP_OPTION_DHCP4_NISPLUS_SERVERS = 65,
+ NM_DHCP_OPTION_DHCP4_TFTP_SERVER_NAME = 66,
+ NM_DHCP_OPTION_DHCP4_BOOTFILE_NAME = 67,
+ NM_DHCP_OPTION_DHCP4_MOBILE_IP_HOME_AGENT = 68,
+ NM_DHCP_OPTION_DHCP4_SMTP_SERVER = 69,
+ NM_DHCP_OPTION_DHCP4_POP_SERVER = 70,
+ NM_DHCP_OPTION_DHCP4_NNTP_SERVER = 71,
+ NM_DHCP_OPTION_DHCP4_WWW_SERVER = 72,
+ NM_DHCP_OPTION_DHCP4_FINGER_SERVER = 73,
+ NM_DHCP_OPTION_DHCP4_IRC_SERVER = 74,
+ NM_DHCP_OPTION_DHCP4_STREETTALK_SERVER = 75,
+ NM_DHCP_OPTION_DHCP4_STREETTALK_DIR_ASSIST_SERVER = 76,
+ NM_DHCP_OPTION_DHCP4_SLP_DIRECTORY_AGENT = 78,
+ NM_DHCP_OPTION_DHCP4_SLP_SERVICE_SCOPE = 79,
+ NM_DHCP_OPTION_DHCP4_RELAY_AGENT_INFORMATION = 82,
+ NM_DHCP_OPTION_DHCP4_NDS_SERVERS = 85,
+ NM_DHCP_OPTION_DHCP4_NDS_TREE_NAME = 86,
+ NM_DHCP_OPTION_DHCP4_NDS_CONTEXT = 87,
+ NM_DHCP_OPTION_DHCP4_BCMS_CONTROLLER_NAMES = 88,
+ NM_DHCP_OPTION_DHCP4_BCMS_CONTROLLER_ADDRESS = 89,
+ NM_DHCP_OPTION_DHCP4_CLIENT_LAST_TRANSACTION = 91,
+ NM_DHCP_OPTION_DHCP4_ASSOCIATED_IP = 92,
+ NM_DHCP_OPTION_DHCP4_PXE_SYSTEM_TYPE = 93,
+ NM_DHCP_OPTION_DHCP4_PXE_INTERFACE_ID = 94,
+ NM_DHCP_OPTION_DHCP4_PXE_CLIENT_ID = 97,
+ NM_DHCP_OPTION_DHCP4_UAP_SERVERS = 98,
+ NM_DHCP_OPTION_DHCP4_GEOCONF_CIVIC = 99,
+ NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE = 101,
+ NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_ADDRESS = 112,
+ NM_DHCP_OPTION_DHCP4_NETINFO_SERVER_TAG = 113,
+ NM_DHCP_OPTION_DHCP4_DEFAULT_URL = 114,
+ NM_DHCP_OPTION_DHCP4_AUTO_CONFIG = 116,
+ NM_DHCP_OPTION_DHCP4_NAME_SERVICE_SEARCH = 117,
+ NM_DHCP_OPTION_DHCP4_SUBNET_SELECTION = 118,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST = 119,
+ NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE = 121,
+ NM_DHCP_OPTION_DHCP4_VIVCO = 124,
+ NM_DHCP_OPTION_DHCP4_VIVSO = 125,
+ NM_DHCP_OPTION_DHCP4_PANA_AGENT = 136,
+ NM_DHCP_OPTION_DHCP4_V4_LOST = 137,
+ NM_DHCP_OPTION_DHCP4_SIP_UA_CS_DOMAINS = 141,
+ NM_DHCP_OPTION_DHCP4_IPV4_ADDRESS_ANDSF = 142,
+ NM_DHCP_OPTION_DHCP4_RDNSS_SELECTION = 146,
+ NM_DHCP_OPTION_DHCP4_TFTP_SERVER_ADDRESS = 150,
+ NM_DHCP_OPTION_DHCP4_V4_PORTPARAMS = 159,
+ NM_DHCP_OPTION_DHCP4_V4_CAPTIVE_PORTAL = 160,
+ NM_DHCP_OPTION_DHCP4_LOADER_CONFIGFILE = 209,
+ NM_DHCP_OPTION_DHCP4_LOADER_PATHPREFIX = 210,
+ NM_DHCP_OPTION_DHCP4_LOADER_REBOOTTIME = 211,
+ NM_DHCP_OPTION_DHCP4_OPTION_6RD = 212,
+ NM_DHCP_OPTION_DHCP4_V4_ACCESS_DOMAIN = 213,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_224 = 224,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_225 = 225,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_226 = 226,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_227 = 227,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_228 = 228,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_229 = 229,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_230 = 230,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_231 = 231,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_232 = 232,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_233 = 233,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_234 = 234,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_235 = 235,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_236 = 236,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_237 = 237,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_238 = 238,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_239 = 239,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_240 = 240,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_241 = 241,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_242 = 242,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_243 = 243,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_244 = 244,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_245 = 245,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_246 = 246,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_247 = 247,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_248 = 248,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE = 249,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_250 = 250,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_251 = 251,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_PROXY_AUTODISCOVERY = 252,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_253 = 253,
+ NM_DHCP_OPTION_DHCP4_PRIVATE_254 = 254,
+ NM_DHCP_OPTION_DHCP4_END = 255,
+ /* Internal values */
+ NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS = 1024,
+ NM_DHCP_OPTION_DHCP4_NM_EXPIRY = 1025,
+} NMDhcpOptionDhcp4Options;
+
+typedef enum {
+ NM_DHCP_OPTION_DHCP6_CLIENTID = 1,
+ NM_DHCP_OPTION_DHCP6_SERVERID = 2,
+ NM_DHCP_OPTION_DHCP6_DNS_SERVERS = 23,
+ NM_DHCP_OPTION_DHCP6_DOMAIN_LIST = 24,
+ NM_DHCP_OPTION_DHCP6_SNTP_SERVERS = 31,
+ /* Internal values */
+ NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS = 1026,
+ NM_DHCP_OPTION_DHCP6_NM_PREFIXLEN = 1027,
+ NM_DHCP_OPTION_DHCP6_NM_PREFERRED_LIFE = 1028,
+ NM_DHCP_OPTION_DHCP6_NM_MAX_LIFE = 1029,
+ NM_DHCP_OPTION_DHCP6_NM_STARTS = 1030,
+ NM_DHCP_OPTION_DHCP6_NM_LIFE_STARTS = 1031,
+ NM_DHCP_OPTION_DHCP6_NM_RENEW = 1032,
+ NM_DHCP_OPTION_DHCP6_NM_REBIND = 1033,
+ NM_DHCP_OPTION_DHCP6_NM_IAID = 1034,
+
+} NMDhcpOptionDhcp6Options;
+
+typedef struct {
+ const char *name;
+ uint16_t option_num;
+ bool include;
+} NMDhcpOption;
+
+extern const NMDhcpOption _nm_dhcp_option_dhcp4_options[];
+extern const NMDhcpOption _nm_dhcp_option_dhcp6_options[];
+
+const char *nm_dhcp_option_request_string (const NMDhcpOption *requests, guint option);
+void nm_dhcp_option_take_option (GHashTable *options, const NMDhcpOption *requests, guint option, char *value);
+void nm_dhcp_option_add_option (GHashTable *options, const NMDhcpOption *requests, guint option, const char *value);
+void nm_dhcp_option_add_option_u64 (GHashTable *options, const NMDhcpOption *requests, guint option, guint64 value);
+void nm_dhcp_option_add_requests_to_options (GHashTable *options, const NMDhcpOption *requests);
+GHashTable *nm_dhcp_option_create_options_dict (void);
+
+#endif /* __NM_DHCP_OPTIONS_H__ */
diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c
index 54b8ae57cb..0e2b310373 100644
--- a/src/dhcp/nm-dhcp-systemd.c
+++ b/src/dhcp/nm-dhcp-systemd.c
@@ -32,11 +32,13 @@
#include "nm-utils.h"
#include "nm-config.h"
#include "nm-dhcp-utils.h"
+#include "nm-dhcp-options.h"
#include "nm-core-utils.h"
#include "NetworkManagerUtils.h"
#include "platform/nm-platform.h"
#include "nm-dhcp-client-logging.h"
#include "systemd/nm-sd.h"
+#include "systemd/nm-sd-utils-dhcp.h"
/*****************************************************************************/
@@ -79,160 +81,10 @@ G_DEFINE_TYPE (NMDhcpSystemd, nm_dhcp_systemd, NM_TYPE_DHCP_CLIENT)
/*****************************************************************************/
-#define DHCP_OPTION_NIS_DOMAIN 40
-#define DHCP_OPTION_NIS_SERVERS 41
-
-/* Internal values */
-#define DHCP_OPTION_IP_ADDRESS 1024
-#define DHCP_OPTION_EXPIRY 1025
-#define DHCP6_OPTION_IP_ADDRESS 1026
-#define DHCP6_OPTION_PREFIXLEN 1027
-#define DHCP6_OPTION_PREFERRED_LIFE 1028
-#define DHCP6_OPTION_MAX_LIFE 1029
-#define DHCP6_OPTION_STARTS 1030
-#define DHCP6_OPTION_LIFE_STARTS 1031
-#define DHCP6_OPTION_RENEW 1032
-#define DHCP6_OPTION_REBIND 1033
-#define DHCP6_OPTION_IAID 1034
-
-typedef struct {
- const char *name;
- uint16_t option_num;
- bool include;
-} ReqOption;
-
-#define REQPREFIX "requested_"
-
-#define REQ(_num, _name, _include) \
- { \
- .name = REQPREFIX""_name, \
- .option_num = _num, \
- .include = _include, \
- }
-
-static const ReqOption dhcp4_requests[] = {
- REQ (SD_DHCP_OPTION_SUBNET_MASK, "subnet_mask", TRUE ),
- REQ (SD_DHCP_OPTION_TIME_OFFSET, "time_offset", TRUE ),
- REQ (SD_DHCP_OPTION_DOMAIN_NAME_SERVER, "domain_name_servers", TRUE ),
- REQ (SD_DHCP_OPTION_HOST_NAME, "host_name", TRUE ),
- REQ (SD_DHCP_OPTION_DOMAIN_NAME, "domain_name", TRUE ),
- REQ (SD_DHCP_OPTION_INTERFACE_MTU, "interface_mtu", TRUE ),
- REQ (SD_DHCP_OPTION_BROADCAST, "broadcast_address", TRUE ),
-
- /* RFC 3442: The Classless Static Routes option code MUST appear in the parameter
- * request list prior to both the Router option code and the Static
- * Routes option code, if present. */
- REQ (SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, "rfc3442_classless_static_routes", TRUE ),
- REQ (SD_DHCP_OPTION_ROUTER, "routers", TRUE ),
- REQ (SD_DHCP_OPTION_STATIC_ROUTE, "static_routes", TRUE ),
-
- REQ (DHCP_OPTION_NIS_DOMAIN, "nis_domain", TRUE ),
- REQ (DHCP_OPTION_NIS_SERVERS, "nis_servers", TRUE ),
- REQ (SD_DHCP_OPTION_NTP_SERVER, "ntp_servers", TRUE ),
- REQ (SD_DHCP_OPTION_SERVER_IDENTIFIER, "dhcp_server_identifier", TRUE ),
- REQ (SD_DHCP_OPTION_DOMAIN_SEARCH_LIST, "domain_search", TRUE ),
- REQ (SD_DHCP_OPTION_PRIVATE_CLASSLESS_STATIC_ROUTE, "ms_classless_static_routes", TRUE ),
- REQ (SD_DHCP_OPTION_PRIVATE_PROXY_AUTODISCOVERY, "wpad", TRUE ),
- REQ (SD_DHCP_OPTION_ROOT_PATH, "root_path", TRUE ),
-
- /* Internal values */
- REQ (SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME, "expiry", FALSE ),
- REQ (SD_DHCP_OPTION_CLIENT_IDENTIFIER, "dhcp_client_identifier", FALSE ),
- REQ (DHCP_OPTION_IP_ADDRESS, "ip_address", FALSE ),
-
- { 0 }
-};
-
-static const ReqOption dhcp6_requests[] = {
- REQ (SD_DHCP6_OPTION_CLIENTID, "dhcp6_client_id", FALSE ),
-
- /* Don't request server ID by default; some servers don't reply to
- * Information Requests that request the Server ID.
- */
- REQ (SD_DHCP6_OPTION_SERVERID, "dhcp6_server_id", FALSE ),
-
- REQ (SD_DHCP6_OPTION_DNS_SERVERS, "dhcp6_name_servers", TRUE ),
- REQ (SD_DHCP6_OPTION_DOMAIN_LIST, "dhcp6_domain_search", TRUE ),
- REQ (SD_DHCP6_OPTION_SNTP_SERVERS, "dhcp6_sntp_servers", TRUE ),
-
- /* Internal values */
- REQ (DHCP6_OPTION_IP_ADDRESS, "ip6_address", FALSE ),
- REQ (DHCP6_OPTION_PREFIXLEN, "ip6_prefixlen", FALSE ),
- REQ (DHCP6_OPTION_PREFERRED_LIFE, "preferred_life", FALSE ),
- REQ (DHCP6_OPTION_MAX_LIFE, "max_life", FALSE ),
- REQ (DHCP6_OPTION_STARTS, "starts", FALSE ),
- REQ (DHCP6_OPTION_LIFE_STARTS, "life_starts", FALSE ),
- REQ (DHCP6_OPTION_RENEW, "renew", FALSE ),
- REQ (DHCP6_OPTION_REBIND, "rebind", FALSE ),
- REQ (DHCP6_OPTION_IAID, "iaid", FALSE ),
-
- { 0 }
-};
-
-static void
-take_option (GHashTable *options,
- const ReqOption *requests,
- guint option,
- char *value)
-{
- guint i;
-
- nm_assert (options);
- nm_assert (requests);
- nm_assert (value);
-
- for (i = 0; requests[i].name; i++) {
- nm_assert (g_str_has_prefix (requests[i].name, REQPREFIX));
- if (requests[i].option_num == option) {
- g_hash_table_insert (options,
- (gpointer) (requests[i].name + NM_STRLEN (REQPREFIX)),
- value);
- return;
- }
- }
-
- /* Option should always be found */
- nm_assert_not_reached ();
-}
-
-static void
-add_option (GHashTable *options, const ReqOption *requests, guint option, const char *value)
-{
- if (options)
- take_option (options, requests, option, g_strdup (value));
-}
-
-static void
-add_option_u64 (GHashTable *options, const ReqOption *requests, guint option, guint64 value)
-{
- if (options)
- take_option (options, requests, option, g_strdup_printf ("%" G_GUINT64_FORMAT, value));
-}
-
-static void
-add_requests_to_options (GHashTable *options, const ReqOption *requests)
-{
- guint i;
-
- if (!options)
- return;
-
- for (i = 0; requests[i].name; i++) {
- if (requests[i].include)
- g_hash_table_insert (options, (gpointer) requests[i].name, g_strdup ("1"));
- }
-}
-
-static GHashTable *
-create_options_dict (void)
-{
- return g_hash_table_new_full (nm_str_hash, g_str_equal, NULL, g_free);
-}
-
#define LOG_LEASE(domain, ...) \
G_STMT_START { \
if (log_lease) { \
- _LOG2I ((domain), (iface), " "__VA_ARGS__); \
+ _LOG2D ((domain), (iface), " "__VA_ARGS__); \
} \
} G_STMT_END
@@ -267,9 +119,14 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
gint64 ts_time = time (NULL);
struct in_addr a_address;
struct in_addr a_netmask;
+ struct in_addr server_id;
+ struct in_addr broadcast;
const struct in_addr *a_router;
guint32 a_plen;
guint32 a_lifetime;
+ guint32 renewal;
+ guint32 rebinding;
+ gs_free nm_sd_dhcp_option *private_options = NULL;
g_return_val_if_fail (lease != NULL, NULL);
@@ -290,26 +147,35 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
ip4_config = nm_ip4_config_new (multi_idx, ifindex);
- options = out_options ? create_options_dict () : NULL;
+ options = out_options ? nm_dhcp_option_create_options_dict () : NULL;
nm_utils_inet4_ntop (a_address.s_addr, addr_str);
- LOG_LEASE (LOGD_DHCP4, "address %s", addr_str);
- add_option (options, dhcp4_requests, DHCP_OPTION_IP_ADDRESS, addr_str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS),
+ addr_str);
+ nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NM_IP_ADDRESS, addr_str);
a_plen = nm_utils_ip4_netmask_to_prefix (a_netmask.s_addr);
- LOG_LEASE (LOGD_DHCP4, "plen %u", (guint) a_plen);
- add_option (options,
- dhcp4_requests,
- SD_DHCP_OPTION_SUBNET_MASK,
- nm_utils_inet4_ntop (a_netmask.s_addr, addr_str));
-
- LOG_LEASE (LOGD_DHCP4, "expires in %u seconds (at %lld)",
+ LOG_LEASE (LOGD_DHCP4, "%s '%u'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_SUBNET_MASK),
+ (guint) a_plen);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_SUBNET_MASK,
+ nm_utils_inet4_ntop (a_netmask.s_addr, addr_str));
+
+ LOG_LEASE (LOGD_DHCP4, "%s '%u' seconds (at %lld)",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NM_EXPIRY),
(guint) a_lifetime,
(long long) (ts_time + a_lifetime));
- add_option_u64 (options,
- dhcp4_requests,
- SD_DHCP_OPTION_IP_ADDRESS_LEASE_TIME,
- (guint64) (ts_time + a_lifetime));
+ nm_dhcp_option_add_option_u64 (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NM_EXPIRY,
+ (guint64) (ts_time + a_lifetime));
+ nm_dhcp_option_add_option_u64 (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_IP_ADDRESS_LEASE_TIME,
+ a_lifetime);
nm_ip4_config_add_address (ip4_config,
&((const NMPlatformIP4Address) {
@@ -322,6 +188,28 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
.preferred = a_lifetime,
}));
+ if (sd_dhcp_lease_get_server_identifier (lease, &server_id) >= 0) {
+ nm_utils_inet4_ntop (server_id.s_addr, addr_str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_SERVER_ID),
+ addr_str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_SERVER_ID,
+ addr_str);
+ }
+
+ if (sd_dhcp_lease_get_broadcast (lease, &broadcast) >= 0) {
+ nm_utils_inet4_ntop (broadcast.s_addr, addr_str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_BROADCAST),
+ addr_str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_BROADCAST,
+ addr_str);
+ }
+
num = sd_dhcp_lease_get_dns (lease, &addr_list);
if (num > 0) {
nm_gstring_prepare (&str);
@@ -337,8 +225,13 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
}
nm_ip4_config_add_nameserver (ip4_config, addr_list[i].s_addr);
}
- LOG_LEASE (LOGD_DHCP4, "nameserver '%s'", str->str);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_DOMAIN_NAME_SERVER, str->str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER),
+ str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER,
+ str->str);
}
num = sd_dhcp_lease_get_search_domains (lease, (char ***) &search_domains);
@@ -348,16 +241,23 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
g_string_append (nm_gstring_add_space_delimiter (str), search_domains[i]);
nm_ip4_config_add_search (ip4_config, search_domains[i]);
}
- LOG_LEASE (LOGD_DHCP4, "domain search '%s'", str->str);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_DOMAIN_SEARCH_LIST, str->str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST),
+ str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_DOMAIN_SEARCH_LIST,
+ str->str);
}
if (sd_dhcp_lease_get_domainname (lease, &s) >= 0) {
gs_strfreev char **domains = NULL;
char **d;
- LOG_LEASE (LOGD_DHCP4, "domain name '%s'", s);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_DOMAIN_NAME, s);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME),
+ s);
+ nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME, s);
/* Multiple domains sometimes stuffed into option 15 "Domain Name".
* As systemd escapes such characters, split them at \\032. */
@@ -367,8 +267,10 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
}
if (sd_dhcp_lease_get_hostname (lease, &s) >= 0) {
- LOG_LEASE (LOGD_DHCP4, "hostname '%s'", s);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_HOST_NAME, s);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_HOST_NAME),
+ s);
+ nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_HOST_NAME, s);
}
num = sd_dhcp_lease_get_routes (lease, &routes);
@@ -379,10 +281,10 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
for (i = 0; i < num; i++) {
switch (sd_dhcp_route_get_option (routes[i])) {
- case SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE:
+ case NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE:
has_classless_route = TRUE;
break;
- case SD_DHCP_OPTION_STATIC_ROUTE:
+ case NM_DHCP_OPTION_DHCP4_STATIC_ROUTE:
has_static_route = TRUE;
break;
}
@@ -404,8 +306,8 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
guint32 m;
option = sd_dhcp_route_get_option (routes[i]);
- if (!NM_IN_SET (option, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE,
- SD_DHCP_OPTION_STATIC_ROUTE))
+ if (!NM_IN_SET (option, NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
+ NM_DHCP_OPTION_DHCP4_STATIC_ROUTE))
continue;
if (sd_dhcp_route_get_destination (routes[i], &r_network) < 0)
@@ -422,14 +324,14 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
nm_utils_inet4_ntop (r_gateway.s_addr, gateway_str);
LOG_LEASE (LOGD_DHCP4,
- "%sstatic route %s/%d gw %s",
- option == SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
- ? "classless "
+ "%sstatic_route %s/%d gw %s",
+ option == NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE
+ ? "rfc3442_classless_"
: "",
network_net_str,
(int) r_plen,
gateway_str);
- g_string_append_printf (nm_gstring_add_space_delimiter ( option == SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE
+ g_string_append_printf (nm_gstring_add_space_delimiter ( option == NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE
? str_classless
: str_static),
"%s/%d %s",
@@ -437,7 +339,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
(int) r_plen,
gateway_str);
- if ( option == SD_DHCP_OPTION_STATIC_ROUTE
+ if ( option == NM_DHCP_OPTION_DHCP4_STATIC_ROUTE
&& has_classless_route) {
/* RFC 3443: if the DHCP server returns both a Classless Static Routes
* option and a Static Routes option, the DHCP client MUST ignore the
@@ -446,7 +348,7 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
}
if ( r_plen == 0
- && option == SD_DHCP_OPTION_STATIC_ROUTE) {
+ && option == NM_DHCP_OPTION_DHCP4_STATIC_ROUTE) {
/* for option 33 (static route), RFC 2132 says:
*
* The default route (0.0.0.0) is an illegal destination for a static
@@ -478,9 +380,15 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
}
if (str_classless && str_classless->len > 0)
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_CLASSLESS_STATIC_ROUTE, str_classless->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE,
+ str_classless->str);
if (str_static && str_static->len > 0)
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_STATIC_ROUTE, str_static->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_STATIC_ROUTE,
+ str_static->str);
}
num = sd_dhcp_lease_get_router (lease, &a_router);
@@ -524,14 +432,21 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
}),
NULL);
}
- LOG_LEASE (LOGD_DHCP4, "router %s", str->str);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROUTER, str->str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROUTER),
+ str->str);
+ nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROUTER, str->str);
}
if ( sd_dhcp_lease_get_mtu (lease, &mtu) >= 0
&& mtu) {
- LOG_LEASE (LOGD_DHCP4, "mtu %u", mtu);
- add_option_u64 (options, dhcp4_requests, SD_DHCP_OPTION_INTERFACE_MTU, mtu);
+ LOG_LEASE (LOGD_DHCP4, "%s '%u'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_INTERFACE_MTU),
+ mtu);
+ nm_dhcp_option_add_option_u64 (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_INTERFACE_MTU,
+ mtu);
nm_ip4_config_set_mtu (ip4_config, mtu, NM_IP_CONFIG_SOURCE_DHCP);
}
@@ -542,19 +457,77 @@ lease_to_ip4_config (NMDedupMultiIndex *multi_idx,
nm_utils_inet4_ntop (addr_list[i].s_addr, addr_str);
g_string_append (nm_gstring_add_space_delimiter (str), addr_str);
}
- LOG_LEASE (LOGD_DHCP4, "ntp server '%s'", str->str);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_NTP_SERVER, str->str);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NTP_SERVER),
+ str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NTP_SERVER,
+ str->str);
}
if (sd_dhcp_lease_get_root_path (lease, &s) >= 0) {
- LOG_LEASE (LOGD_DHCP4, "root path '%s'", s);
- add_option (options, dhcp4_requests, SD_DHCP_OPTION_ROOT_PATH, s);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROOT_PATH),
+ s);
+ nm_dhcp_option_add_option (options, _nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_ROOT_PATH, s);
+ }
+
+ if (sd_dhcp_lease_get_t1 (lease, &renewal) >= 0) {
+ LOG_LEASE (LOGD_DHCP4, "%s '%u'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_RENEWAL_T1_TIME),
+ renewal);
+ nm_dhcp_option_add_option_u64 (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_RENEWAL_T1_TIME,
+ renewal);
+ }
+
+ if (sd_dhcp_lease_get_t2 (lease, &rebinding) >= 0) {
+ LOG_LEASE (LOGD_DHCP4, "%s '%u'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_REBINDING_T2_TIME),
+ rebinding);
+ nm_dhcp_option_add_option_u64 (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_REBINDING_T2_TIME,
+ rebinding);
+ }
+
+ if (sd_dhcp_lease_get_timezone (lease, &s) >= 0) {
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE),
+ s);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ NM_DHCP_OPTION_DHCP4_NEW_TZDB_TIMEZONE,
+ s);
}
if (sd_dhcp_lease_get_vendor_specific (lease, &data, &data_len) >= 0)
metered = !!memmem (data, data_len, "ANDROID_METERED", NM_STRLEN ("ANDROID_METERED"));
nm_ip4_config_set_metered (ip4_config, metered);
+ num = nm_sd_dhcp_lease_get_private_options (lease, &private_options);
+ if (num > 0) {
+ for (i = 0; i < num; i++) {
+ char *option_string;
+
+ option_string = nm_utils_bin2hexstr_full (private_options[i].data,
+ private_options[i].data_len,
+ ':', FALSE, NULL);
+ LOG_LEASE (LOGD_DHCP4, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp4_options, private_options[i].code),
+ option_string);
+ if (!options) {
+ g_free (option_string);
+ continue;
+ }
+ nm_dhcp_option_take_option (options,
+ _nm_dhcp_option_dhcp4_options,
+ private_options[i].code,
+ option_string);
+ }
+ }
NM_SET_OUT (out_options, g_steal_pointer (&options));
return g_steal_pointer (&ip4_config);
}
@@ -627,7 +600,7 @@ bound4_handle (NMDhcpSystemd *self)
return;
}
- add_requests_to_options (options, dhcp4_requests);
+ nm_dhcp_option_add_requests_to_options (options, _nm_dhcp_option_dhcp4_options);
dhcp_lease_save (lease, priv->lease_file);
nm_dhcp_client_set_state (NM_DHCP_CLIENT (self),
@@ -780,10 +753,10 @@ ip4_start (NMDhcpClient *client,
}
/* Add requested options */
- for (i = 0; dhcp4_requests[i].name; i++) {
- if (dhcp4_requests[i].include) {
- nm_assert (dhcp4_requests[i].option_num <= 255);
- r = sd_dhcp_client_set_request_option (sd_client, dhcp4_requests[i].option_num);
+ for (i = 0; _nm_dhcp_option_dhcp4_options[i].name; i++) {
+ if (_nm_dhcp_option_dhcp4_options[i].include) {
+ nm_assert (_nm_dhcp_option_dhcp4_options[i].option_num <= 255);
+ r = sd_dhcp_client_set_request_option (sd_client, _nm_dhcp_option_dhcp4_options[i].option_num);
nm_assert (r >= 0 || r == -EEXIST);
}
}
@@ -850,7 +823,7 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
ip6_config = nm_ip6_config_new (multi_idx, ifindex);
- options = out_options ? create_options_dict () : NULL;
+ options = out_options ? nm_dhcp_option_create_options_dict () : NULL;
sd_dhcp6_lease_reset_address_iter (lease);
nm_gstring_prepare (&str);
@@ -870,12 +843,15 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
nm_utils_inet6_ntop (&tmp_addr, addr_str);
g_string_append (nm_gstring_add_space_delimiter (str), addr_str);
- LOG_LEASE (LOGD_DHCP6,
- "address %s",
+ LOG_LEASE (LOGD_DHCP6, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp6_options, NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS),
nm_platform_ip6_address_to_string (&address, sbuf, sizeof (sbuf)));
};
if (str->len)
- add_option (options, dhcp6_requests, DHCP6_OPTION_IP_ADDRESS, str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp6_options,
+ NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS,
+ str->str);
if ( !info_only
&& nm_ip6_config_get_num_addresses (ip6_config) == 0) {
@@ -894,8 +870,13 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
g_string_append (nm_gstring_add_space_delimiter (str), addr_str);
nm_ip6_config_add_nameserver (ip6_config, &dns[i]);
}
- LOG_LEASE (LOGD_DHCP6, "nameserver %s", str->str);
- add_option (options, dhcp6_requests, SD_DHCP6_OPTION_DNS_SERVERS, str->str);
+ LOG_LEASE (LOGD_DHCP6, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp6_options, NM_DHCP_OPTION_DHCP6_DNS_SERVERS),
+ str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp6_options,
+ NM_DHCP_OPTION_DHCP6_DNS_SERVERS,
+ str->str);
}
num = sd_dhcp6_lease_get_domains (lease, &domains);
@@ -905,8 +886,13 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx,
g_string_append (nm_gstring_add_space_delimiter (str), domains[i]);
nm_ip6_config_add_search (ip6_config, domains[i]);
}
- LOG_LEASE (LOGD_DHCP6, "domain name '%s'", str->str);
- add_option (options, dhcp6_requests, SD_DHCP6_OPTION_DOMAIN_LIST, str->str);
+ LOG_LEASE (LOGD_DHCP6, "%s '%s'",
+ nm_dhcp_option_request_string (_nm_dhcp_option_dhcp6_options, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST),
+ str->str);
+ nm_dhcp_option_add_option (options,
+ _nm_dhcp_option_dhcp6_options,
+ NM_DHCP_OPTION_DHCP6_DOMAIN_LIST,
+ str->str);
}
NM_SET_OUT (out_options, g_steal_pointer (&options));
@@ -1079,9 +1065,9 @@ ip6_start (NMDhcpClient *client,
}
/* Add requested options */
- for (i = 0; dhcp6_requests[i].name; i++) {
- if (dhcp6_requests[i].include) {
- r = sd_dhcp6_client_set_request_option (sd_client, dhcp6_requests[i].option_num);
+ for (i = 0; _nm_dhcp_option_dhcp6_options[i].name; i++) {
+ if (_nm_dhcp_option_dhcp6_options[i].include) {
+ r = sd_dhcp6_client_set_request_option (sd_client, _nm_dhcp_option_dhcp6_options[i].option_num);
nm_assert (r >= 0 || r == -EEXIST);
}
}
diff --git a/src/meson.build b/src/meson.build
index af0bcec99c..aec6eceb44 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -25,6 +25,7 @@ sources = files(
'dhcp/nm-dhcp-nettools.c',
'dhcp/nm-dhcp-systemd.c',
'dhcp/nm-dhcp-utils.c',
+ 'dhcp/nm-dhcp-options.c',
'ndisc/nm-lndp-ndisc.c',
'ndisc/nm-ndisc.c',
'platform/nm-netlink.c',
diff --git a/src/systemd/meson.build b/src/systemd/meson.build
index 599c95e8a4..af1d0c8b35 100644
--- a/src/systemd/meson.build
+++ b/src/systemd/meson.build
@@ -25,6 +25,7 @@ libnm_systemd_core = static_library(
'src/libsystemd/sd-id128/sd-id128.c',
'nm-sd.c',
'nm-sd-utils-core.c',
+ 'nm-sd-utils-dhcp.c',
),
include_directories: [
src_inc,
diff --git a/src/systemd/nm-sd-utils-dhcp.c b/src/systemd/nm-sd-utils-dhcp.c
new file mode 100644
index 0000000000..49a924b62c
--- /dev/null
+++ b/src/systemd/nm-sd-utils-dhcp.c
@@ -0,0 +1,54 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2019 Red Hat, Inc.
+ */
+
+#include "nm-default.h"
+
+#include "nm-sd-utils-dhcp.h"
+
+#include "sd-adapt-core/nm-sd-adapt-core.h"
+#include "src/libsystemd-network/dhcp-lease-internal.h"
+
+int
+nm_sd_dhcp_lease_get_private_options (sd_dhcp_lease *lease, nm_sd_dhcp_option **out_options)
+{
+ struct sd_dhcp_raw_option *raw_option;
+ int cnt = 0;
+
+ g_return_val_if_fail (lease, -EINVAL);
+ g_return_val_if_fail (out_options, -EINVAL);
+ g_return_val_if_fail (*out_options == NULL, -EINVAL);
+
+ if (lease->private_options == NULL)
+ return -ENODATA;
+
+ LIST_FOREACH (options, raw_option, lease->private_options)
+ cnt++;
+
+ *out_options = g_new (nm_sd_dhcp_option, cnt);
+ cnt = 0;
+
+ LIST_FOREACH (options, raw_option, lease->private_options) {
+ (*out_options)[cnt].code = raw_option->tag;
+ (*out_options)[cnt].data = raw_option->data;
+ (*out_options)[cnt].data_len = raw_option->length;
+ cnt++;
+ }
+
+ return cnt;
+}
diff --git a/src/systemd/nm-sd-utils-dhcp.h b/src/systemd/nm-sd-utils-dhcp.h
new file mode 100644
index 0000000000..496bf374ac
--- /dev/null
+++ b/src/systemd/nm-sd-utils-dhcp.h
@@ -0,0 +1,34 @@
+/*
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+ * Boston, MA 02110-1301 USA.
+ *
+ * (C) Copyright 2019 Red Hat, Inc.
+ */
+
+#ifndef __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__
+#define __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__
+
+#include "nm-sd.h"
+
+typedef struct {
+ uint8_t code;
+ uint8_t data_len;
+ void *data;
+} nm_sd_dhcp_option;
+
+int
+nm_sd_dhcp_lease_get_private_options (sd_dhcp_lease *lease, nm_sd_dhcp_option **out_options);
+
+#endif /* __NETWORKMANAGER_DHCP_SYSTEMD_UTILS_H__ */