diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 9750902661..40e302c90d 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -1225,6 +1225,9 @@ The table identifier for DHCP routes (a number between 1 and 4294967295, or 0 to unset). The table can be retrieved using ip route show table num. + When used in combination with VRF= the + VRF's routing table is used unless this parameter is specified. + @@ -1824,8 +1827,9 @@ Bond=bond1 Virtual Routing and Forwarding (VRF) Add the bond1 interface to the VRF master interface vrf1. This will redirect routes generated on this interface to be - within the routing table defined during VRF creation. Traffic won't be redirected - towards the VRFs routing table unless specific ip-rules are added. + within the routing table defined during VRF creation. For kernels before 4.8 traffic + won't be redirected towards the VRFs routing table unless specific ip-rules are added. + # /etc/systemd/network/25-vrf.network [Match] Name=bond1 diff --git a/src/network/networkd-dhcp4.c b/src/network/networkd-dhcp4.c index 3b5bacd13b..e1e3e88708 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 5947f6dc15..af39d77ce9 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -117,7 +117,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 24f8ee6e9c..6fd550b80c 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -218,6 +218,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 */ @@ -1399,6 +1400,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; @@ -1414,7 +1416,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 11f5bb1174..9fb0eae380 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -139,6 +139,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 */