Allow `[VRF] Table=` to accept route table names in addition to
numeric table identifiers. These may be predefined route table names
or names configured with `networkd.conf` `RouteTable=`.
There was an earlier attempt to make `VRF.Table=` accept names in
f98dd1e707, but it wired the setting to
`config_parse_route_table()`. That parser was a `[Route]` section
parser, not a generic scalar parser for netdevs: it expected
network/route parser state and created a `Route` object. It was
therefore reverted by
40352cf0c1.
This commit replaces the uint32 parser with
`manager_get_route_table_from_string()`, the generic table parser
already used by route/rule, DHCP/RA `RouteTable=`, and WireGuard
`RouteTable=` in `.netdev` files. The VRF semantics stay
unchanged. The commit retains the existing behavior of the
deprecated `TableId=` field.
Co-developed-by: OpenAI Codex <codex@openai.com>
<varlistentry>
<term><varname>Table=</varname></term>
<listitem>
- <para>The numeric routing table identifier. This setting is compulsory.</para>
+ <para>The routing table identifier. Takes a route table name or number. Route table names
+ may be predefined or configured with <varname>RouteTable=</varname> in
+ <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+ This setting is compulsory.</para>
<xi:include href="version-info.xml" xpointer="v243"/>
</listitem>
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)
#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);
DEFINE_NETDEV_CAST(VRF, Vrf);
extern const NetDevVTable vrf_vtable;
+
+CONFIG_PARSER_PROTOTYPE(config_parse_vrf_table);
#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;
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;