1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-22 13:33:56 +03:00

network: add RoutingPolicyRule.Family= setting

Closes #13233.
This commit is contained in:
Yu Watanabe 2019-08-01 07:41:36 +09:00
parent 01fc8e4f43
commit f6c6ff97f5
7 changed files with 101 additions and 2 deletions

View File

@ -1139,6 +1139,16 @@
<para>A boolean. Specifies whether the rule to be inverted. Defaults to false.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Family=</varname></term>
<listitem>
<para>Takes a special value <literal>ipv4</literal>, <literal>ipv6</literal>, or
<literal>both</literal>. By default, the address family is determined by the address
specified in <varname>To=</varname> or <varname>From=</varname>. If neither
<varname>To=</varname> nor <varname>From=</varname> are specified, then defaults to
<literal>ipv4</literal>.</para>
</listitem>
</varlistentry>
</variablelist>
</refsect1>

View File

@ -122,6 +122,7 @@ RoutingPolicyRule.IPProtocol, config_parse_routing_policy_rule_ip_prot
RoutingPolicyRule.SourcePort, config_parse_routing_policy_rule_port_range, 0, 0
RoutingPolicyRule.DestinationPort, config_parse_routing_policy_rule_port_range, 0, 0
RoutingPolicyRule.InvertRule, config_parse_routing_policy_rule_invert, 0, 0
RoutingPolicyRule.Family, config_parse_routing_policy_rule_family, 0, 0
Route.Gateway, config_parse_gateway, 0, 0
Route.Destination, config_parse_destination, 0, 0
Route.Source, config_parse_destination, 0, 0

View File

@ -11,6 +11,7 @@
#include "networkd-routing-policy-rule.h"
#include "netlink-util.h"
#include "networkd-manager.h"
#include "networkd-util.h"
#include "parse-util.h"
#include "socket-util.h"
#include "string-util.h"
@ -569,11 +570,45 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
}
int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
int r;
if (section_is_invalid(rule->section))
return -EINVAL;
if (rule->family == AF_UNSPEC)
if ((rule->family == AF_INET && FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV6)) ||
(rule->family == AF_INET6 && FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV4)))
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
"%s: address family specified by Family= conflicts with the address "
"specified by To= or From=. Ignoring [RoutingPolicyRule] section from line %u.",
rule->section->filename, rule->section->line);
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_IPV6)) {
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule6 = NULL;
assert(rule->family == AF_UNSPEC);
/* When Family=both, we need to copy the section, AF_INET and AF_INET6. */
r = routing_policy_rule_new_static(rule->network, NULL, 0, &rule6);
if (r < 0)
return r;
r = routing_policy_rule_copy(rule6, rule);
if (r < 0)
return r;
rule->family = AF_INET;
rule6->family = AF_INET6;
TAKE_PTR(rule6);
}
if (rule->family == AF_UNSPEC) {
if (FLAGS_SET(rule->address_family, ADDRESS_FAMILY_IPV6))
rule->family = AF_INET6;
else
rule->family = AF_INET;
}
return 0;
}
@ -973,6 +1008,46 @@ int config_parse_routing_policy_rule_invert(
return 0;
}
int config_parse_routing_policy_rule_family(
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_(routing_policy_rule_free_or_set_invalidp) RoutingPolicyRule *n = NULL;
Network *network = userdata;
AddressFamily a;
int r;
assert(filename);
assert(section);
assert(lvalue);
assert(rvalue);
assert(data);
r = routing_policy_rule_new_static(network, filename, section_line, &n);
if (r < 0)
return r;
a = routing_policy_rule_address_family_from_string(rvalue);
if (a < 0) {
log_syntax(unit, LOG_ERR, filename, line, 0,
"Invalid address family '%s', ignoring.", rvalue);
return 0;
}
n->address_family = a;
n = NULL;
return 0;
}
static int routing_policy_rule_read_full_file(const char *state_file, char **ret) {
_cleanup_free_ char *s = NULL;
size_t size;

View File

@ -36,7 +36,8 @@ struct RoutingPolicyRule {
uint32_t fwmask;
uint32_t priority;
int family;
AddressFamily address_family; /* Specified by Family= */
int family; /* Automatically determined by From= or To= */
unsigned char to_prefixlen;
unsigned char from_prefixlen;
@ -77,3 +78,4 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_device);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_port_range);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_ip_protocol);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_invert);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_family);

View File

@ -24,8 +24,15 @@ static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] =
[ADDRESS_FAMILY_FALLBACK_IPV4] = "ipv4-fallback",
};
static const char * const routing_policy_rule_address_family_table[_ADDRESS_FAMILY_MAX] = {
[ADDRESS_FAMILY_YES] = "both",
[ADDRESS_FAMILY_IPV4] = "ipv4",
[ADDRESS_FAMILY_IPV6] = "ipv6",
};
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family, AddressFamily, ADDRESS_FAMILY_YES);
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family, AddressFamily, ADDRESS_FAMILY_YES);
DEFINE_STRING_TABLE_LOOKUP(routing_policy_rule_address_family, AddressFamily);
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
AddressFamily, "Failed to parse option");

View File

@ -32,6 +32,9 @@ AddressFamily address_family_from_string(const char *s) _pure_;
const char *link_local_address_family_to_string(AddressFamily b) _const_;
AddressFamily link_local_address_family_from_string(const char *s) _pure_;
const char *routing_policy_rule_address_family_to_string(AddressFamily b) _const_;
AddressFamily routing_policy_rule_address_family_from_string(const char *s) _pure_;
int kernel_route_expiration_supported(void);
int network_config_section_new(const char *filename, unsigned line, NetworkConfigSection **s);

View File

@ -208,6 +208,7 @@ SourcePort=
DestinationPort=
IPProtocol=
InvertRule=
Family=
[IPv6PrefixDelegation]
RouterPreference=
DNSLifetimeSec=