diff options
| author | Michael Biebl <biebl@debian.org> | 2022-05-04 15:35:24 +0200 |
|---|---|---|
| committer | Michael Biebl <biebl@debian.org> | 2022-05-04 15:35:24 +0200 |
| commit | 9959fdb2e8ddd06f2161798ca0a39c77d67c652d (patch) | |
| tree | 2ce24a336d2b1c5fd5dec3090db312eded6c78ba /src/core/dhcp | |
| parent | 8c623dddbdebe354cb94bfc559a5371a14865317 (diff) | |
New upstream version 1.37.92 upstream/1.37.92
Diffstat (limited to 'src/core/dhcp')
| -rw-r--r-- | src/core/dhcp/nm-dhcp-client.c | 32 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-dhcpcd.c | 3 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 27 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-systemd.c | 103 | ||||
| -rw-r--r-- | src/core/dhcp/nm-dhcp-utils.c | 38 |
5 files changed, 101 insertions, 102 deletions
diff --git a/src/core/dhcp/nm-dhcp-client.c b/src/core/dhcp/nm-dhcp-client.c index 85e48ff7..2bfd7e01 100644 --- a/src/core/dhcp/nm-dhcp-client.c +++ b/src/core/dhcp/nm-dhcp-client.c @@ -109,25 +109,22 @@ nm_dhcp_client_get_pid(NMDhcpClient *self) return NM_DHCP_CLIENT_GET_PRIVATE(self)->pid; } -static void -_set_effective_client_id(NMDhcpClient *self, GBytes *client_id, gboolean take) +void +nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id) { NMDhcpClientPrivate *priv = NM_DHCP_CLIENT_GET_PRIVATE(self); - nm_assert(!client_id || g_bytes_get_size(client_id) >= 2); + g_return_if_fail(NM_IS_DHCP_CLIENT(self)); + g_return_if_fail(!client_id || g_bytes_get_size(client_id) >= 2); + + priv = NM_DHCP_CLIENT_GET_PRIVATE(self); - if (priv->effective_client_id == client_id - || (priv->effective_client_id && client_id - && g_bytes_equal(priv->effective_client_id, client_id))) { - if (take && client_id) - g_bytes_unref(client_id); + if (nm_g_bytes_equal0(priv->effective_client_id, client_id)) return; - } - if (priv->effective_client_id) - g_bytes_unref(priv->effective_client_id); + g_bytes_unref(priv->effective_client_id); priv->effective_client_id = client_id; - if (!take && client_id) + if (client_id) g_bytes_ref(client_id); { @@ -141,15 +138,6 @@ _set_effective_client_id(NMDhcpClient *self, GBytes *client_id, gboolean take) } } -void -nm_dhcp_client_set_effective_client_id(NMDhcpClient *self, GBytes *client_id) -{ - g_return_if_fail(NM_IS_DHCP_CLIENT(self)); - g_return_if_fail(!client_id || g_bytes_get_size(client_id) >= 2); - - _set_effective_client_id(self, client_id, FALSE); -} - /*****************************************************************************/ NM_UTILS_LOOKUP_STR_DEFINE(nm_dhcp_state_to_string, @@ -678,7 +666,7 @@ nm_dhcp_client_start_ip6(NMDhcpClient *self, GError **error) if (!priv->config.v6.enforce_duid) own_client_id = NM_DHCP_CLIENT_GET_CLASS(self)->get_duid(self); - _set_effective_client_id(self, own_client_id ?: priv->config.client_id, FALSE); + nm_dhcp_client_set_effective_client_id(self, own_client_id ?: priv->config.client_id); addr = ipv6_lladdr_find(self); if (!addr) { diff --git a/src/core/dhcp/nm-dhcp-dhcpcd.c b/src/core/dhcp/nm-dhcp-dhcpcd.c index 4b3429ef..280d9ce6 100644 --- a/src/core/dhcp/nm-dhcp-dhcpcd.c +++ b/src/core/dhcp/nm-dhcp-dhcpcd.c @@ -70,7 +70,7 @@ ip4_start(NMDhcpClient *client, GError **error) const NMDhcpClientConfig *client_config; gs_unref_ptrarray GPtrArray *argv = NULL; pid_t pid; - GError *local = NULL; + gs_free_error GError *local = NULL; gs_free char *cmd_str = NULL; const char *dhcpcd_path; @@ -143,7 +143,6 @@ ip4_start(NMDhcpClient *client, GError **error) NM_UTILS_ERROR_UNKNOWN, "dhcpcd failed to start: %s", local->message); - g_error_free(local); return FALSE; } diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index d7fbe356..aac18967 100644 --- a/src/core/dhcp/nm-dhcp-nettools.c +++ b/src/core/dhcp/nm-dhcp-nettools.c @@ -154,6 +154,7 @@ static gboolean lease_parse_address(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, GHashTable *options, + in_addr_t *out_address, GError **error) { struct in_addr a_address; @@ -268,6 +269,8 @@ lease_parse_address(NDhcp4ClientLease *lease, .preferred = a_lifetime, })); + NM_SET_OUT(out_address, a_address.s_addr); + return TRUE; } @@ -326,6 +329,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease, static void lease_parse_routes(NDhcp4ClientLease *lease, NML3ConfigData *l3cd, + in_addr_t lease_address, GHashTable *options, NMStrBuf *sbuf) { @@ -343,6 +347,17 @@ lease_parse_routes(NDhcp4ClientLease *lease, int r; guint i; + /* Routes can be in option 33 (static-route), 121 (classless-static-route) and 249 (a non-standard classless-static-route). + * Option 249 (Microsoft Classless Static Route), is described here: + * https://docs.microsoft.com/en-us/openspecs/windows_protocols/ms-dhcpe/f9c19c79-1c7f-4746-b555-0c0fc523f3f9 + * + * We will anyway parse all these 3 options and add them to the "options" hash (as distinct entries). + * We will however also parse one of the options into the "l3cd" for configuring routing. + * Thereby we prefer 121 over 249 over 33. + * + * Preferring 121 over 33 is defined by RFC 3443. + * Preferring 121 over 249 over 33 is made up as it makes sense (the MS docs are not very clear). + */ for (i = 0; i < 2; i++) { const guint8 option_code = (i == 0) ? NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE : NM_DHCP_OPTION_DHCP4_PRIVATE_CLASSLESS_STATIC_ROUTE; @@ -373,10 +388,11 @@ lease_parse_routes(NDhcp4ClientLease *lease, nm_l3_config_data_add_route_4(l3cd, &((const NMPlatformIP4Route){ + .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = dest, .plen = plen, .gateway = gateway, - .rt_source = NM_IP_CONFIG_SOURCE_DHCP, + .pref_src = lease_address, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, @@ -416,10 +432,11 @@ lease_parse_routes(NDhcp4ClientLease *lease, nm_l3_config_data_add_route_4(l3cd, &((const NMPlatformIP4Route){ + .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = dest, .plen = plen, .gateway = gateway, - .rt_source = NM_IP_CONFIG_SOURCE_DHCP, + .pref_src = lease_address, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, @@ -464,6 +481,7 @@ lease_parse_routes(NDhcp4ClientLease *lease, &((const NMPlatformIP4Route){ .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .gateway = gateway, + .pref_src = lease_address, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, @@ -547,6 +565,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, const char *v_str; guint16 v_u16; in_addr_t v_inaddr; + in_addr_t lease_address; struct in_addr v_inaddr_s; int r; @@ -556,7 +575,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, options = nm_dhcp_option_create_options_dict(); - if (!lease_parse_address(lease, l3cd, options, error)) + if (!lease_parse_address(lease, l3cd, options, &lease_address, error)) return NULL; r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s); @@ -575,7 +594,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, v_inaddr); } - lease_parse_routes(lease, l3cd, options, &sbuf); + lease_parse_routes(lease, l3cd, lease_address, options, &sbuf); lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options, &sbuf); diff --git a/src/core/dhcp/nm-dhcp-systemd.c b/src/core/dhcp/nm-dhcp-systemd.c index 0884def3..14a121e7 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -81,16 +81,20 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, const struct in_addr *addr_list; char addr_str[NM_UTILS_INET_ADDRSTRLEN]; const char *s; - nm_auto_free_gstring GString *str = NULL; - nm_auto_free sd_dhcp_route **routes = NULL; - const char *const *search_domains = NULL; + nm_auto_free_gstring GString *str = NULL; + nm_auto_free sd_dhcp_route **routes_static = NULL; + nm_auto_free sd_dhcp_route **routes_classless = NULL; + const char *const *search_domains = NULL; + guint32 default_route_metric_offset; guint16 mtu; - int i, num; + int i; + int num; + int is_classless; + int n_routes_static; + int n_routes_classless; const void *data; gsize data_len; gboolean has_router_from_classless = FALSE; - gboolean has_classless_route = FALSE; - gboolean has_static_route = FALSE; const gint32 ts = nm_utils_get_monotonic_timestamp_sec(); gint64 ts_time = time(NULL); struct in_addr a_address; @@ -226,44 +230,27 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, nm_dhcp_option_add_option(options, AF_INET, NM_DHCP_OPTION_DHCP4_HOST_NAME, s); } - num = sd_dhcp_lease_get_routes(lease, &routes); - if (num > 0) { - nm_auto_free_gstring GString *str_classless = NULL; - nm_auto_free_gstring GString *str_static = NULL; - guint32 default_route_metric_offset = 0; + default_route_metric_offset = 0; + n_routes_static = sd_dhcp_lease_get_static_routes(lease, &routes_static); + n_routes_classless = sd_dhcp_lease_get_classless_routes(lease, &routes_classless); + for (is_classless = 1; is_classless >= 0; is_classless--) { + int n_routes = (is_classless ? n_routes_classless : n_routes_static); + sd_dhcp_route *const *routes = (is_classless ? routes_classless : routes_static); - for (i = 0; i < num; i++) { - switch (sd_dhcp_route_get_option(routes[i])) { - case NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE: - has_classless_route = TRUE; - break; - case NM_DHCP_OPTION_DHCP4_STATIC_ROUTE: - has_static_route = TRUE; - break; - } - } + if (n_routes <= 0) + continue; - if (has_classless_route) - str_classless = g_string_sized_new(30); - if (has_static_route) - str_static = g_string_sized_new(30); + nm_gstring_prepare(&str); - for (i = 0; i < num; i++) { + for (i = 0; i < n_routes; i++) { char network_net_str[NM_UTILS_INET_ADDRSTRLEN]; char gateway_str[NM_UTILS_INET_ADDRSTRLEN]; guint8 r_plen; struct in_addr r_network; struct in_addr r_gateway; in_addr_t network_net; - int option; guint32 m; - option = sd_dhcp_route_get_option(routes[i]); - 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) continue; if (sd_dhcp_route_get_destination_prefix_length(routes[i], &r_plen) < 0 || r_plen > 32) @@ -275,31 +262,28 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, _nm_utils_inet4_ntop(network_net, network_net_str); _nm_utils_inet4_ntop(r_gateway.s_addr, gateway_str); - g_string_append_printf( - nm_gstring_add_space_delimiter(option == NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE - ? str_classless - : str_static), - "%s/%d %s", - network_net_str, - (int) r_plen, - gateway_str); + g_string_append_printf(nm_gstring_add_space_delimiter(str), + "%s/%d %s", + network_net_str, + (int) r_plen, + gateway_str); - if (option == NM_DHCP_OPTION_DHCP4_STATIC_ROUTE && has_classless_route) { + if (!is_classless && n_routes_classless > 0) { /* RFC 3443: if the DHCP server returns both a Classless Static Routes * option and a Static Routes option, the DHCP client MUST ignore the * Static Routes option. */ continue; } - if (r_plen == 0 && 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 - * route. */ - continue; - } - if (r_plen == 0) { + if (!is_classless) { + /* for option 33 (static route), RFC 2132 says: + * + * The default route (0.0.0.0) is an illegal destination for a static + * route. */ + continue; + } + /* if there are multiple default routes, we add them with differing * metrics. */ m = default_route_metric_offset++; @@ -309,10 +293,11 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, nm_l3_config_data_add_route_4(l3cd, &((const NMPlatformIP4Route){ + .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = network_net, .plen = r_plen, .gateway = r_gateway.s_addr, - .rt_source = NM_IP_CONFIG_SOURCE_DHCP, + .pref_src = a_address.s_addr, .metric_any = TRUE, .metric = m, .table_any = TRUE, @@ -320,21 +305,18 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, })); } - if (str_classless && str_classless->len > 0) - nm_dhcp_option_add_option(options, - AF_INET, - NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE, - str_classless->str); - if (str_static && str_static->len > 0) + if (str->len > 0) { nm_dhcp_option_add_option(options, AF_INET, - NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, - str_static->str); + is_classless ? NM_DHCP_OPTION_DHCP4_CLASSLESS_STATIC_ROUTE + : NM_DHCP_OPTION_DHCP4_STATIC_ROUTE, + str->str); + } } num = sd_dhcp_lease_get_router(lease, &a_router); if (num > 0) { - guint32 default_route_metric_offset = 0; + default_route_metric_offset = 0; nm_gstring_prepare(&str); for (i = 0; i < num; i++) { @@ -366,6 +348,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx, &((const NMPlatformIP4Route){ .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .gateway = a_router[i].s_addr, + .pref_src = a_address.s_addr, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, diff --git a/src/core/dhcp/nm-dhcp-utils.c b/src/core/dhcp/nm-dhcp-utils.c index 214e94cd..a0eec6e0 100644 --- a/src/core/dhcp/nm-dhcp-utils.c +++ b/src/core/dhcp/nm-dhcp-utils.c @@ -28,7 +28,8 @@ static gboolean ip4_process_dhcpcd_rfc3442_routes(const char *iface, const char *str, NML3ConfigData *l3cd, - guint32 *gwaddr) + in_addr_t address, + guint32 *out_gwaddr) { gs_free const char **routes = NULL; const char **r; @@ -79,7 +80,7 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface, have_routes = TRUE; if (rt_cidr == 0 && rt_addr == 0) { /* FIXME: how to handle multiple routers? */ - *gwaddr = rt_route; + *out_gwaddr = rt_route; } else { _LOG2I(LOGD_DHCP4, iface, @@ -91,13 +92,13 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface, nm_l3_config_data_add_route_4( l3cd, &((const NMPlatformIP4Route){ + .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .network = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr), .plen = rt_cidr, .gateway = rt_route, - .rt_source = NM_IP_CONFIG_SOURCE_DHCP, + .pref_src = address, .metric_any = TRUE, .table_any = TRUE, - })); } } @@ -158,7 +159,8 @@ static gboolean ip4_process_dhclient_rfc3442_routes(const char *iface, const char *str, NML3ConfigData *l3cd, - guint32 *gwaddr) + in_addr_t address, + guint32 *out_gwaddr) { gs_free const char **octets = NULL; const char *const *o; @@ -182,13 +184,14 @@ ip4_process_dhclient_rfc3442_routes(const char *iface, have_routes = TRUE; if (!route.plen) { /* gateway passed as classless static route */ - *gwaddr = route.gateway; + *out_gwaddr = route.gateway; } else { char b1[INET_ADDRSTRLEN]; char b2[INET_ADDRSTRLEN]; /* normal route */ route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; + route.pref_src = address; route.table_any = TRUE; route.table_coerced = 0; route.metric_any = TRUE; @@ -212,14 +215,15 @@ static gboolean ip4_process_classless_routes(const char *iface, GHashTable *options, NML3ConfigData *l3cd, - guint32 *gwaddr) + in_addr_t address, + guint32 *out_gwaddr) { const char *str, *p; g_return_val_if_fail(options != NULL, FALSE); g_return_val_if_fail(l3cd != NULL, FALSE); - *gwaddr = 0; + *out_gwaddr = 0; /* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a * slightly different format: @@ -266,14 +270,17 @@ ip4_process_classless_routes(const char *iface, if (strchr(str, '/')) { /* dhcpcd format */ - return ip4_process_dhcpcd_rfc3442_routes(iface, str, l3cd, gwaddr); + return ip4_process_dhcpcd_rfc3442_routes(iface, str, l3cd, address, out_gwaddr); } - return ip4_process_dhclient_rfc3442_routes(iface, str, l3cd, gwaddr); + return ip4_process_dhclient_rfc3442_routes(iface, str, l3cd, address, out_gwaddr); } static void -process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData *l3cd) +process_classful_routes(const char *iface, + GHashTable *options, + NML3ConfigData *l3cd, + in_addr_t address) { gs_free const char **searches = NULL; const char **s; @@ -293,6 +300,7 @@ process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData * } for (s = searches; *s; s += 2) { + char sbuf[NM_UTILS_TO_STRING_BUFFER_SIZE]; NMPlatformIP4Route route; guint32 rt_addr, rt_route; @@ -321,6 +329,7 @@ process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData * route.plen = 32; } route.gateway = rt_route; + route.pref_src = address; route.rt_source = NM_IP_CONFIG_SOURCE_DHCP; route.table_any = TRUE; route.table_coerced = 0; @@ -334,7 +343,7 @@ process_classful_routes(const char *iface, GHashTable *options, NML3ConfigData * _LOG2I(LOGD_DHCP, iface, " static route %s", - nm_platform_ip4_route_to_string(&route, NULL, 0)); + nm_platform_ip4_route_to_string(&route, sbuf, sizeof(sbuf))); } } @@ -422,8 +431,8 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, /* Routes: if the server returns classless static routes, we MUST ignore * the 'static_routes' option. */ - if (!ip4_process_classless_routes(iface, options, l3cd, &gateway)) - process_classful_routes(iface, options, l3cd); + if (!ip4_process_classless_routes(iface, options, l3cd, address.address, &gateway)) + process_classful_routes(iface, options, l3cd, address.address); if (gateway) { _LOG2I(LOGD_DHCP4, iface, " gateway %s", _nm_utils_inet4_ntop(gateway, sbuf)); @@ -453,6 +462,7 @@ nm_dhcp_utils_ip4_config_from_options(NMDedupMultiIndex *multi_idx, const NMPlatformIP4Route r = { .rt_source = NM_IP_CONFIG_SOURCE_DHCP, .gateway = gateway, + .pref_src = address.address, .table_any = TRUE, .table_coerced = 0, .metric_any = TRUE, |