mirror of
https://github.com/systemd/systemd-stable.git
synced 2025-01-25 06:03:40 +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>
|
is false. Defaults to yes.</para></listitem>
|
||||||
</varlistentry>
|
</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>
|
</variablelist>
|
||||||
</refsect1>
|
</refsect1>
|
||||||
|
|
||||||
|
@ -1200,8 +1200,9 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Table=</varname></term>
|
<term><varname>Table=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>Specifies the routing table identifier to lookup if the rule selector matches. Takes
|
<para>Specifies the routing table identifier to lookup if the rule selector matches. Takes one of predefined names
|
||||||
one of <literal>default</literal>, <literal>main</literal>, and <literal>local</literal>,
|
<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>
|
or a number between 1 and 4294967295. Defaults to <literal>main</literal>.</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
</varlistentry>
|
</varlistentry>
|
||||||
@ -1409,11 +1410,11 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para>
|
|||||||
<varlistentry>
|
<varlistentry>
|
||||||
<term><varname>Table=</varname></term>
|
<term><varname>Table=</varname></term>
|
||||||
<listitem>
|
<listitem>
|
||||||
<para>The table identifier for the route. Takes <literal>default</literal>,
|
<para>The table identifier for the route. Takes one of predefined names <literal>default</literal>, <literal>main</literal>,
|
||||||
<literal>main</literal>, <literal>local</literal> or a number between 1 and 4294967295.
|
and <literal>local</literal>, and names defined in <varname>RouteTable=</varname> in <citerefentry><refentrytitle>networkd.conf</refentrytitle>
|
||||||
The table can be retrieved using <command>ip route show table <replaceable>num</replaceable></command>.
|
<manvolnum>5</manvolnum></citerefentry>, or a number between 1 and 4294967295. The table can be retrieved using
|
||||||
If unset and <varname>Type=</varname> is <literal>local</literal>, <literal>broadcast</literal>,
|
<command>ip route show table <replaceable>num</replaceable></command>. If unset and <varname>Type=</varname> is <literal>local</literal>,
|
||||||
<literal>anycast</literal>, or <literal>nat</literal>, then <literal>local</literal> is used.
|
<literal>broadcast</literal>, <literal>anycast</literal>, or <literal>nat</literal>, then <literal>local</literal> is used.
|
||||||
In other cases, defaults to <literal>main</literal>.
|
In other cases, defaults to <literal>main</literal>.
|
||||||
</para>
|
</para>
|
||||||
</listitem>
|
</listitem>
|
||||||
|
@ -6,6 +6,7 @@ _Pragma("GCC diagnostic ignored \"-Wimplicit-fallthrough\"")
|
|||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "networkd-conf.h"
|
#include "networkd-conf.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
|
#include "networkd-route.h"
|
||||||
%}
|
%}
|
||||||
struct ConfigPerfItem;
|
struct ConfigPerfItem;
|
||||||
%null_strings
|
%null_strings
|
||||||
@ -21,5 +22,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, 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,6 +875,8 @@ void manager_free(Manager *m) {
|
|||||||
|
|
||||||
ordered_set_free_free(m->address_pools);
|
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.
|
/* 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. */
|
||||||
m->rules = set_free(m->rules);
|
m->rules = set_free(m->rules);
|
||||||
|
@ -65,6 +65,9 @@ struct Manager {
|
|||||||
Set *routes;
|
Set *routes;
|
||||||
Set *routes_foreign;
|
Set *routes_foreign;
|
||||||
|
|
||||||
|
/* Route table name */
|
||||||
|
Hashmap *route_tables;
|
||||||
|
|
||||||
/* For link speed meter*/
|
/* For link speed meter*/
|
||||||
bool use_speed_meter;
|
bool use_speed_meter;
|
||||||
sd_event_source *speed_meter_event_source;
|
sd_event_source *speed_meter_event_source;
|
||||||
|
@ -87,7 +87,7 @@ 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);
|
||||||
|
|
||||||
#define ROUTE_TABLE_STR_MAX CONST_MAX(DECIMAL_STR_MAX(int), STRLEN("default") + 1)
|
#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) {
|
static const char *format_route_table(int table, char *buf, size_t size) {
|
||||||
@ -1868,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,
|
||||||
@ -1899,16 +1921,11 @@ int config_parse_route_table(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
r = route_table_from_string(rvalue);
|
r = route_table_from_string_full(network->manager, rvalue, &n->table);
|
||||||
if (r >= 0)
|
if (r < 0) {
|
||||||
n->table = r;
|
log_syntax(unit, LOG_WARNING, filename, line, r,
|
||||||
else {
|
"Could not parse route table number \"%s\", ignoring assignment: %m", rvalue);
|
||||||
r = safe_atou32(rvalue, &n->table);
|
return 0;
|
||||||
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;
|
n->table_set = true;
|
||||||
@ -2356,6 +2373,77 @@ int config_parse_multipath_route(
|
|||||||
return 0;
|
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) {
|
static int route_section_verify(Route *route, Network *network) {
|
||||||
if (section_is_invalid(route->section))
|
if (section_is_invalid(route->section))
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
@ -86,6 +86,11 @@ 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 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_gateway);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
|
CONFIG_PARSER_PROTOTYPE(config_parse_preferred_src);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_destination);
|
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_route_mtu);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
CONFIG_PARSER_PROTOTYPE(config_parse_multipath_route);
|
||||||
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
CONFIG_PARSER_PROTOTYPE(config_parse_tcp_advmss);
|
||||||
|
CONFIG_PARSER_PROTOTYPE(config_parse_route_table_names);
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
#include "conf-parser.h"
|
#include "conf-parser.h"
|
||||||
#include "fileio.h"
|
#include "fileio.h"
|
||||||
#include "format-util.h"
|
#include "format-util.h"
|
||||||
|
#include "hashmap.h"
|
||||||
#include "ip-protocol-list.h"
|
#include "ip-protocol-list.h"
|
||||||
#include "netlink-util.h"
|
#include "netlink-util.h"
|
||||||
#include "networkd-manager.h"
|
#include "networkd-manager.h"
|
||||||
@ -1129,9 +1130,10 @@ int config_parse_routing_policy_rule_table(
|
|||||||
if (r < 0)
|
if (r < 0)
|
||||||
return log_oom();
|
return log_oom();
|
||||||
|
|
||||||
r = safe_atou32(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, "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;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user