diff options
author | Thomas Haller <thaller@redhat.com> | 2022-04-01 08:39:56 +0200 |
---|---|---|
committer | Thomas Haller <thaller@redhat.com> | 2022-04-06 21:16:25 +0200 |
commit | b3a78c261b27e7e782fecd97a9a01670f97c3634 (patch) | |
tree | 4ff9ccd55b57819fc22885899b289e77bd9702b0 | |
parent | 5b6311ea07b802efec53ece896d7e10ecea461c4 (diff) | |
download | NetworkManager-th/dhcp-pref-src.tar.gz |
dhcp: set "src" for DHCPv4 routesth/dhcp-pref-src
Let's set the "src" (RTA_PREFSRC) of DHCP routes.
This helps with source address selection.
This can matter if the interface also has static addresses
configured.
Systemd-networkd also does this ([1], [2]).
[1] https://github.com/systemd/systemd/commit/ac2dce5f36bb8b1a877ff765e6a4dfde6bfb2d49
[2] https://github.com/systemd/systemd/blob/5b89bff55f45235f72d30d90fd489fe2247ad00d/src/network/networkd-dhcp4.c#L395
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1995372
-rw-r--r-- | NEWS | 2 | ||||
-rw-r--r-- | src/core/dhcp/nm-dhcp-nettools.c | 16 | ||||
-rw-r--r-- | src/core/dhcp/nm-dhcp-systemd.c | 4 | ||||
-rw-r--r-- | src/core/dhcp/nm-dhcp-utils.c | 26 |
4 files changed, 32 insertions, 16 deletions
@@ -36,6 +36,8 @@ USE AT YOUR OWN RISK. NOT RECOMMENDED FOR PRODUCTION USE! * nmcli: add connection migrate command to move a profile to a specified settings plugin. This allows to convert profiles in the deprecated ifcfg-rh format to keyfile. +* Set "src" attribute for routes from DHCPv4 to the leased address. This + helps with source address selection. * Updated translations. * Various bugfixes and internal improvements. diff --git a/src/core/dhcp/nm-dhcp-nettools.c b/src/core/dhcp/nm-dhcp-nettools.c index a1a057ba79..aac189676d 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) { @@ -384,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, @@ -427,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, @@ -475,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, @@ -558,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; @@ -567,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); @@ -586,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 70f89a211c..14a121e73e 100644 --- a/src/core/dhcp/nm-dhcp-systemd.c +++ b/src/core/dhcp/nm-dhcp-systemd.c @@ -293,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, @@ -347,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 214e94cd08..a5916de839 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,10 +270,10 @@ 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 @@ -422,7 +426,7 @@ 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)) + if (!ip4_process_classless_routes(iface, options, l3cd, address.address, &gateway)) process_classful_routes(iface, options, l3cd); if (gateway) { |