diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml
index abf47d17b6..bf597cac2e 100644
--- a/man/networkd.conf.xml
+++ b/man/networkd.conf.xml
@@ -89,9 +89,10 @@
colon, i.e., name:number.
The route table name must not be default, main, or
local, as these route table names are predefined with route table number 253,
- 254, and 255, respectively. The route table number must be an integer in the range 1…4294967295.
- This setting can be specified multiple times. If an empty string is specified, then the list
- specified earlier are cleared. Defaults to unset.
+ 254, and 255, respectively. The route table number must be an integer in the range 1…4294967295,
+ except for predefined numbers 253, 254, and 255. This setting can be specified multiple times.
+ If an empty string is specified, then the list specified earlier are cleared. Defaults to unset.
+
diff --git a/src/network/networkd-json.c b/src/network/networkd-json.c
index b9e119ceeb..bb83a35967 100644
--- a/src/network/networkd-json.c
+++ b/src/network/networkd-json.c
@@ -235,7 +235,7 @@ static int route_build_json(Route *route, JsonVariant **ret) {
if (r < 0)
return r;
- r = manager_get_route_table_to_string(manager, route->table, &table);
+ r = manager_get_route_table_to_string(manager, route->table, /* append_num = */ false, &table);
if (r < 0)
return r;
@@ -305,7 +305,7 @@ static int routing_policy_rule_build_json(RoutingPolicyRule *rule, JsonVariant *
assert(rule->manager);
assert(ret);
- r = manager_get_route_table_to_string(rule->manager, rule->table, &table);
+ r = manager_get_route_table_to_string(rule->manager, rule->table, /* append_num = */ false, &table);
if (r < 0 && r != -EINVAL)
return r;
diff --git a/src/network/networkd-route-util.c b/src/network/networkd-route-util.c
index 51514f2cd4..b4620079fc 100644
--- a/src/network/networkd-route-util.c
+++ b/src/network/networkd-route-util.c
@@ -424,10 +424,9 @@ int manager_get_route_table_from_string(const Manager *m, const char *s, uint32_
return 0;
}
-int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret) {
+int manager_get_route_table_to_string(const Manager *m, uint32_t table, bool append_num, char **ret) {
_cleanup_free_ char *str = NULL;
const char *s;
- int r;
assert(m);
assert(ret);
@@ -439,13 +438,16 @@ int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **r
if (!s)
s = hashmap_get(m->route_table_names_by_number, UINT32_TO_PTR(table));
- if (s)
- /* Currently, this is only used in debugging logs. To not confuse any bug
- * reports, let's include the table number. */
- r = asprintf(&str, "%s(%" PRIu32 ")", s, table);
- else
- r = asprintf(&str, "%" PRIu32, table);
- if (r < 0)
+ if (s && !append_num) {
+ str = strdup(s);
+ if (!str)
+ return -ENOMEM;
+
+ } else if (asprintf(&str, "%s%s%" PRIu32 "%s",
+ strempty(s),
+ s ? "(" : "",
+ table,
+ s ? ")" : "") < 0)
return -ENOMEM;
*ret = TAKE_PTR(str);
@@ -512,9 +514,10 @@ int config_parse_route_table_names(
"Route table name cannot be numeric. Ignoring assignment: %s:%s", name, num);
continue;
}
- if (STR_IN_SET(name, "default", "main", "local")) {
+ if (route_table_from_string(name) >= 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
- "Route table name %s is already predefined. Ignoring assignment: %s:%s", name, name, num);
+ "Route table name %s is predefined for %i. Ignoring assignment: %s:%s",
+ name, route_table_from_string(name), name, num);
continue;
}
@@ -529,6 +532,12 @@ int config_parse_route_table_names(
"Invalid route table number, ignoring assignment: %s:%s", name, num);
continue;
}
+ if (route_table_to_string(table)) {
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "Route table name for %s is predefined (%s). Ignoring assignment: %s:%s",
+ num, route_table_to_string(table), name, num);
+ continue;
+ }
r = hashmap_ensure_put(&m->route_table_numbers_by_name, &string_hash_ops_free, name, UINT32_TO_PTR(table));
if (r == -ENOMEM)
diff --git a/src/network/networkd-route-util.h b/src/network/networkd-route-util.h
index b862cd6774..1b082fc63f 100644
--- a/src/network/networkd-route-util.h
+++ b/src/network/networkd-route-util.h
@@ -44,6 +44,6 @@ int route_protocol_full_to_string_alloc(int t, char **ret);
int route_flags_to_string_alloc(uint32_t flags, char **ret);
int manager_get_route_table_from_string(const Manager *m, const char *table, uint32_t *ret);
-int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret);
+int manager_get_route_table_to_string(const Manager *m, uint32_t table, bool append_num, char **ret);
CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c
index 5214a8ad2c..f7215858e6 100644
--- a/src/network/networkd-route.c
+++ b/src/network/networkd-route.c
@@ -597,7 +597,7 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
if (in_addr_is_set(route->family, &route->prefsrc))
(void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc);
(void) route_scope_to_string_alloc(route->scope, &scope);
- (void) manager_get_route_table_to_string(manager, route->table, &table);
+ (void) manager_get_route_table_to_string(manager, route->table, /* append_num = */ true, &table);
(void) route_protocol_full_to_string_alloc(route->protocol, &proto);
(void) route_flags_to_string_alloc(route->flags, &flags);
diff --git a/src/network/networkd-routing-policy-rule.c b/src/network/networkd-routing-policy-rule.c
index 130ed5e0a7..ee3b1b275e 100644
--- a/src/network/networkd-routing-policy-rule.c
+++ b/src/network/networkd-routing-policy-rule.c
@@ -427,7 +427,7 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const c
return;
(void) network_config_state_to_string_alloc(rule->state, &state);
- (void) manager_get_route_table_to_string(m, rule->table, &table);
+ (void) manager_get_route_table_to_string(m, rule->table, /* append_num = */ true, &table);
log_link_debug(link,
"%s %s routing policy rule (%s): priority: %"PRIu32", %s -> %s, iif: %s, oif: %s, table: %s",
diff --git a/src/network/test-network.c b/src/network/test-network.c
index 250ab9eff4..35592e0733 100644
--- a/src/network/test-network.c
+++ b/src/network/test-network.c
@@ -114,9 +114,14 @@ static void test_route_tables_one(Manager *manager, const char *name, uint32_t n
}
assert_se(asprintf(&expected, "%s(%" PRIu32 ")", name, number) >= 0);
- assert_se(manager_get_route_table_to_string(manager, number, &str) >= 0);
+ assert_se(manager_get_route_table_to_string(manager, number, /* append_num = */ true, &str) >= 0);
assert_se(streq(str, expected));
+ str = mfree(str);
+
+ assert_se(manager_get_route_table_to_string(manager, number, /* append_num = */ false, &str) >= 0);
+ assert_se(streq(str, name));
+
assert_se(manager_get_route_table_from_string(manager, name, &t) >= 0);
assert_se(t == number);
@@ -148,6 +153,7 @@ static void test_route_tables(Manager *manager) {
/* Invalid pairs */
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "main:123 default:333 local:999", manager, manager) >= 0);
+ assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "xxx:253 yyy:254 local:255", manager, manager) >= 0);
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "1234:321 :567 hoge:foo aaa:-888", manager, manager) >= 0);
assert_se(!manager->route_table_names_by_number);
assert_se(!manager->route_table_numbers_by_name);