diff options
| author | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2020-06-28 18:58:14 +0200 |
| commit | a54ac63bbf9b2c71026ac9028a8ffaf186cf3c82 (patch) | |
| tree | 6a32883bd916c4096357b35298beff6db8bcd0b5 /src/dhcp | |
| parent | 45e8e1149027529194982212c804c0468aa01d98 (diff) | |
New upstream version 1.25.90 upstream/1.25.90
Diffstat (limited to 'src/dhcp')
| -rw-r--r-- | src/dhcp/nm-dhcp-client.c | 21 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-client.h | 2 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.c | 22 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient-utils.h | 1 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-dhclient.c | 6 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-helper.c | 47 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-manager.c | 6 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-manager.h | 2 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-nettools.c | 96 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-options.c | 2 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-options.h | 2 | ||||
| -rw-r--r-- | src/dhcp/nm-dhcp-systemd.c | 23 | ||||
| -rw-r--r-- | src/dhcp/tests/test-dhcp-dhclient.c | 59 |
13 files changed, 230 insertions, 59 deletions
diff --git a/src/dhcp/nm-dhcp-client.c b/src/dhcp/nm-dhcp-client.c index 90a64aca..f7324baf 100644 --- a/src/dhcp/nm-dhcp-client.c +++ b/src/dhcp/nm-dhcp-client.c @@ -50,6 +50,7 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMDhcpClient, PROP_IAID_EXPLICIT, PROP_HOSTNAME, PROP_HOSTNAME_FLAGS, + PROP_MUD_URL, ); typedef struct _NMDhcpClientPrivate { @@ -60,6 +61,7 @@ typedef struct _NMDhcpClientPrivate { char * uuid; GBytes * client_id; char * hostname; + char * mud_url; pid_t pid; guint timeout_id; guint watch_id; @@ -312,6 +314,14 @@ nm_dhcp_client_get_use_fqdn (NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE (self)->use_fqdn; } +const char * +nm_dhcp_client_get_mud_url (NMDhcpClient *self) +{ + g_return_val_if_fail (NM_IS_DHCP_CLIENT (self), NULL); + + return NM_DHCP_CLIENT_GET_PRIVATE (self)->mud_url; +} + /*****************************************************************************/ static const char *state_table[NM_DHCP_STATE_MAX + 1] = { @@ -1052,6 +1062,10 @@ set_property (GObject *object, guint prop_id, /* construct-only */ priv->hostname_flags = g_value_get_uint (value); break; + case PROP_MUD_URL: + /* construct-only */ + priv->mud_url = g_value_dup_string (value); + break; case PROP_ROUTE_TABLE: priv->route_table = g_value_get_uint (value); break; @@ -1102,6 +1116,7 @@ dispose (GObject *object) nm_clear_g_free (&priv->iface); nm_clear_g_free (&priv->hostname); nm_clear_g_free (&priv->uuid); + nm_clear_g_free (&priv->mud_url); nm_clear_pointer (&priv->client_id, g_bytes_unref); nm_clear_pointer (&priv->hwaddr, g_bytes_unref); nm_clear_pointer (&priv->bcast_hwaddr, g_bytes_unref); @@ -1191,6 +1206,12 @@ nm_dhcp_client_class_init (NMDhcpClientClass *client_class) G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_MUD_URL] = + g_param_spec_string (NM_DHCP_CLIENT_MUD_URL, "", "", + NULL, + G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_ROUTE_TABLE] = g_param_spec_uint (NM_DHCP_CLIENT_ROUTE_TABLE, "", "", 0, G_MAXUINT32, RT_TABLE_MAIN, diff --git a/src/dhcp/nm-dhcp-client.h b/src/dhcp/nm-dhcp-client.h index 1ff09067..479ea000 100644 --- a/src/dhcp/nm-dhcp-client.h +++ b/src/dhcp/nm-dhcp-client.h @@ -30,6 +30,7 @@ #define NM_DHCP_CLIENT_INTERFACE "iface" #define NM_DHCP_CLIENT_MULTI_IDX "multi-idx" #define NM_DHCP_CLIENT_HOSTNAME "hostname" +#define NM_DHCP_CLIENT_MUD_URL "mud-url" #define NM_DHCP_CLIENT_ROUTE_METRIC "route-metric" #define NM_DHCP_CLIENT_ROUTE_TABLE "route-table" #define NM_DHCP_CLIENT_TIMEOUT "timeout" @@ -141,6 +142,7 @@ gboolean nm_dhcp_client_get_iaid_explicit (NMDhcpClient *self); GBytes *nm_dhcp_client_get_client_id (NMDhcpClient *self); const char *nm_dhcp_client_get_hostname (NMDhcpClient *self); +const char *nm_dhcp_client_get_mud_url (NMDhcpClient *self); NMDhcpHostnameFlags nm_dhcp_client_get_hostname_flags (NMDhcpClient *self); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.c b/src/dhcp/nm-dhcp-dhclient-utils.c index da28abad..76fc1a89 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.c +++ b/src/dhcp/nm-dhcp-dhclient-utils.c @@ -33,6 +33,13 @@ #define ALSOREQ_TAG "also request " #define REQ_TAG "request " +#define MUDURLv4_DEF "option mudurl code 161 = text;\n" +#define MUDURLv4_FMT "send mudurl \"%s\";\n" + +#define MUDURLv6_DEF "option dhcp6.mudurl code 112 = text;\n" +#define MUDURLv6_FMT "send dhcp6.mudurl \"%s\";\n" + + static void add_request (GPtrArray *array, const char *item) { @@ -183,6 +190,19 @@ add_hostname6 (GString *str, } } +static void add_mud_url_config(GString *str, const char *mud_url, int addr_family) +{ + if (mud_url) { + if (addr_family == AF_INET) { + g_string_append (str, MUDURLv4_DEF); + g_string_append_printf (str, MUDURLv4_FMT, mud_url); + } else { + g_string_append (str, MUDURLv6_DEF); + g_string_append_printf (str, MUDURLv6_FMT, mud_url); + } + } +} + static GBytes * read_client_id (const char *str) { @@ -286,6 +306,7 @@ nm_dhcp_dhclient_create_config (const char *interface, guint32 timeout, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id) @@ -451,6 +472,7 @@ nm_dhcp_dhclient_create_config (const char *interface, g_string_append_printf (new_contents, "timeout %u;\n", timeout); } + add_mud_url_config (new_contents, mud_url, addr_family); if (addr_family == AF_INET) { add_ip4_config (new_contents, client_id, hostname, use_fqdn, hostname_flags); add_request (reqs, "rfc3442-classless-static-routes"); diff --git a/src/dhcp/nm-dhcp-dhclient-utils.h b/src/dhcp/nm-dhcp-dhclient-utils.h index 0cf53887..5094d614 100644 --- a/src/dhcp/nm-dhcp-dhclient-utils.h +++ b/src/dhcp/nm-dhcp-dhclient-utils.h @@ -17,6 +17,7 @@ char *nm_dhcp_dhclient_create_config (const char *interface, guint32 timeout, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, const char *orig_path, const char *orig_contents, GBytes **out_new_client_id); diff --git a/src/dhcp/nm-dhcp-dhclient.c b/src/dhcp/nm-dhcp-dhclient.c index 617ce236..4ad056e5 100644 --- a/src/dhcp/nm-dhcp-dhclient.c +++ b/src/dhcp/nm-dhcp-dhclient.c @@ -147,6 +147,7 @@ merge_dhclient_config (NMDhcpDhclient *self, guint32 timeout, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, const char *orig_path, GBytes **out_new_client_id, GError **error) @@ -176,6 +177,7 @@ merge_dhclient_config (NMDhcpDhclient *self, timeout, use_fqdn, hostname_flags, + mud_url, orig_path, orig, out_new_client_id); @@ -268,6 +270,7 @@ create_dhclient_config (NMDhcpDhclient *self, guint32 timeout, gboolean use_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, GBytes **out_new_client_id) { gs_free char *orig = NULL; @@ -296,6 +299,7 @@ create_dhclient_config (NMDhcpDhclient *self, timeout, use_fqdn, hostname_flags, + mud_url, orig, out_new_client_id, &error)) { @@ -496,6 +500,7 @@ ip4_start (NMDhcpClient *client, nm_dhcp_client_get_timeout (client), nm_dhcp_client_get_use_fqdn (client), nm_dhcp_client_get_hostname_flags (client), + nm_dhcp_client_get_mud_url (client), &new_client_id); if (!priv->conf_file) { nm_utils_error_set_literal (error, @@ -540,6 +545,7 @@ ip6_start (NMDhcpClient *client, nm_dhcp_client_get_timeout (client), TRUE, nm_dhcp_client_get_hostname_flags (client), + nm_dhcp_client_get_mud_url (client), NULL); if (!priv->conf_file) { nm_utils_error_set_literal (error, diff --git a/src/dhcp/nm-dhcp-helper.c b/src/dhcp/nm-dhcp-helper.c index 365e32e3..071d331b 100644 --- a/src/dhcp/nm-dhcp-helper.c +++ b/src/dhcp/nm-dhcp-helper.c @@ -46,33 +46,46 @@ /*****************************************************************************/ -static const char * ignore[] = {"PATH", "SHLVL", "_", "PWD", "dhc_dbus", NULL}; - static GVariant * build_signal_parameters (void) { - char **item; + const char *const*environ_iter; GVariantBuilder builder; g_variant_builder_init (&builder, G_VARIANT_TYPE_VARDICT); /* List environment and format for dbus dict */ - for (item = environ; *item; item++) { - char *name, *val, **p; - - /* Split on the = */ - name = g_strdup (*item); - val = strchr (name, '='); - if (!val || val == name) - goto next; - *val++ = '\0'; - - /* Ignore non-DCHP-related environment variables */ - for (p = (char **) ignore; *p; p++) { + for (environ_iter = (const char *const*) environ; *environ_iter; environ_iter++) { + static const char *const ignore_with_prefix_list[] = { + "PATH", + "SHLVL", + "_", + "PWD", + "dhc_dbus", + NULL + }; + const char *item = *environ_iter; + gs_free char *name = NULL; + const char *val; + const char *const*p; + + val = strchr (item, '='); + if ( !val + || item == val) + continue; + + name = g_strndup (item, val - item); + val += 1; + + /* Ignore non-DHCP-related environment variables */ + for (p = ignore_with_prefix_list; *p; p++) { if (strncmp (name, *p, strlen (*p)) == 0) goto next; } + if (!g_utf8_validate (name, -1, NULL)) + continue; + /* Value passed as a byte array rather than a string, because there are * no character encoding guarantees with DHCP, and D-Bus requires * strings to be UTF-8. @@ -85,8 +98,8 @@ build_signal_parameters (void) g_variant_new_fixed_array (G_VARIANT_TYPE_BYTE, val, strlen (val), 1)); - next: - g_free (name); +next: + ; } return g_variant_ref_sink (g_variant_new ("(a{sv})", &builder)); diff --git a/src/dhcp/nm-dhcp-manager.c b/src/dhcp/nm-dhcp-manager.c index 333744dd..7565bfc8 100644 --- a/src/dhcp/nm-dhcp-manager.c +++ b/src/dhcp/nm-dhcp-manager.c @@ -220,6 +220,7 @@ client_start (NMDhcpManager *self, const char *hostname, gboolean hostname_use_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, gboolean info_only, NMSettingIP6ConfigPrivacy privacy, const char *last_ip4_address, @@ -303,6 +304,7 @@ client_start (NMDhcpManager *self, NM_DHCP_CLIENT_IAID, (guint) iaid, NM_DHCP_CLIENT_IAID_EXPLICIT, iaid_explicit, NM_DHCP_CLIENT_HOSTNAME, hostname, + NM_DHCP_CLIENT_MUD_URL, mud_url, NM_DHCP_CLIENT_ROUTE_TABLE, (guint) route_table, NM_DHCP_CLIENT_ROUTE_METRIC, (guint) route_metric, NM_DHCP_CLIENT_TIMEOUT, (guint) timeout, @@ -382,6 +384,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, const char *dhcp_hostname, const char *dhcp_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, @@ -440,6 +443,7 @@ nm_dhcp_manager_start_ip4 (NMDhcpManager *self, hostname, use_fqdn, hostname_flags, + mud_url, FALSE, 0, last_ip_address, @@ -462,6 +466,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, gboolean send_hostname, const char *dhcp_hostname, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, GBytes *duid, gboolean enforce_duid, guint32 iaid, @@ -503,6 +508,7 @@ nm_dhcp_manager_start_ip6 (NMDhcpManager *self, hostname, TRUE, hostname_flags, + mud_url, info_only, privacy, NULL, diff --git a/src/dhcp/nm-dhcp-manager.h b/src/dhcp/nm-dhcp-manager.h index 1b793c22..88435282 100644 --- a/src/dhcp/nm-dhcp-manager.h +++ b/src/dhcp/nm-dhcp-manager.h @@ -43,6 +43,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip4 (NMDhcpManager *manager, const char *dhcp_hostname, const char *dhcp_fqdn, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, GBytes *dhcp_client_id, guint32 timeout, const char *dhcp_anycast_addr, @@ -62,6 +63,7 @@ NMDhcpClient * nm_dhcp_manager_start_ip6 (NMDhcpManager *manager, gboolean send_hostname, const char *dhcp_hostname, NMDhcpHostnameFlags hostname_flags, + const char *mud_url, GBytes *duid, gboolean enforce_duid, guint32 iaid, diff --git a/src/dhcp/nm-dhcp-nettools.c b/src/dhcp/nm-dhcp-nettools.c index 00b416da..fe6a4582 100644 --- a/src/dhcp/nm-dhcp-nettools.c +++ b/src/dhcp/nm-dhcp-nettools.c @@ -68,6 +68,20 @@ G_DEFINE_TYPE (NMDhcpNettools, nm_dhcp_nettools, NM_TYPE_DHCP_CLIENT) /*****************************************************************************/ +static void +set_error_nettools (GError **error, int r, const char *message) +{ + /* the error code returned from n_dhcp4_* API is either a negative + * errno, or a positive internal error code. Generate different messages + * for these. */ + if (r < 0) + nm_utils_error_set_errno (error, r, "%s: %s", message); + else + nm_utils_error_set (error, r, "%s (code %d)", message, r); +} + +/*****************************************************************************/ + #define DHCP_MAX_FQDN_LENGTH 255 enum { @@ -681,11 +695,10 @@ lease_parse_metered (NDhcp4ClientLease *lease, int r; r = n_dhcp4_client_lease_query (lease, NM_DHCP_OPTION_DHCP4_VENDOR_SPECIFIC, &data, &n_data); - if (r) { + if (r) metered = FALSE; - } else { + else metered = !!memmem (data, n_data, "ANDROID_METERED", NM_STRLEN ("ANDROID_METERED")); - } /* TODO: expose the vendor specific option when present */ nm_ip4_config_set_metered (ip4_config, metered); @@ -1023,9 +1036,8 @@ dhcp4_event_handle (NMDhcpNettools *self, case N_DHCP4_CLIENT_EVENT_OFFER: /* always accept the first lease */ r = n_dhcp4_client_lease_select (event->offer.lease); - if (r) { + if (r) _LOGW ("selecting lease failed: %d", r); - } break; case N_DHCP4_CLIENT_EVENT_RETRACTED: case N_DHCP4_CLIENT_EVENT_EXPIRED: @@ -1044,6 +1056,18 @@ dhcp4_event_handle (NMDhcpNettools *self, case N_DHCP4_CLIENT_EVENT_DOWN: /* ignore down events, they are purely informational */ break; + case N_DHCP4_CLIENT_EVENT_LOG: { + NMLogLevel nm_level; + + nm_level = nm_log_level_from_syslog (event->log.level); + if (nm_logging_enabled (nm_level, LOGD_DHCP4)) { + nm_log (nm_level, LOGD_DHCP4, NULL , NULL, + "dhcp4 (%s): %s", + nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)), + event->log.message); + } + } + break; default: _LOGW ("unhandled DHCP event %d", event->event); break; @@ -1084,27 +1108,6 @@ dhcp4_event_cb (int fd, return G_SOURCE_CONTINUE; } -G_GNUC_PRINTF (3, 4) -static void -nettools_log (int level, void *data, const char *fmt, ...) -{ - NMDhcpNettools *self = data; - NMLogLevel nm_level; - gs_free char *msg = NULL; - va_list ap; - - nm_level = nm_log_level_from_syslog (level); - if (nm_logging_enabled (nm_level, LOGD_DHCP4)) { - va_start (ap, fmt); - msg = g_strdup_vprintf (fmt, ap); - va_end (ap); - nm_log (nm_level, LOGD_DHCP4, NULL , NULL, - "dhcp4 (%s): %s", - nm_dhcp_client_get_iface (NM_DHCP_CLIENT (self)), - msg); - } -} - static gboolean nettools_create (NMDhcpNettools *self, const char *dhcp_anycast_addr, @@ -1170,12 +1173,10 @@ nettools_create (NMDhcpNettools *self, r = n_dhcp4_client_config_new (&config); if (r) { - nm_utils_error_set_errno (error, r, "failed to create client-config: %s"); + set_error_nettools (error, r, "failed to create client-config"); return FALSE; } - n_dhcp4_client_config_set_log_level (config, nm_log_level_to_syslog (nm_logging_get_level (LOGD_DHCP4))); - n_dhcp4_client_config_set_log_func (config, nettools_log, self); n_dhcp4_client_config_set_ifindex (config, nm_dhcp_client_get_ifindex (NM_DHCP_CLIENT (self))); n_dhcp4_client_config_set_transport (config, transport); n_dhcp4_client_config_set_mac (config, hwaddr_arr, hwaddr_len); @@ -1184,19 +1185,21 @@ nettools_create (NMDhcpNettools *self, client_id_arr, NM_MIN (client_id_len, 1 + _NM_SD_MAX_CLIENT_ID_LEN)); if (r) { - nm_utils_error_set_errno (error, r, "failed to set client-id: %s"); + set_error_nettools (error, r, "failed to set client-id"); return FALSE; } r = n_dhcp4_client_new (&client, config); if (r) { - nm_utils_error_set (error, NM_UTILS_ERROR_UNKNOWN, "failed to create client: error %d", r); + set_error_nettools (error, r, "failed to create client"); return FALSE; } priv->client = client; client = NULL; + n_dhcp4_client_set_log_level (priv->client, nm_log_level_to_syslog (nm_logging_get_level (LOGD_DHCP4))); + n_dhcp4_client_get_fd (priv->client, &fd); priv->event_source = nm_g_unix_fd_source_new (fd, @@ -1224,7 +1227,7 @@ _accept (NMDhcpClient *client, r = n_dhcp4_client_lease_accept (priv->lease); if (r) { - nm_utils_error_set_errno (error, r, "failed to accept lease: %s"); + set_error_nettools (error, r, "failed to accept lease"); return FALSE; } @@ -1248,7 +1251,7 @@ decline (NMDhcpClient *client, r = n_dhcp4_client_lease_decline (priv->lease, error_message); if (r) { - nm_utils_error_set_errno (error, r, "failed to decline lease: %s"); + set_error_nettools (error, r, "failed to decline lease"); return FALSE; } @@ -1285,6 +1288,7 @@ ip4_start (NMDhcpClient *client, gs_free char *lease_file = NULL; struct in_addr last_addr = { 0 }; const char *hostname; + const char *mud_url; int r, i; g_return_val_if_fail (!priv->probe, FALSE); @@ -1294,7 +1298,7 @@ ip4_start (NMDhcpClient *client, r = n_dhcp4_client_probe_config_new (&config); if (r) { - nm_utils_error_set_errno (error, r, "failed to create dhcp-client-probe-config: %s"); + set_error_nettools (error, r, "failed to create dhcp-client-probe-config"); return FALSE; } @@ -1341,6 +1345,17 @@ ip4_start (NMDhcpClient *client, } } + mud_url = nm_dhcp_client_get_mud_url (client); + if (mud_url) { + r = n_dhcp4_client_probe_config_append_option (config, + NM_DHCP_OPTION_DHCP4_MUD_URL, + mud_url, + strlen (mud_url)); + if (r) { + set_error_nettools (error, r, "failed to set MUD URL"); + return FALSE; + } + } hostname = nm_dhcp_client_get_hostname (client); if (hostname) { if (nm_dhcp_client_get_use_fqdn (client)) { @@ -1359,7 +1374,10 @@ ip4_start (NMDhcpClient *client, sizeof (buffer) - 3, FALSE); if (r <= 0) { - nm_utils_error_set_errno (error, r, "failed to convert DHCP FQDN: %s"); + if (r < 0) + nm_utils_error_set_errno (error, r, "failed to convert DHCP FQDN: %s"); + else + nm_utils_error_set (error, r, "failed to convert DHCP FQDN"); return FALSE; } fqdn_len = r; @@ -1377,7 +1395,7 @@ ip4_start (NMDhcpClient *client, buffer, 3 + fqdn_len); if (r) { - nm_utils_error_set_errno (error, r, "failed to set DHCP FQDN: %s"); + set_error_nettools (error, r, "failed to set DHCP FQDN"); return FALSE; } } else { @@ -1386,7 +1404,7 @@ ip4_start (NMDhcpClient *client, hostname, strlen (hostname)); if (r) { - nm_utils_error_set_errno (error, r, "failed to set DHCP hostname: %s"); + set_error_nettools (error, r, "failed to set DHCP hostname"); return FALSE; } } @@ -1397,7 +1415,7 @@ ip4_start (NMDhcpClient *client, r = n_dhcp4_client_probe (priv->client, &priv->probe, config); if (r) { - nm_utils_error_set_errno (error, r, "failed to start DHCP client: %s"); + set_error_nettools (error, r, "failed to start DHCP client"); return FALSE; } @@ -1434,7 +1452,7 @@ dispose (GObject *object) { NMDhcpNettoolsPrivate *priv = NM_DHCP_NETTOOLS_GET_PRIVATE (object); - nm_clear_pointer (&priv->lease_file, g_free); + nm_clear_g_free (&priv->lease_file); nm_clear_g_source_inst (&priv->event_source); nm_clear_pointer (&priv->lease, n_dhcp4_client_lease_unref); nm_clear_pointer (&priv->probe, n_dhcp4_client_probe_free); diff --git a/src/dhcp/nm-dhcp-options.c b/src/dhcp/nm-dhcp-options.c index 1d391f3e..b10635fc 100644 --- a/src/dhcp/nm-dhcp-options.c +++ b/src/dhcp/nm-dhcp-options.c @@ -126,6 +126,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp4_options[] = { 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_MUD_URL, "mud_url", 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 ), @@ -182,6 +183,7 @@ const NMDhcpOption _nm_dhcp_option_dhcp6_options[] = { 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 ), + REQ (NM_DHCP_OPTION_DHCP6_MUD_URL, "dhcp6_mud_url", FALSE ), /* Internal values */ REQ (NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS, "ip6_address", FALSE ), diff --git a/src/dhcp/nm-dhcp-options.h b/src/dhcp/nm-dhcp-options.h index bf9ccd57..7c012170 100644 --- a/src/dhcp/nm-dhcp-options.h +++ b/src/dhcp/nm-dhcp-options.h @@ -110,6 +110,7 @@ typedef enum { 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_MUD_URL = 161, NM_DHCP_OPTION_DHCP4_LOADER_CONFIGFILE = 209, NM_DHCP_OPTION_DHCP4_LOADER_PATHPREFIX = 210, NM_DHCP_OPTION_DHCP4_LOADER_REBOOTTIME = 211, @@ -159,6 +160,7 @@ typedef enum { NM_DHCP_OPTION_DHCP6_DNS_SERVERS = 23, NM_DHCP_OPTION_DHCP6_DOMAIN_LIST = 24, NM_DHCP_OPTION_DHCP6_SNTP_SERVERS = 31, + NM_DHCP_OPTION_DHCP6_MUD_URL = 112, /* Internal values */ NM_DHCP_OPTION_DHCP6_NM_IP_ADDRESS = 1026, NM_DHCP_OPTION_DHCP6_NM_PREFIXLEN = 1027, diff --git a/src/dhcp/nm-dhcp-systemd.c b/src/dhcp/nm-dhcp-systemd.c index 23862e9e..f65937d8 100644 --- a/src/dhcp/nm-dhcp-systemd.c +++ b/src/dhcp/nm-dhcp-systemd.c @@ -573,6 +573,7 @@ ip4_start (NMDhcpClient *client, size_t client_id_len; struct in_addr last_addr = { 0 }; const char *hostname; + const char *mud_url; int r, i; g_return_val_if_fail (!priv->client4, FALSE); @@ -688,6 +689,15 @@ ip4_start (NMDhcpClient *client, } } + mud_url = nm_dhcp_client_get_mud_url (client); + if (mud_url) { + r = sd_dhcp_client_set_mud_url (sd_client, mud_url); + if (r < 0) { + nm_utils_error_set_errno (error, r, "failed to set DHCP MUDURL: %s"); + return FALSE; + } + } + r = sd_dhcp_client_set_callback (sd_client, dhcp_event_cb, client); if (r < 0) { nm_utils_error_set_errno (error, r, "failed to set callback: %s"); @@ -725,7 +735,8 @@ lease_to_ip6_config (NMDedupMultiIndex *multi_idx, { gs_unref_object NMIP6Config *ip6_config = NULL; gs_unref_hashtable GHashTable *options = NULL; - struct in6_addr tmp_addr, *dns; + struct in6_addr tmp_addr; + const struct in6_addr *dns; uint32_t lft_pref, lft_valid; char addr_str[NM_UTILS_INET_ADDRSTRLEN]; char **domains; @@ -894,6 +905,7 @@ ip6_start (NMDhcpClient *client, nm_auto (sd_dhcp6_client_unrefp) sd_dhcp6_client *sd_client = NULL; GBytes *hwaddr; const char *hostname; + const char *mud_url; int r, i; const guint8 *duid_arr; gsize duid_len; @@ -976,6 +988,15 @@ ip6_start (NMDhcpClient *client, } } + mud_url = nm_dhcp_client_get_mud_url (client); + if (mud_url) { + r = sd_dhcp6_client_set_request_mud_url (sd_client, mud_url); + if (r < 0) { + nm_utils_error_set_errno (error, r, "failed to set mud-url: %s"); + return FALSE; + } + } + if (needed_prefixes > 0) { if (needed_prefixes > 1) _LOGW ("dhcp-client6: only one prefix request is supported"); diff --git a/src/dhcp/tests/test-dhcp-dhclient.c b/src/dhcp/tests/test-dhcp-dhclient.c index 761f9cdb..d51bcae5 100644 --- a/src/dhcp/tests/test-dhcp-dhclient.c +++ b/src/dhcp/tests/test-dhcp-dhclient.c @@ -21,6 +21,7 @@ #include "nm-test-utils-core.h" #define TEST_DIR NM_BUILD_SRCDIR"/src/dhcp/tests" +#define TEST_MUDURL "https://example.com/mud.json" static void test_config (const char *orig, @@ -33,7 +34,8 @@ test_config (const char *orig, const char *dhcp_client_id, GBytes *expected_new_client_id, const char *iface, - const char *anycast_addr) + const char *anycast_addr, + const char *mud_url) { gs_free char *new = NULL; gs_unref_bytes GBytes *client_id = NULL; @@ -52,6 +54,7 @@ test_config (const char *orig, timeout, use_fqdn, hostname_flags, + mud_url, "/path/to/dhclient.conf", orig, &new_client_id); @@ -100,7 +103,37 @@ test_orig_missing (void) orig_missing_expected, AF_INET, NULL, 0, FALSE, NM_DHCP_HOSTNAME_FLAG_NONE, - NULL, NULL, "eth0", NULL); + NULL, NULL, "eth0", NULL, NULL); +} + +/*****************************************************************************/ + + +static const char *orig_missing_add_mud_url_expected = \ + "# Created by NetworkManager\n" + "\n" + "option mudurl code 161 = text;\n" + "send mudurl \"https://example.com/mud.json\";\n\n" + "option rfc3442-classless-static-routes code 121 = array of unsigned integer 8;\n" + "option ms-classless-static-routes code 249 = array of unsigned integer 8;\n" + "option wpad code 252 = string;\n" + "\n" + "also request rfc3442-classless-static-routes;\n" + "also request ms-classless-static-routes;\n" + "also request static-routes;\n" + "also request wpad;\n" + "also request ntp-servers;\n" + "also request root-path;\n" + "\n"; + +static void +test_orig_missing_add_mud_url (void) +{ + test_config (NULL, + orig_missing_add_mud_url_expected, + AF_INET, NULL, 0, FALSE, + NM_DHCP_HOSTNAME_FLAG_NONE, + NULL, NULL, "eth0", NULL, TEST_MUDURL); } /*****************************************************************************/ @@ -135,6 +168,7 @@ test_override_client_id (void) "11:22:33:44:55:66", NULL, "eth0", + NULL, NULL); } @@ -166,6 +200,7 @@ test_quote_client_id (void) "abcd", NULL, "eth0", + NULL, NULL); } @@ -197,6 +232,7 @@ test_quote_client_id_2 (void) "a\\bc", NULL, "eth0", + NULL, NULL); } @@ -228,6 +264,7 @@ test_hex_zero_client_id (void) "00:11:22:33", NULL, "eth0", + NULL, NULL); } @@ -259,6 +296,7 @@ test_ascii_client_id (void) "qb:cd:ef:12:34:56", NULL, "eth0", + NULL, NULL); } @@ -290,6 +328,7 @@ test_hex_single_client_id (void) "ab:cd:e:12:34:56", NULL, "eth0", + NULL, NULL); } @@ -329,6 +368,7 @@ test_existing_hex_client_id (void) NULL, new_client_id, "eth0", + NULL, NULL); } @@ -367,6 +407,7 @@ test_existing_escaped_client_id (void) NULL, new_client_id, "eth0", + NULL, NULL); } @@ -409,6 +450,7 @@ test_existing_ascii_client_id (void) NULL, new_client_id, "eth0", + NULL, NULL); } /*****************************************************************************/ @@ -443,6 +485,7 @@ test_fqdn (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -486,6 +529,7 @@ test_fqdn_options_override (void) TRUE, NULL, NULL, "eth0", + NULL, NULL); } @@ -521,6 +565,7 @@ test_override_hostname (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -550,6 +595,7 @@ test_override_hostname6 (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -576,6 +622,7 @@ test_nonfqdn_hostname6 (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -613,6 +660,7 @@ test_existing_alsoreq (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -653,6 +701,7 @@ test_existing_req (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -694,6 +743,7 @@ test_existing_multiline_alsoreq (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -934,6 +984,7 @@ test_interface1 (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -981,6 +1032,7 @@ test_interface2 (void) NULL, NULL, "eth1", + NULL, NULL); } @@ -1093,6 +1145,7 @@ test_structured (void) NULL, new_client_id, "eth0", + NULL, NULL); } @@ -1149,6 +1202,7 @@ test_config_req_intf (void) NULL, NULL, "eth0", + NULL, NULL); } @@ -1162,6 +1216,7 @@ main (int argc, char **argv) nmtst_init_with_logging (&argc, &argv, NULL, "DEFAULT"); g_test_add_func ("/dhcp/dhclient/orig_missing", test_orig_missing); + g_test_add_func ("/dhcp/dhclient/orig_missing_add_mud_url", test_orig_missing_add_mud_url); g_test_add_func ("/dhcp/dhclient/override_client_id", test_override_client_id); g_test_add_func ("/dhcp/dhclient/quote_client_id/1", test_quote_client_id); g_test_add_func ("/dhcp/dhclient/quote_client_id/2", test_quote_client_id_2); |