diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index 554d8da8ef..d62e4d6232 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -3188,6 +3188,23 @@ MultiPathRoute=2001:db8::1@eth0
+
+ RouteTable=num
+
+ The table identifier for routes installed by the DHCPv6 client, e.g. unreachable
+ routes for delegated prefixes. Takes one of the predefined names default,
+ main, and local, names defined in
+ RouteTable= in
+ networkd.conf5,
+ or a number between 1…4294967295.
+
+ When used in combination with VRF=, the VRF's routing table is
+ used when this parameter is not specified.
+
+
+
+
+
RapidCommit=
diff --git a/src/network/networkd-dhcp-common.c b/src/network/networkd-dhcp-common.c
index d2e51e7e91..3368145981 100644
--- a/src/network/networkd-dhcp-common.c
+++ b/src/network/networkd-dhcp-common.c
@@ -24,6 +24,7 @@
#include "networkd-manager.h"
#include "networkd-network.h"
#include "networkd-route-util.h"
+#include "networkd-util.h"
#include "parse-util.h"
#include "set.h"
#include "socket-util.h"
@@ -60,6 +61,15 @@ uint32_t link_get_ndisc_route_table(Link *link) {
return link_get_vrf_table(link);
}
+uint32_t link_get_dhcp6_route_table(Link *link) {
+ assert(link);
+ assert(link->network);
+
+ if (link->network->dhcp6_route_table_set)
+ return link->network->dhcp6_route_table;
+ return link_get_vrf_table(link);
+}
+
bool link_dhcp_enabled(Link *link, int family) {
assert(link);
assert(IN_SET(family, AF_INET, AF_INET6));
@@ -565,7 +575,7 @@ int config_parse_dhcp_or_ra_route_table(
assert(filename);
assert(lvalue);
- assert(IN_SET(ltype, AF_INET, AF_INET6));
+ assert(IN_SET(ltype, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6, NETWORK_CONFIG_SOURCE_NDISC));
assert(rvalue);
r = manager_get_route_table_from_string(network->manager, rvalue, &rt);
@@ -576,11 +586,15 @@ int config_parse_dhcp_or_ra_route_table(
}
switch (ltype) {
- case AF_INET:
+ case NETWORK_CONFIG_SOURCE_DHCP4:
network->dhcp_route_table = rt;
network->dhcp_route_table_set = true;
break;
- case AF_INET6:
+ case NETWORK_CONFIG_SOURCE_DHCP6:
+ network->dhcp6_route_table = rt;
+ network->dhcp6_route_table_set = true;
+ break;
+ case NETWORK_CONFIG_SOURCE_NDISC:
network->ndisc_route_table = rt;
network->ndisc_route_table_set = true;
break;
diff --git a/src/network/networkd-dhcp-common.h b/src/network/networkd-dhcp-common.h
index 6be8bcd6dc..b6385492c3 100644
--- a/src/network/networkd-dhcp-common.h
+++ b/src/network/networkd-dhcp-common.h
@@ -41,6 +41,7 @@ typedef struct DUID {
uint32_t link_get_dhcp4_route_table(Link *link);
uint32_t link_get_ndisc_route_table(Link *link);
+uint32_t link_get_dhcp6_route_table(Link *link);
bool link_dhcp_enabled(Link *link, int family);
static inline bool link_dhcp4_enabled(Link *link) {
diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c
index e734b0171d..85c5233472 100644
--- a/src/network/networkd-dhcp-prefix-delegation.c
+++ b/src/network/networkd-dhcp-prefix-delegation.c
@@ -14,6 +14,7 @@
#include "in-addr-prefix-util.h"
#include "networkd-address.h"
#include "networkd-address-generation.h"
+#include "networkd-dhcp-common.h"
#include "networkd-dhcp-prefix-delegation.h"
#include "networkd-dhcp6.h"
#include "networkd-link.h"
@@ -851,6 +852,8 @@ static int dhcp_request_unreachable_route(
route->protocol = RTPROT_DHCP;
route->priority = IP6_RT_PRIO_USER;
route->lifetime_usec = lifetime_usec;
+ if (source == NETWORK_CONFIG_SOURCE_DHCP6 && !route->table_set)
+ route->table = link_get_dhcp6_route_table(link);
r = route_adjust_nexthops(route, link);
if (r < 0)
diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf
index a5afeed1cb..9e6eb7c799 100644
--- a/src/network/networkd-network-gperf.gperf
+++ b/src/network/networkd-network-gperf.gperf
@@ -283,7 +283,7 @@ DHCPv4.IAID, config_parse_iaid,
DHCPv4.DUIDType, config_parse_network_duid_type, 0, 0
DHCPv4.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCPv4.RouteMetric, config_parse_dhcp_route_metric, AF_INET, 0
-DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0
+DHCPv4.RouteTable, config_parse_dhcp_or_ra_route_table, NETWORK_CONFIG_SOURCE_DHCP4, 0
DHCPv4.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCPv4.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCPv4.ServerPort, config_parse_uint16, 0, offsetof(Network, dhcp_port)
@@ -332,6 +332,7 @@ DHCPv6.RapidCommit, config_parse_bool,
DHCPv6.NetLabel, config_parse_string, CONFIG_PARSE_STRING_SAFE, offsetof(Network, dhcp6_netlabel)
DHCPv6.SendRelease, config_parse_bool, 0, offsetof(Network, dhcp6_send_release)
DHCPv6.NFTSet, config_parse_nft_set, NFT_SET_PARSE_NETWORK, offsetof(Network, dhcp6_nft_set_context)
+DHCPv6.RouteTable, config_parse_dhcp_or_ra_route_table, NETWORK_CONFIG_SOURCE_DHCP6, 0
IPv6AcceptRA.UseRedirect, config_parse_bool, 0, offsetof(Network, ndisc_use_redirect)
IPv6AcceptRA.UseGateway, config_parse_bool, 0, offsetof(Network, ndisc_use_gateway)
IPv6AcceptRA.UseRoutePrefix, config_parse_bool, 0, offsetof(Network, ndisc_use_route_prefix)
@@ -346,7 +347,7 @@ IPv6AcceptRA.UseHopLimit, config_parse_bool,
IPv6AcceptRA.UseReachableTime, config_parse_bool, 0, offsetof(Network, ndisc_use_reachable_time)
IPv6AcceptRA.UseRetransmissionTime, config_parse_bool, 0, offsetof(Network, ndisc_use_retransmission_time)
IPv6AcceptRA.DHCPv6Client, config_parse_ndisc_start_dhcp6_client, 0, offsetof(Network, ndisc_start_dhcp6_client)
-IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET6, 0
+IPv6AcceptRA.RouteTable, config_parse_dhcp_or_ra_route_table, NETWORK_CONFIG_SOURCE_NDISC, 0
IPv6AcceptRA.RouteMetric, config_parse_ndisc_route_metric, 0, 0
IPv6AcceptRA.QuickAck, config_parse_bool, 0, offsetof(Network, ndisc_quickack)
IPv6AcceptRA.UseCaptivePortal, config_parse_bool, 0, offsetof(Network, ndisc_use_captive_portal)
@@ -669,7 +670,7 @@ DHCP.IAID, config_parse_iaid,
DHCP.DUIDType, config_parse_network_duid_type, 0, 0
DHCP.DUIDRawData, config_parse_network_duid_rawdata, 0, 0
DHCP.RouteMetric, config_parse_dhcp_route_metric, AF_UNSPEC, 0
-DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, AF_INET, 0
+DHCP.RouteTable, config_parse_dhcp_or_ra_route_table, NETWORK_CONFIG_SOURCE_DHCP4, 0
DHCP.UseTimezone, config_parse_bool, 0, offsetof(Network, dhcp_use_timezone)
DHCP.ListenPort, config_parse_uint16, 0, offsetof(Network, dhcp_client_port)
DHCP.RapidCommit, config_parse_bool, 0, offsetof(Network, dhcp6_use_rapid_commit)
diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c
index 17cf78db37..dfe524d150 100644
--- a/src/network/networkd-network.c
+++ b/src/network/networkd-network.c
@@ -424,6 +424,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
.dhcp6_client_start_mode = _DHCP6_CLIENT_START_MODE_INVALID,
.dhcp6_send_release = true,
.dhcp6_pd_prefix_route_type = RTN_UNREACHABLE,
+ .dhcp6_route_table = RT_TABLE_MAIN,
.dhcp_pd = -1,
.dhcp_pd_announce = true,
diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h
index d1765a2bf4..625b3b9a08 100644
--- a/src/network/networkd-network.h
+++ b/src/network/networkd-network.h
@@ -205,6 +205,8 @@ typedef struct Network {
char *dhcp6_netlabel;
bool dhcp6_send_release;
NFTSetContext dhcp6_nft_set_context;
+ uint32_t dhcp6_route_table;
+ bool dhcp6_route_table_set;
/* DHCP Server Support */
bool dhcp_server;