mirror of
https://github.com/systemd/systemd.git
synced 2024-12-22 17:35:35 +03:00
network: add support to RoutingPolicyRule lookup table name
This commit is contained in:
parent
656e5aa452
commit
c038ce4606
@ -70,6 +70,14 @@
|
||||
is false. Defaults to yes.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><varname>RouteTable=</varname></term>
|
||||
<listitem><para>Specifies the route table name. Takes a route name and table number separated with a colon.
|
||||
(<literal><replaceable>name</replaceable>:<replaceable>integer</replaceable></literal>. 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 all options specified earlier are cleared. Defaults to unset.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -1200,8 +1200,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Table=</varname></term>
|
||||
<listitem>
|
||||
<para>Specifies the routing table identifier to lookup if the rule selector matches. Takes
|
||||
one of <literal>default</literal>, <literal>main</literal>, and <literal>local</literal>,
|
||||
<para>Specifies the routing table identifier to lookup if the rule selector matches. Takes one of predefined names
|
||||
<literal>default</literal>, <literal>main</literal>, and <literal>local</literal>, and names defined in <varname>RouteTable=</varname>
|
||||
in <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
|
||||
or a number between 1 and 4294967295. Defaults to <literal>main</literal>.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -1409,11 +1410,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
||||
<varlistentry>
|
||||
<term><varname>Table=</varname></term>
|
||||
<listitem>
|
||||
<para>The table identifier for the route. Takes <literal>default</literal>,
|
||||
<literal>main</literal>, <literal>local</literal> or a number between 1 and 4294967295.
|
||||
The table can be retrieved using <command>ip route show table <replaceable>num</replaceable></command>.
|
||||
If unset and <varname>Type=</varname> is <literal>local</literal>, <literal>broadcast</literal>,
|
||||
<literal>anycast</literal>, or <literal>nat</literal>, then <literal>local</literal> is used.
|
||||
<para>The table identifier for the route. Takes one of predefined names <literal>default</literal>, <literal>main</literal>,
|
||||
and <literal>local</literal>, and names defined in <varname>RouteTable=</varname> in <citerefentry><refentrytitle>networkd.conf</refentrytitle>
|
||||
<manvolnum>5</manvolnum></citerefentry>, or a number between 1 and 4294967295. The table can be retrieved using
|
||||
<command>ip route show table <replaceable>num</replaceable></command>. If unset and <varname>Type=</varname> is <literal>local</literal>,
|
||||
<literal>broadcast</literal>, <literal>anycast</literal>, or <literal>nat</literal>, then <literal>local</literal> is used.
|
||||
In other cases, defaults to <literal>main</literal>.
|
||||
</para>
|
||||
</listitem>
|
||||
|
@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
||||
#include "conf-parser.h"
|
||||
#include "networkd-conf.h"
|
||||
#include "networkd-manager.h"
|
||||
#include "networkd-route.h"
|
||||
%}
|
||||
struct ConfigPerfItem;
|
||||
%null_strings
|
||||
@ -21,5 +22,6 @@ struct ConfigPerfItem;
|
||||
Network.SpeedMeter, config_parse_bool, 0, offsetof(Manager, use_speed_meter)
|
||||
Network.SpeedMeterIntervalSec, config_parse_sec, 0, offsetof(Manager, speed_meter_interval_usec)
|
||||
Network.ManageForeignRoutes, config_parse_bool, 0, offsetof(Manager, manage_foreign_routes)
|
||||
Network.RouteTable, config_parse_route_table_names, 0, offsetof(Manager, route_tables)
|
||||
DHCP.DUIDType, config_parse_duid_type, 0, offsetof(Manager, duid)
|
||||
DHCP.DUIDRawData, config_parse_duid_rawdata, 0, offsetof(Manager, duid)
|
||||
|
@ -875,6 +875,8 @@ void manager_free(Manager *m) {
|
||||
|
||||
ordered_set_free_free(m->address_pools);
|
||||
|
||||
m->route_tables = hashmap_free_free_key(m->route_tables);
|
||||
|
||||
/* routing_policy_rule_free() access m->rules and m->rules_foreign.
|
||||
* So, it is necessary to set NULL after the sets are freed. */
|
||||
m->rules = set_free(m->rules);
|
||||
|
@ -65,6 +65,9 @@ struct Manager {
|
||||
Set *routes;
|
||||
Set *routes_foreign;
|
||||
|
||||
/* Route table name */
|
||||
Hashmap *route_tables;
|
||||
|
||||
/* For link speed meter*/
|
||||
bool use_speed_meter;
|
||||
sd_event_source *speed_meter_event_source;
|
||||
|
@ -87,7 +87,7 @@ static const char * const route_table_table[] = {
|
||||
[RT_TABLE_LOCAL] = "local",
|
||||
};
|
||||
|
||||
DEFINE_PRIVATE_STRING_TABLE_LOOKUP(route_table, int);
|
||||
DEFINE_STRING_TABLE_LOOKUP(route_table, int);
|
||||
|
||||
#define ROUTE_TABLE_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("default") + 1)
|
||||
static const char *format_route_table(int table, char *buf, size_t size) {
|
||||
@ -1868,6 +1868,28 @@ int config_parse_route_scope(
|
||||
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(
|
||||
const char *unit,
|
||||
const char *filename,
|
||||
@ -1899,16 +1921,11 @@ int config_parse_route_table(
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = route_table_from_string(rvalue);
|
||||
if (r >= 0)
|
||||
n->table = r;
|
||||
else {
|
||||
r = safe_atou32(rvalue, &n->table);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
r = route_table_from_string_full(network->manager, rvalue, &n->table);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n->table_set = true;
|
||||
@ -2356,6 +2373,77 @@ int config_parse_multipath_route(
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_route_table_names(
|
||||
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) {
|
||||
|
||||
_cleanup_free_ char *name = NULL;
|
||||
Hashmap **s = data;
|
||||
uint32_t table;
|
||||
const char *p;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
assert(rvalue);
|
||||
assert(data);
|
||||
|
||||
if (isempty(rvalue)) {
|
||||
*s = hashmap_free_free_key(*s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = rvalue;
|
||||
r = extract_first_word(&p, &name, ":", 0);
|
||||
if (r == -ENOMEM)
|
||||
return log_oom();
|
||||
if (r <= 0 || isempty(p)) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Invalid RouteTable=, ignoring assignment: %s", rvalue);
|
||||
return 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;
|
||||
}
|
||||
|
||||
r = safe_atou32(p, &table);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Failed to parse RouteTable=, ignoring assignment: %s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
return log_oom();
|
||||
if (r == -EEXIST) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Specified RouteTable= name and value pair conflicts with others, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r > 0)
|
||||
TAKE_PTR(name);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int route_section_verify(Route *route, Network *network) {
|
||||
if (section_is_invalid(route->section))
|
||||
return -EINVAL;
|
||||
|
@ -86,6 +86,11 @@ int network_add_ipv4ll_route(Network *network);
|
||||
int network_add_default_route_on_device(Network *network);
|
||||
void network_drop_invalid_routes(Network *network);
|
||||
|
||||
int route_table_from_string_full(Manager *m, const char *table, uint32_t *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_preferred_src);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_destination);
|
||||
@ -100,3 +105,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_tcp_window);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_mtu);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
|
||||
|
@ -8,6 +8,7 @@
|
||||
#include "conf-parser.h"
|
||||
#include "fileio.h"
|
||||
#include "format-util.h"
|
||||
#include "hashmap.h"
|
||||
#include "ip-protocol-list.h"
|
||||
#include "netlink-util.h"
|
||||
#include "networkd-manager.h"
|
||||
@ -1129,9 +1130,10 @@ int config_parse_routing_policy_rule_table(
|
||||
if (r < 0)
|
||||
return log_oom();
|
||||
|
||||
r = safe_atou32(rvalue, &n->table);
|
||||
r = route_table_from_string_full(network->manager, rvalue, &n->table);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r, "Failed to parse RPDB rule table, ignoring: %s", rvalue);
|
||||
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||
"Could not parse RPDB rule route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user