From fc1ba79d65f1835effebd2e3fd532631f74a0536 Mon Sep 17 00:00:00 2001 From: Andreas Rammhold Date: Thu, 7 Sep 2017 11:08:39 +0200 Subject: [PATCH] networkd: use VRFs routing table for DHCP routes When an interface has been enslaved to a VRF the received routes should be added to the VRFs RT instead of the main table. This change modifies the default behaviour of routes in the case where a network belongs to an VRF. When the user does not configure a `DHCP.RouteTable` in a `systemd.network` file and the interface belongs to a VRF, the VRFs routing table is used instead of RT_TABLE_MAIN. When the user has configured a custom routing table for DHCP the VRFs table is ignored and the users preference takes precedence. --- src/network/networkd-dhcp4.c | 14 +++++++++++--- src/network/networkd-network-gperf.gperf | 2 +- src/network/networkd-network.c | 5 ++++- src/network/networkd-network.h | 1 + 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 9c69979c7b..156edff21e 100644 --- a/src/network/networkd-dhcp4.c +++ b/src/network/networkd-dhcp4.c @@ -23,6 +23,7 @@ #include "alloc-util.h" #include "dhcp-lease-internal.h" #include "hostname-util.h" +#include "netdev/vrf.h" #include "network-internal.h" #include "networkd-link.h" #include "networkd-manager.h" @@ -69,6 +70,7 @@ static int link_set_dhcp_routes(Link *link) { struct in_addr gateway, address; _cleanup_free_ sd_dhcp_route **static_routes = NULL; int r, n, i; + uint32_t table; assert(link); @@ -81,6 +83,12 @@ static int link_set_dhcp_routes(Link *link) { if (!link->network->dhcp_use_routes) return 0; + /* When the interface is part of an VRF use the VRFs routing table, unless + * there is a another table specified. */ + table = link->network->dhcp_route_table; + if (!link->network->dhcp_route_table_set && link->network->vrf != NULL) + table = VRF(link->network->vrf)->table; + r = sd_dhcp_lease_get_address(link->dhcp_lease, &address); if (r < 0) return log_link_warning_errno(link, r, "DHCP error: could not get address: %m"); @@ -113,7 +121,7 @@ static int link_set_dhcp_routes(Link *link) { route_gw->scope = RT_SCOPE_LINK; route_gw->protocol = RTPROT_DHCP; route_gw->priority = link->network->dhcp_route_metric; - route_gw->table = link->network->dhcp_route_table; + route_gw->table = table; r = route_configure(route_gw, link, dhcp4_route_handler); if (r < 0) @@ -125,7 +133,7 @@ static int link_set_dhcp_routes(Link *link) { route->gw.in = gateway; route->prefsrc.in = address; route->priority = link->network->dhcp_route_metric; - route->table = link->network->dhcp_route_table; + route->table = table; r = route_configure(route, link, dhcp4_route_handler); if (r < 0) { @@ -156,7 +164,7 @@ static int link_set_dhcp_routes(Link *link) { assert_se(sd_dhcp_route_get_destination(static_routes[i], &route->dst.in) >= 0); assert_se(sd_dhcp_route_get_destination_prefix_length(static_routes[i], &route->dst_prefixlen) >= 0); route->priority = link->network->dhcp_route_metric; - route->table = link->network->dhcp_route_table; + route->table = table; route->scope = route_scope_from_address(route, &address); r = route_configure(route, link, dhcp4_route_handler); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 112efd2dfb..94c23b165f 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -110,7 +110,7 @@ DHCP.VendorClassIdentifier, config_parse_string, DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Network, duid.type) DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Network, duid) DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) -DHCP.RouteTable, config_parse_dhcp_route_table, 0, offsetof(Network, dhcp_route_table) +DHCP.RouteTable, config_parse_dhcp_route_table, 0, 0 DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone) DHCP.IAID, config_parse_iaid, 0, offsetof(Network, iaid) DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index a873e55d4c..b2589ccd2a 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -212,6 +212,7 @@ static int network_load_one(Manager *manager, const char *filename) { /* NOTE: this var might be overwrite by network_apply_anonymize_if_set */ network->dhcp_client_identifier = DHCP_CLIENT_ID_DUID; network->dhcp_route_table = RT_TABLE_MAIN; + network->dhcp_route_table_set = false; /* NOTE: the following vars were not set to any default, * even if they are commented in the man? * These vars might be overwriten by network_apply_anonymize_if_set */ @@ -1339,6 +1340,7 @@ int config_parse_dhcp_route_table(const char *unit, const char *rvalue, void *data, void *userdata) { + Network *network = data; uint32_t rt; int r; @@ -1354,7 +1356,8 @@ int config_parse_dhcp_route_table(const char *unit, return 0; } - *((uint32_t *)data) = rt; + network->dhcp_route_table = rt; + network->dhcp_route_table_set = true; return 0; } diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index 035b57d5f2..10f6eb617c 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -138,6 +138,7 @@ struct Network { bool dhcp_use_routes; bool dhcp_use_timezone; bool dhcp_use_hostname; + bool dhcp_route_table_set; DHCPUseDomains dhcp_use_domains; /* DHCP Server Support */