summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Haller <thaller@redhat.com>2022-04-01 08:39:56 +0200
committerThomas Haller <thaller@redhat.com>2022-04-06 21:16:25 +0200
commitb3a78c261b27e7e782fecd97a9a01670f97c3634 (patch)
tree4ff9ccd55b57819fc22885899b289e77bd9702b0
parent5b6311ea07b802efec53ece896d7e10ecea461c4 (diff)
downloadNetworkManager-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--NEWS2
-rw-r--r--src/core/dhcp/nm-dhcp-nettools.c16
-rw-r--r--src/core/dhcp/nm-dhcp-systemd.c4
-rw-r--r--src/core/dhcp/nm-dhcp-utils.c26
4 files changed, 32 insertions, 16 deletions
diff --git a/NEWS b/NEWS
index 937dbaefa0..22e80abe38 100644
--- a/NEWS
+++ b/NEWS
@@ -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) {