diff --git a/man/systemd.netdev.xml b/man/systemd.netdev.xml index 6a84b7a648..6879518b4b 100644 --- a/man/systemd.netdev.xml +++ b/man/systemd.netdev.xml @@ -2683,7 +2683,10 @@ Ports=eth2 Table= - The numeric routing table identifier. This setting is compulsory. + The routing table identifier. Takes a route table name or number. Route table names + may be predefined or configured with RouteTable= in + networkd.conf5. + This setting is compulsory. diff --git a/src/network/netdev/netdev-gperf.gperf b/src/network/netdev/netdev-gperf.gperf index 250b6cf7bc..269a974542 100644 --- a/src/network/netdev/netdev-gperf.gperf +++ b/src/network/netdev/netdev-gperf.gperf @@ -249,7 +249,7 @@ Bridge.MulticastIGMPVersion, config_parse_bridge_igmp_version, Bridge.FDBMaxLearned, config_parse_bridge_fdb_max_learned, 0, offsetof(Bridge, fdb_max_learned) Bridge.LinkLocalLearning, config_parse_tristate, 0, offsetof(Bridge, linklocal_learn) VRF.TableId, config_parse_uint32, 0, offsetof(Vrf, table) /* deprecated */ -VRF.Table, config_parse_uint32, 0, offsetof(Vrf, table) +VRF.Table, config_parse_vrf_table, 0, offsetof(Vrf, table) BareUDP.DestinationPort, config_parse_ip_port, 0, offsetof(BareUDP, dest_port) BareUDP.MinSourcePort, config_parse_ip_port, 0, offsetof(BareUDP, min_port) BareUDP.EtherType, config_parse_bare_udp_iftype, 0, offsetof(BareUDP, iftype) diff --git a/src/network/netdev/vrf.c b/src/network/netdev/vrf.c index 540c269f2d..d91ccf394a 100644 --- a/src/network/netdev/vrf.c +++ b/src/network/netdev/vrf.c @@ -4,8 +4,40 @@ #include "sd-netlink.h" +#include "networkd-route-util.h" #include "vrf.h" +int config_parse_vrf_table( + const char *unit, + const char *filename, + unsigned line, + const char *section, + unsigned section_line, + const char *lvalue, + int ltype, + const char *rvalue, + void *data, + void *userdata) { + + Vrf *vrf = ASSERT_PTR(userdata); + uint32_t *table = ASSERT_PTR(data); + int r; + + assert(filename); + assert(lvalue); + assert(rvalue); + + r = manager_get_route_table_from_string(vrf->meta.manager, rvalue, table); + if (r < 0) { + log_syntax(unit, LOG_WARNING, filename, line, r, + "Failed to parse %s=, ignoring assignment: %s", + lvalue, rvalue); + return 0; + } + + return 0; +} + static int netdev_vrf_fill_message_create(NetDev *netdev, Link *link, sd_netlink_message *m) { assert(!link); assert(m); diff --git a/src/network/netdev/vrf.h b/src/network/netdev/vrf.h index 7bf9447856..a794c237c9 100644 --- a/src/network/netdev/vrf.h +++ b/src/network/netdev/vrf.h @@ -11,3 +11,5 @@ typedef struct Vrf { DEFINE_NETDEV_CAST(VRF, Vrf); extern const NetDevVTable vrf_vtable; + +CONFIG_PARSER_PROTOTYPE(config_parse_vrf_table); diff --git a/src/network/test-network.c b/src/network/test-network.c index 6582d3b074..ab3a86e10b 100644 --- a/src/network/test-network.c +++ b/src/network/test-network.c @@ -11,6 +11,7 @@ #include "networkd-route-util.h" #include "strv.h" #include "tests.h" +#include "vrf.h" TEST(deserialize_in_addr) { _cleanup_free_ struct in_addr *addresses = NULL; @@ -150,6 +151,29 @@ TEST(route_tables) { test_route_tables_one(manager, "local", 255); } +TEST(vrf_table) { + _cleanup_(manager_freep) Manager *manager = NULL; + Vrf vrf = {}; + + ASSERT_OK(manager_new(&manager, /* test_mode= */ true)); + ASSERT_OK(manager_setup(manager)); + + vrf.meta.manager = manager; + + ASSERT_OK(config_parse_vrf_table("netdev", "filename", 1, "VRF", 1, "Table", 0, "default", &vrf.table, &vrf)); + ASSERT_EQ(vrf.table, 253U); + + ASSERT_OK(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "vrf-test:1234", manager, manager)); + ASSERT_OK(config_parse_vrf_table("netdev", "filename", 1, "VRF", 1, "Table", 0, "vrf-test", &vrf.table, &vrf)); + ASSERT_EQ(vrf.table, 1234U); + + ASSERT_OK(config_parse_vrf_table("netdev", "filename", 1, "VRF", 1, "Table", 0, "5678", &vrf.table, &vrf)); + ASSERT_EQ(vrf.table, 5678U); + + ASSERT_OK(config_parse_vrf_table("netdev", "filename", 1, "VRF", 1, "Table", 0, "no-such-table", &vrf.table, &vrf)); + ASSERT_EQ(vrf.table, 5678U); +} + TEST(manager_enumerate) { _cleanup_(manager_freep) Manager *manager = NULL;