dhcp: set "src" for DHCPv4 routes
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]ac2dce5f36
[2]5b89bff55f/src/network/networkd-dhcp4.c (L395)
Related: https://bugzilla.redhat.com/show_bug.cgi?id=1995372 https://gitlab.freedesktop.org/NetworkManager/NetworkManager/-/merge_requests/1173
This commit is contained in:
2
NEWS
2
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
|
* nmcli: add connection migrate command to move a profile to a specified
|
||||||
settings plugin. This allows to convert profiles in the deprecated ifcfg-rh
|
settings plugin. This allows to convert profiles in the deprecated ifcfg-rh
|
||||||
format to keyfile.
|
format to keyfile.
|
||||||
|
* Set "src" attribute for routes from DHCPv4 to the leased address. This
|
||||||
|
helps with source address selection.
|
||||||
* Updated translations.
|
* Updated translations.
|
||||||
* Various bugfixes and internal improvements.
|
* Various bugfixes and internal improvements.
|
||||||
|
|
||||||
|
@@ -154,6 +154,7 @@ static gboolean
|
|||||||
lease_parse_address(NDhcp4ClientLease *lease,
|
lease_parse_address(NDhcp4ClientLease *lease,
|
||||||
NML3ConfigData *l3cd,
|
NML3ConfigData *l3cd,
|
||||||
GHashTable *options,
|
GHashTable *options,
|
||||||
|
in_addr_t *out_address,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
struct in_addr a_address;
|
struct in_addr a_address;
|
||||||
@@ -268,6 +269,8 @@ lease_parse_address(NDhcp4ClientLease *lease,
|
|||||||
.preferred = a_lifetime,
|
.preferred = a_lifetime,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
NM_SET_OUT(out_address, a_address.s_addr);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -326,6 +329,7 @@ lease_parse_address_list(NDhcp4ClientLease *lease,
|
|||||||
static void
|
static void
|
||||||
lease_parse_routes(NDhcp4ClientLease *lease,
|
lease_parse_routes(NDhcp4ClientLease *lease,
|
||||||
NML3ConfigData *l3cd,
|
NML3ConfigData *l3cd,
|
||||||
|
in_addr_t lease_address,
|
||||||
GHashTable *options,
|
GHashTable *options,
|
||||||
NMStrBuf *sbuf)
|
NMStrBuf *sbuf)
|
||||||
{
|
{
|
||||||
@@ -384,10 +388,11 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
|
|
||||||
nm_l3_config_data_add_route_4(l3cd,
|
nm_l3_config_data_add_route_4(l3cd,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.network = dest,
|
.network = dest,
|
||||||
.plen = plen,
|
.plen = plen,
|
||||||
.gateway = gateway,
|
.gateway = gateway,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.pref_src = lease_address,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
.table_coerced = 0,
|
.table_coerced = 0,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
@@ -427,10 +432,11 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
|
|
||||||
nm_l3_config_data_add_route_4(l3cd,
|
nm_l3_config_data_add_route_4(l3cd,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.network = dest,
|
.network = dest,
|
||||||
.plen = plen,
|
.plen = plen,
|
||||||
.gateway = gateway,
|
.gateway = gateway,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.pref_src = lease_address,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
.table_coerced = 0,
|
.table_coerced = 0,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
@@ -475,6 +481,7 @@ lease_parse_routes(NDhcp4ClientLease *lease,
|
|||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.gateway = gateway,
|
.gateway = gateway,
|
||||||
|
.pref_src = lease_address,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
.table_coerced = 0,
|
.table_coerced = 0,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
@@ -558,6 +565,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
|
|||||||
const char *v_str;
|
const char *v_str;
|
||||||
guint16 v_u16;
|
guint16 v_u16;
|
||||||
in_addr_t v_inaddr;
|
in_addr_t v_inaddr;
|
||||||
|
in_addr_t lease_address;
|
||||||
struct in_addr v_inaddr_s;
|
struct in_addr v_inaddr_s;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
@@ -567,7 +575,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
|
|||||||
|
|
||||||
options = nm_dhcp_option_create_options_dict();
|
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;
|
return NULL;
|
||||||
|
|
||||||
r = n_dhcp4_client_lease_get_server_identifier(lease, &v_inaddr_s);
|
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);
|
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);
|
lease_parse_address_list(lease, l3cd, NM_DHCP_OPTION_DHCP4_DOMAIN_NAME_SERVER, options, &sbuf);
|
||||||
|
|
||||||
|
@@ -293,10 +293,11 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
|
|||||||
|
|
||||||
nm_l3_config_data_add_route_4(l3cd,
|
nm_l3_config_data_add_route_4(l3cd,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.network = network_net,
|
.network = network_net,
|
||||||
.plen = r_plen,
|
.plen = r_plen,
|
||||||
.gateway = r_gateway.s_addr,
|
.gateway = r_gateway.s_addr,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.pref_src = a_address.s_addr,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
.metric = m,
|
.metric = m,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
@@ -347,6 +348,7 @@ lease_to_ip4_config(NMDedupMultiIndex *multi_idx,
|
|||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.gateway = a_router[i].s_addr,
|
.gateway = a_router[i].s_addr,
|
||||||
|
.pref_src = a_address.s_addr,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
.table_coerced = 0,
|
.table_coerced = 0,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
|
@@ -28,7 +28,8 @@ static gboolean
|
|||||||
ip4_process_dhcpcd_rfc3442_routes(const char *iface,
|
ip4_process_dhcpcd_rfc3442_routes(const char *iface,
|
||||||
const char *str,
|
const char *str,
|
||||||
NML3ConfigData *l3cd,
|
NML3ConfigData *l3cd,
|
||||||
guint32 *gwaddr)
|
in_addr_t address,
|
||||||
|
guint32 *out_gwaddr)
|
||||||
{
|
{
|
||||||
gs_free const char **routes = NULL;
|
gs_free const char **routes = NULL;
|
||||||
const char **r;
|
const char **r;
|
||||||
@@ -79,7 +80,7 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface,
|
|||||||
have_routes = TRUE;
|
have_routes = TRUE;
|
||||||
if (rt_cidr == 0 && rt_addr == 0) {
|
if (rt_cidr == 0 && rt_addr == 0) {
|
||||||
/* FIXME: how to handle multiple routers? */
|
/* FIXME: how to handle multiple routers? */
|
||||||
*gwaddr = rt_route;
|
*out_gwaddr = rt_route;
|
||||||
} else {
|
} else {
|
||||||
_LOG2I(LOGD_DHCP4,
|
_LOG2I(LOGD_DHCP4,
|
||||||
iface,
|
iface,
|
||||||
@@ -91,13 +92,13 @@ ip4_process_dhcpcd_rfc3442_routes(const char *iface,
|
|||||||
nm_l3_config_data_add_route_4(
|
nm_l3_config_data_add_route_4(
|
||||||
l3cd,
|
l3cd,
|
||||||
&((const NMPlatformIP4Route){
|
&((const NMPlatformIP4Route){
|
||||||
|
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
||||||
.network = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr),
|
.network = nm_utils_ip4_address_clear_host_address(rt_addr, rt_cidr),
|
||||||
.plen = rt_cidr,
|
.plen = rt_cidr,
|
||||||
.gateway = rt_route,
|
.gateway = rt_route,
|
||||||
.rt_source = NM_IP_CONFIG_SOURCE_DHCP,
|
.pref_src = address,
|
||||||
.metric_any = TRUE,
|
.metric_any = TRUE,
|
||||||
.table_any = TRUE,
|
.table_any = TRUE,
|
||||||
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,7 +159,8 @@ static gboolean
|
|||||||
ip4_process_dhclient_rfc3442_routes(const char *iface,
|
ip4_process_dhclient_rfc3442_routes(const char *iface,
|
||||||
const char *str,
|
const char *str,
|
||||||
NML3ConfigData *l3cd,
|
NML3ConfigData *l3cd,
|
||||||
guint32 *gwaddr)
|
in_addr_t address,
|
||||||
|
guint32 *out_gwaddr)
|
||||||
{
|
{
|
||||||
gs_free const char **octets = NULL;
|
gs_free const char **octets = NULL;
|
||||||
const char *const *o;
|
const char *const *o;
|
||||||
@@ -182,13 +184,14 @@ ip4_process_dhclient_rfc3442_routes(const char *iface,
|
|||||||
have_routes = TRUE;
|
have_routes = TRUE;
|
||||||
if (!route.plen) {
|
if (!route.plen) {
|
||||||
/* gateway passed as classless static route */
|
/* gateway passed as classless static route */
|
||||||
*gwaddr = route.gateway;
|
*out_gwaddr = route.gateway;
|
||||||
} else {
|
} else {
|
||||||
char b1[INET_ADDRSTRLEN];
|
char b1[INET_ADDRSTRLEN];
|
||||||
char b2[INET_ADDRSTRLEN];
|
char b2[INET_ADDRSTRLEN];
|
||||||
|
|
||||||
/* normal route */
|
/* normal route */
|
||||||
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
|
route.rt_source = NM_IP_CONFIG_SOURCE_DHCP;
|
||||||
|
route.pref_src = address;
|
||||||
route.table_any = TRUE;
|
route.table_any = TRUE;
|
||||||
route.table_coerced = 0;
|
route.table_coerced = 0;
|
||||||
route.metric_any = TRUE;
|
route.metric_any = TRUE;
|
||||||
@@ -212,14 +215,15 @@ static gboolean
|
|||||||
ip4_process_classless_routes(const char *iface,
|
ip4_process_classless_routes(const char *iface,
|
||||||
GHashTable *options,
|
GHashTable *options,
|
||||||
NML3ConfigData *l3cd,
|
NML3ConfigData *l3cd,
|
||||||
guint32 *gwaddr)
|
in_addr_t address,
|
||||||
|
guint32 *out_gwaddr)
|
||||||
{
|
{
|
||||||
const char *str, *p;
|
const char *str, *p;
|
||||||
|
|
||||||
g_return_val_if_fail(options != NULL, FALSE);
|
g_return_val_if_fail(options != NULL, FALSE);
|
||||||
g_return_val_if_fail(l3cd != 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
|
/* dhcpd/dhclient in Fedora has support for rfc3442 implemented using a
|
||||||
* slightly different format:
|
* slightly different format:
|
||||||
@@ -266,10 +270,10 @@ ip4_process_classless_routes(const char *iface,
|
|||||||
|
|
||||||
if (strchr(str, '/')) {
|
if (strchr(str, '/')) {
|
||||||
/* dhcpcd format */
|
/* 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
|
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
|
/* Routes: if the server returns classless static routes, we MUST ignore
|
||||||
* the 'static_routes' option.
|
* 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);
|
process_classful_routes(iface, options, l3cd);
|
||||||
|
|
||||||
if (gateway) {
|
if (gateway) {
|
||||||
|
Reference in New Issue
Block a user