mirror of
https://github.com/systemd/systemd
synced 2025-09-30 09:14:46 +02:00
Compare commits
No commits in common. "cb3363ef7af77cdaf29d2d6a6380a152cf5702bd" and "ca9fab8896995b1766787b70963ea752cbb68939" have entirely different histories.
cb3363ef7a
...
ca9fab8896
@ -72,14 +72,11 @@
|
|||||||
|
|
||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>RouteTable=</varname></term>
|
<term><varname>RouteTable=</varname></term>
|
||||||
<listitem><para>Defines the route table name. Takes a whitespace-separated list of the pairs of
|
<listitem><para>Specifies the route table name. Takes a route name and table number separated with a
|
||||||
route table name and number. The route table name and number in each pair are separated with a
|
colon. (<literal><replaceable>name</replaceable>:<replaceable>integer</replaceable></literal>. The
|
||||||
colon, i.e., <literal><replaceable>name</replaceable>:<replaceable>number</replaceable></literal>.
|
route table number must be an integer in the range 1…4294967295. This setting can be specified
|
||||||
The route table name must not be <literal>default</literal>, <literal>main</literal>, or
|
multiple times. If an empty string is specified, then all options specified earlier are cleared.
|
||||||
<literal>local</literal>, as these route table names are predefined with route table number 253,
|
Defaults to unset.</para></listitem>
|
||||||
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.</para></listitem>
|
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
|
|
||||||
</variablelist>
|
</variablelist>
|
||||||
|
@ -3842,9 +3842,6 @@ int manager_reload(Manager *m) {
|
|||||||
/* Clean up runtime objects no longer referenced */
|
/* Clean up runtime objects no longer referenced */
|
||||||
manager_vacuum(m);
|
manager_vacuum(m);
|
||||||
|
|
||||||
/* Clean up deserialized tracked clients */
|
|
||||||
m->deserialized_subscribed = strv_free(m->deserialized_subscribed);
|
|
||||||
|
|
||||||
/* Consider the reload process complete now. */
|
/* Consider the reload process complete now. */
|
||||||
assert(m->n_reloading > 0);
|
assert(m->n_reloading > 0);
|
||||||
m->n_reloading--;
|
m->n_reloading--;
|
||||||
|
@ -23,6 +23,6 @@ struct ConfigPerfItem;
|
|||||||
Network.SpeedMeter, config_parse_bool, 0, offsetof(Manager, use_speed_meter)
|
Network.SpeedMeter, config_parse_bool, 0, offsetof(Manager, use_speed_meter)
|
||||||
Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec)
|
Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec)
|
||||||
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
||||||
Network.RouteTable, config_parse_route_table_names, 0, 0
|
Network.RouteTable, config_parse_route_table_names, 0, offsetof(Manager, route_tables)
|
||||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
||||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
||||||
|
@ -875,8 +875,7 @@ void manager_free(Manager *m) {
|
|||||||
|
|
||||||
ordered_set_free_free(m->address_pools);
|
ordered_set_free_free(m->address_pools);
|
||||||
|
|
||||||
hashmap_free(m->route_table_names_by_number);
|
m->route_tables = hashmap_free_free_key(m->route_tables);
|
||||||
hashmap_free(m->route_table_numbers_by_name);
|
|
||||||
|
|
||||||
/* routing_policy_rule_free() access m->rules and m->rules_foreign.
|
/* routing_policy_rule_free() access m->rules and m->rules_foreign.
|
||||||
* So, it is necessary to set NULL after the sets are freed. */
|
* So, it is necessary to set NULL after the sets are freed. */
|
||||||
|
@ -66,8 +66,7 @@ struct Manager {
|
|||||||
Set *routes_foreign;
|
Set *routes_foreign;
|
||||||
|
|
||||||
/* Route table name */
|
/* Route table name */
|
||||||
Hashmap *route_table_numbers_by_name;
|
Hashmap *route_tables;
|
||||||
Hashmap *route_table_names_by_number;
|
|
||||||
|
|
||||||
/* For link speed meter*/
|
/* For link speed meter*/
|
||||||
bool use_speed_meter;
|
bool use_speed_meter;
|
||||||
|
@ -87,68 +87,20 @@ static const char * const route_table_table[] = {
|
|||||||
[RT_TABLE_LOCAL] = "local",
|
[RT_TABLE_LOCAL] = "local",
|
||||||
};
|
};
|
||||||
|
|
||||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_table, int);
|
DEFINE_STRING_TABLE_LOOKUP(route_table, int);
|
||||||
|
|
||||||
int manager_get_route_table_from_string(const Manager *m, const char *s, uint32_t *ret) {
|
#define ROUTE_TABLE_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("default") + 1)
|
||||||
uint32_t t;
|
static const char *format_route_table(int table, char *buf, size_t size) {
|
||||||
int r;
|
|
||||||
|
|
||||||
assert(m);
|
|
||||||
assert(s);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
r = route_table_from_string(s);
|
|
||||||
if (r >= 0) {
|
|
||||||
*ret = (uint32_t) r;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
t = PTR_TO_UINT32(hashmap_get(m->route_table_numbers_by_name, s));
|
|
||||||
if (t != 0) {
|
|
||||||
*ret = t;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = safe_atou32(s, &t);
|
|
||||||
if (r < 0)
|
|
||||||
return r;
|
|
||||||
|
|
||||||
if (t == 0)
|
|
||||||
return -ERANGE;
|
|
||||||
|
|
||||||
*ret = t;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret) {
|
|
||||||
_cleanup_free_ char *str = NULL;
|
|
||||||
const char *s;
|
const char *s;
|
||||||
|
char *p = buf;
|
||||||
assert(m);
|
|
||||||
assert(ret);
|
|
||||||
|
|
||||||
if (table == 0)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
s = route_table_to_string(table);
|
s = route_table_to_string(table);
|
||||||
if (!s)
|
if (s)
|
||||||
s = hashmap_get(m->route_table_names_by_number, UINT32_TO_PTR(table));
|
strpcpy(&p, size, s);
|
||||||
|
else
|
||||||
|
strpcpyf(&p, size, "%d", table);
|
||||||
|
|
||||||
if (s) {
|
return buf;
|
||||||
/* Currently, this is only used in debugging logs. To not confuse any bug
|
|
||||||
* reports, let's include the table number. */
|
|
||||||
if (asprintf(&str, "%s(%" PRIu32 ")", s, table) < 0)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(str);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (asprintf(&str, "%" PRIu32, table) < 0)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
*ret = TAKE_PTR(str);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char * const route_protocol_table[] = {
|
static const char * const route_protocol_table[] = {
|
||||||
@ -632,16 +584,15 @@ static bool route_type_is_reject(const Route *route) {
|
|||||||
return IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW);
|
return IN_SET(route->type, RTN_UNREACHABLE, RTN_PROHIBIT, RTN_BLACKHOLE, RTN_THROW);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_route_debug(const Route *route, const char *str, const Link *link, const Manager *m) {
|
static void log_route_debug(const Route *route, const char *str, const Link *link) {
|
||||||
assert(route);
|
assert(route);
|
||||||
assert(str);
|
assert(str);
|
||||||
assert(m);
|
|
||||||
|
|
||||||
/* link may be NULL. */
|
/* link may be NULL. */
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL, *table = NULL;
|
_cleanup_free_ char *dst = NULL, *dst_prefixlen = NULL, *src = NULL, *gw = NULL, *prefsrc = NULL;
|
||||||
char scope[ROUTE_SCOPE_STR_MAX], protocol[ROUTE_PROTOCOL_STR_MAX];
|
char scope[ROUTE_SCOPE_STR_MAX], table[ROUTE_TABLE_STR_MAX], protocol[ROUTE_PROTOCOL_STR_MAX];
|
||||||
|
|
||||||
if (!in_addr_is_null(route->family, &route->dst)) {
|
if (!in_addr_is_null(route->family, &route->dst)) {
|
||||||
(void) in_addr_to_string(route->family, &route->dst, &dst);
|
(void) in_addr_to_string(route->family, &route->dst, &dst);
|
||||||
@ -653,13 +604,12 @@ static void log_route_debug(const Route *route, const char *str, const Link *lin
|
|||||||
(void) in_addr_to_string(route->gw_family, &route->gw, &gw);
|
(void) in_addr_to_string(route->gw_family, &route->gw, &gw);
|
||||||
if (!in_addr_is_null(route->family, &route->prefsrc))
|
if (!in_addr_is_null(route->family, &route->prefsrc))
|
||||||
(void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc);
|
(void) in_addr_to_string(route->family, &route->prefsrc, &prefsrc);
|
||||||
(void) manager_get_route_table_to_string(m, route->table, &table);
|
|
||||||
|
|
||||||
log_link_debug(link,
|
log_link_debug(link,
|
||||||
"%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
|
"%s route: dst: %s%s, src: %s, gw: %s, prefsrc: %s, scope: %s, table: %s, proto: %s, type: %s",
|
||||||
str, strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc),
|
str, strna(dst), strempty(dst_prefixlen), strna(src), strna(gw), strna(prefsrc),
|
||||||
format_route_scope(route->scope, scope, sizeof(scope)),
|
format_route_scope(route->scope, scope, sizeof(scope)),
|
||||||
strna(table),
|
format_route_table(route->table, table, sizeof(table)),
|
||||||
format_route_protocol(route->protocol, protocol, sizeof(protocol)),
|
format_route_protocol(route->protocol, protocol, sizeof(protocol)),
|
||||||
strna(route_type_to_string(route->type)));
|
strna(route_type_to_string(route->type)));
|
||||||
}
|
}
|
||||||
@ -801,7 +751,7 @@ int route_remove(
|
|||||||
manager = link->manager;
|
manager = link->manager;
|
||||||
/* link may be NULL! */
|
/* link may be NULL! */
|
||||||
|
|
||||||
log_route_debug(route, "Removing", link, manager);
|
log_route_debug(route, "Removing", link);
|
||||||
|
|
||||||
r = sd_rtnl_message_new_route(manager->rtnl, &req,
|
r = sd_rtnl_message_new_route(manager->rtnl, &req,
|
||||||
RTM_DELROUTE, route->family,
|
RTM_DELROUTE, route->family,
|
||||||
@ -1116,7 +1066,7 @@ int route_configure(
|
|||||||
return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
|
return log_link_error_errno(link, SYNTHETIC_ERRNO(E2BIG),
|
||||||
"Too many routes are configured, refusing: %m");
|
"Too many routes are configured, refusing: %m");
|
||||||
|
|
||||||
log_route_debug(route, "Configuring", link, link->manager);
|
log_route_debug(route, "Configuring", link);
|
||||||
|
|
||||||
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
|
r = sd_rtnl_message_new_route(link->manager->rtnl, &req,
|
||||||
RTM_NEWROUTE, route->family,
|
RTM_NEWROUTE, route->family,
|
||||||
@ -1345,10 +1295,10 @@ static int process_route_one(Manager *manager, Link *link, uint16_t type, const
|
|||||||
case RTM_NEWROUTE:
|
case RTM_NEWROUTE:
|
||||||
if (!route) {
|
if (!route) {
|
||||||
if (!manager->manage_foreign_routes)
|
if (!manager->manage_foreign_routes)
|
||||||
log_route_debug(tmp, "Ignoring received foreign", link, manager);
|
log_route_debug(tmp, "Ignoring received foreign", link);
|
||||||
else {
|
else {
|
||||||
/* A route appeared that we did not request */
|
/* A route appeared that we did not request */
|
||||||
log_route_debug(tmp, "Remembering foreign", link, manager);
|
log_route_debug(tmp, "Remembering foreign", link);
|
||||||
r = route_add_foreign(manager, link, tmp, NULL);
|
r = route_add_foreign(manager, link, tmp, NULL);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_link_warning_errno(link, r, "Failed to remember foreign route, ignoring: %m");
|
log_link_warning_errno(link, r, "Failed to remember foreign route, ignoring: %m");
|
||||||
@ -1356,15 +1306,14 @@ static int process_route_one(Manager *manager, Link *link, uint16_t type, const
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
log_route_debug(tmp, "Received remembered", link, manager);
|
log_route_debug(tmp, "Received remembered", link);
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case RTM_DELROUTE:
|
case RTM_DELROUTE:
|
||||||
log_route_debug(tmp,
|
log_route_debug(tmp,
|
||||||
route ? "Forgetting" :
|
route ? "Forgetting" :
|
||||||
manager->manage_foreign_routes ? "Kernel removed unknown" : "Ignoring received foreign",
|
manager->manage_foreign_routes ? "Kernel removed unknown" : "Ignoring received foreign", link);
|
||||||
link, manager);
|
|
||||||
route_free(route);
|
route_free(route);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -1919,6 +1868,28 @@ int config_parse_route_scope(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int route_table_from_string_full(Manager *m, const char *s, uint32_t *ret) {
|
||||||
|
int r;
|
||||||
|
|
||||||
|
assert(s);
|
||||||
|
assert(m);
|
||||||
|
assert(ret);
|
||||||
|
|
||||||
|
r = route_table_from_string(s);
|
||||||
|
if (r >= 0) {
|
||||||
|
*ret = (uint32_t) r;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t t = PTR_TO_UINT32(hashmap_get(m->route_tables, s));
|
||||||
|
if (t != 0) {
|
||||||
|
*ret = t;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
return safe_atou32(s, ret);
|
||||||
|
}
|
||||||
|
|
||||||
int config_parse_route_table(
|
int config_parse_route_table(
|
||||||
const char *unit,
|
const char *unit,
|
||||||
const char *filename,
|
const char *filename,
|
||||||
@ -1950,7 +1921,7 @@ int config_parse_route_table(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = manager_get_route_table_from_string(network->manager, rvalue, &n->table);
|
r = route_table_from_string_full(network->manager, rvalue, &n->table);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
|
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||||
@ -2414,98 +2385,63 @@ int config_parse_route_table_names(
|
|||||||
void *data,
|
void *data,
|
||||||
void *userdata) {
|
void *userdata) {
|
||||||
|
|
||||||
Manager *m = userdata;
|
_cleanup_free_ char *name = NULL;
|
||||||
|
Hashmap **s = data;
|
||||||
|
uint32_t table;
|
||||||
|
const char *p;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
assert(filename);
|
assert(filename);
|
||||||
assert(lvalue);
|
assert(lvalue);
|
||||||
assert(rvalue);
|
assert(rvalue);
|
||||||
assert(userdata);
|
assert(data);
|
||||||
|
|
||||||
if (isempty(rvalue)) {
|
if (isempty(rvalue)) {
|
||||||
m->route_table_names_by_number = hashmap_free(m->route_table_names_by_number);
|
*s = hashmap_free_free_key(*s);
|
||||||
m->route_table_numbers_by_name = hashmap_free(m->route_table_numbers_by_name);
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const char *p = rvalue;;) {
|
p = rvalue;
|
||||||
_cleanup_free_ char *name = NULL;
|
r = extract_first_word(&p, &name, ":", 0);
|
||||||
uint32_t table;
|
|
||||||
char *num;
|
|
||||||
|
|
||||||
r = extract_first_word(&p, &name, NULL, 0);
|
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
if (r < 0) {
|
if (r <= 0 || isempty(p)) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Invalid RouteTable=, ignoring assignment: %s", rvalue);
|
"Invalid RouteTable=, ignoring assignment: %s", rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (r == 0)
|
|
||||||
|
if (STR_IN_SET(name, "default", "main","local")) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
|
"Route table name %s already preconfigured. Ignoring assignment: %s", name, rvalue);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
num = strchr(name, ':');
|
|
||||||
if (!num) {
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
|
||||||
"Invalid route table name and number pair, ignoring assignment: %s", name);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
*num++ = '\0';
|
r = safe_atou32(p, &table);
|
||||||
|
|
||||||
if (STR_IN_SET(name, "default", "main", "local")) {
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
|
||||||
"Route table name %s already predefined. Ignoring assignment: %s:%s", name, name, num);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
r = safe_atou32(num, &table);
|
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Failed to parse route table number '%s', ignoring assignment: %s:%s", num, name, num);
|
"Failed to parse RouteTable=, ignoring assignment: %s", p);
|
||||||
continue;
|
return 0;
|
||||||
}
|
|
||||||
if (table == 0) {
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
|
||||||
"Invalid route table number, ignoring assignment: %s:%s", name, num);
|
|
||||||
continue;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = hashmap_ensure_put(&m->route_table_numbers_by_name, &string_hash_ops_free, name, UINT32_TO_PTR(table));
|
if (table == 0) {
|
||||||
|
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||||
|
"Invalid RouteTable=, ignoring assignment: %s", p);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
r = hashmap_ensure_put(s, &string_hash_ops, name, UINT32_TO_PTR(table));
|
||||||
if (r == -ENOMEM)
|
if (r == -ENOMEM)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
if (r == -EEXIST) {
|
if (r == -EEXIST) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
|
"Specified RouteTable= name and value pair conflicts with others, ignoring assignment: %s", rvalue);
|
||||||
continue;
|
return 0;
|
||||||
}
|
}
|
||||||
if (r < 0) {
|
if (r > 0)
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
|
||||||
"Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
if (r == 0)
|
|
||||||
/* The entry is duplicated. It should not be added to route_table_names_by_number hashmap. */
|
|
||||||
continue;
|
|
||||||
|
|
||||||
r = hashmap_ensure_put(&m->route_table_names_by_number, NULL, UINT32_TO_PTR(table), name);
|
|
||||||
if (r < 0) {
|
|
||||||
hashmap_remove(m->route_table_numbers_by_name, name);
|
|
||||||
|
|
||||||
if (r == -ENOMEM)
|
|
||||||
return log_oom();
|
|
||||||
if (r == -EEXIST)
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
|
||||||
"Specified route table name and number pair conflicts with others, ignoring assignment: %s:%s", name, num);
|
|
||||||
else
|
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
|
||||||
"Failed to store route table name and number pair, ignoring assignment: %s:%s", name, num);
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
assert(r > 0);
|
|
||||||
|
|
||||||
TAKE_PTR(name);
|
TAKE_PTR(name);
|
||||||
}
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int route_section_verify(Route *route, Network *network) {
|
static int route_section_verify(Route *route, Network *network) {
|
||||||
|
@ -86,8 +86,10 @@ int network_add_ipv4ll_route(Network *network);
|
|||||||
int network_add_default_route_on_device(Network *network);
|
int network_add_default_route_on_device(Network *network);
|
||||||
void network_drop_invalid_routes(Network *network);
|
void network_drop_invalid_routes(Network *network);
|
||||||
|
|
||||||
int manager_get_route_table_from_string(const Manager *m, const char *table, uint32_t *ret);
|
int route_table_from_string_full(Manager *m, const char *table, uint32_t *ret);
|
||||||
int manager_get_route_table_to_string(const Manager *m, uint32_t table, char **ret);
|
|
||||||
|
const char *route_table_to_string(int d) _const_;
|
||||||
|
int route_table_from_string(const char *d) _pure_;
|
||||||
|
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_gateway);
|
CONFIG_PARSER_PROTOTYPE(config_parse_gateway);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
|
CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
|
||||||
|
@ -389,25 +389,23 @@ static int routing_policy_rule_consume_foreign(Manager *m, RoutingPolicyRule *ru
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int family, const char *str, const Link *link, const Manager *m) {
|
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int family, const char *str, const Link *link) {
|
||||||
assert(rule);
|
assert(rule);
|
||||||
assert(IN_SET(family, AF_INET, AF_INET6));
|
assert(IN_SET(family, AF_INET, AF_INET6));
|
||||||
assert(str);
|
assert(str);
|
||||||
assert(m);
|
|
||||||
|
|
||||||
/* link may be NULL. */
|
/* link may be NULL. */
|
||||||
|
|
||||||
if (DEBUG_LOGGING) {
|
if (DEBUG_LOGGING) {
|
||||||
_cleanup_free_ char *from = NULL, *to = NULL, *table = NULL;
|
_cleanup_free_ char *from = NULL, *to = NULL;
|
||||||
|
|
||||||
(void) in_addr_to_string(family, &rule->from, &from);
|
(void) in_addr_to_string(family, &rule->from, &from);
|
||||||
(void) in_addr_to_string(family, &rule->to, &to);
|
(void) in_addr_to_string(family, &rule->to, &to);
|
||||||
(void) manager_get_route_table_to_string(m, rule->table, &table);
|
|
||||||
|
|
||||||
log_link_debug(link,
|
log_link_debug(link,
|
||||||
"%s routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %s",
|
"%s routing policy rule: priority: %"PRIu32", %s/%u -> %s/%u, iif: %s, oif: %s, table: %"PRIu32,
|
||||||
str, rule->priority, strna(from), rule->from_prefixlen, strna(to), rule->to_prefixlen,
|
str, rule->priority, strna(from), rule->from_prefixlen, strna(to), rule->to_prefixlen,
|
||||||
strna(rule->iif), strna(rule->oif), strna(table));
|
strna(rule->iif), strna(rule->oif), rule->table);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -553,7 +551,7 @@ static int routing_policy_rule_remove(const RoutingPolicyRule *rule, Manager *ma
|
|||||||
assert(manager->rtnl);
|
assert(manager->rtnl);
|
||||||
assert(IN_SET(rule->family, AF_INET, AF_INET6));
|
assert(IN_SET(rule->family, AF_INET, AF_INET6));
|
||||||
|
|
||||||
log_routing_policy_rule_debug(rule, rule->family, "Removing", NULL, manager);
|
log_routing_policy_rule_debug(rule, rule->family, "Removing", NULL);
|
||||||
|
|
||||||
r = sd_rtnl_message_new_routing_policy_rule(manager->rtnl, &m, RTM_DELRULE, rule->family);
|
r = sd_rtnl_message_new_routing_policy_rule(manager->rtnl, &m, RTM_DELRULE, rule->family);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -612,7 +610,7 @@ static int routing_policy_rule_configure_internal(const RoutingPolicyRule *rule,
|
|||||||
assert(link->manager);
|
assert(link->manager);
|
||||||
assert(link->manager->rtnl);
|
assert(link->manager->rtnl);
|
||||||
|
|
||||||
log_routing_policy_rule_debug(rule, family, "Configuring", link, link->manager);
|
log_routing_policy_rule_debug(rule, family, "Configuring", link);
|
||||||
|
|
||||||
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, family);
|
r = sd_rtnl_message_new_routing_policy_rule(link->manager->rtnl, &m, RTM_NEWRULE, family);
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
@ -975,9 +973,9 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
|
|||||||
switch (type) {
|
switch (type) {
|
||||||
case RTM_NEWRULE:
|
case RTM_NEWRULE:
|
||||||
if (rule)
|
if (rule)
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL);
|
||||||
else {
|
else {
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL);
|
||||||
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp));
|
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp));
|
||||||
if (r < 0)
|
if (r < 0)
|
||||||
log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
|
log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
|
||||||
@ -985,10 +983,10 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
|
|||||||
break;
|
break;
|
||||||
case RTM_DELRULE:
|
case RTM_DELRULE:
|
||||||
if (rule) {
|
if (rule) {
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Forgetting", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Forgetting", NULL);
|
||||||
routing_policy_rule_free(rule);
|
routing_policy_rule_free(rule);
|
||||||
} else
|
} else
|
||||||
log_routing_policy_rule_debug(tmp, tmp->family, "Kernel removed unknown", NULL, m);
|
log_routing_policy_rule_debug(tmp, tmp->family, "Kernel removed unknown", NULL);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1132,7 +1130,7 @@ int config_parse_routing_policy_rule_table(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = manager_get_route_table_from_string(network->manager, rvalue, &n->table);
|
r = route_table_from_string_full(network->manager, rvalue, &n->table);
|
||||||
if (r < 0) {
|
if (r < 0) {
|
||||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
"Could not parse RPDB rule route table number \"%s\", ignoring assignment: %m", rvalue);
|
"Could not parse RPDB rule route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||||
|
@ -12,7 +12,6 @@
|
|||||||
#include "network-internal.h"
|
#include "network-internal.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
#include "string-util.h"
|
#include "string-util.h"
|
||||||
#include "strv.h"
|
|
||||||
#include "tests.h"
|
#include "tests.h"
|
||||||
|
|
||||||
static void test_deserialize_in_addr(void) {
|
static void test_deserialize_in_addr(void) {
|
||||||
@ -102,53 +101,6 @@ static void test_deserialize_dhcp_routes(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_route_tables_one(Manager *manager, const char *name, uint32_t number) {
|
|
||||||
_cleanup_free_ char *str = NULL, *expected = NULL, *num_str = NULL;
|
|
||||||
uint32_t t;
|
|
||||||
|
|
||||||
if (!STR_IN_SET(name, "default", "main", "local")) {
|
|
||||||
assert_se(streq(hashmap_get(manager->route_table_names_by_number, UINT32_TO_PTR(number)), name));
|
|
||||||
assert_se(PTR_TO_UINT32(hashmap_get(manager->route_table_numbers_by_name, name)) == number);
|
|
||||||
}
|
|
||||||
|
|
||||||
assert_se(asprintf(&expected, "%s(%" PRIu32 ")", name, number) >= 0);
|
|
||||||
assert_se(manager_get_route_table_to_string(manager, number, &str) >= 0);
|
|
||||||
assert_se(streq(str, expected));
|
|
||||||
|
|
||||||
assert_se(manager_get_route_table_from_string(manager, name, &t) >= 0);
|
|
||||||
assert_se(t == number);
|
|
||||||
|
|
||||||
assert_se(asprintf(&num_str, "%" PRIu32, number) >= 0);
|
|
||||||
assert_se(manager_get_route_table_from_string(manager, num_str, &t) >= 0);
|
|
||||||
assert_se(t == number);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void test_route_tables(Manager *manager) {
|
|
||||||
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "hoge:123 foo:456 aaa:111", manager, manager) >= 0);
|
|
||||||
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "bbb:11111 ccc:22222", manager, manager) >= 0);
|
|
||||||
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "ddd:22222", manager, manager) >= 0);
|
|
||||||
|
|
||||||
test_route_tables_one(manager, "hoge", 123);
|
|
||||||
test_route_tables_one(manager, "foo", 456);
|
|
||||||
test_route_tables_one(manager, "aaa", 111);
|
|
||||||
test_route_tables_one(manager, "bbb", 11111);
|
|
||||||
test_route_tables_one(manager, "ccc", 22222);
|
|
||||||
|
|
||||||
assert_se(!hashmap_get(manager->route_table_numbers_by_name, "ddd"));
|
|
||||||
|
|
||||||
test_route_tables_one(manager, "default", 253);
|
|
||||||
test_route_tables_one(manager, "main", 254);
|
|
||||||
test_route_tables_one(manager, "local", 255);
|
|
||||||
|
|
||||||
assert_se(config_parse_route_table_names("manager", "filename", 1, "section", 1, "RouteTable", 0, "", manager, manager) >= 0);
|
|
||||||
assert_se(!manager->route_table_names_by_number);
|
|
||||||
assert_se(!manager->route_table_numbers_by_name);
|
|
||||||
|
|
||||||
test_route_tables_one(manager, "default", 253);
|
|
||||||
test_route_tables_one(manager, "main", 254);
|
|
||||||
test_route_tables_one(manager, "local", 255);
|
|
||||||
}
|
|
||||||
|
|
||||||
static int test_load_config(Manager *manager) {
|
static int test_load_config(Manager *manager) {
|
||||||
int r;
|
int r;
|
||||||
/* TODO: should_reload, is false if the config dirs do not exist, so
|
/* TODO: should_reload, is false if the config dirs do not exist, so
|
||||||
@ -289,8 +241,6 @@ int main(void) {
|
|||||||
|
|
||||||
assert_se(manager_new(&manager) >= 0);
|
assert_se(manager_new(&manager) >= 0);
|
||||||
|
|
||||||
test_route_tables(manager);
|
|
||||||
|
|
||||||
r = test_load_config(manager);
|
r = test_load_config(manager);
|
||||||
if (r == -EPERM)
|
if (r == -EPERM)
|
||||||
return log_tests_skipped("Cannot load configuration");
|
return log_tests_skipped("Cannot load configuration");
|
||||||
|
Loading…
x
Reference in New Issue
Block a user