1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-22 17:35:35 +03:00

network: Add SuppressInterfaceGroup= into routing policy

This adds SuppressInterfaceGroup= option in the [RoutingPolicyRule] section
which has the same semantics as suppress_ifgroup in `ip rule` command.
This commit is contained in:
Slava Bacherikov 2021-11-04 18:54:49 +02:00 committed by Yu Watanabe
parent 10af8bb24b
commit af493fb742
6 changed files with 100 additions and 7 deletions

View File

@ -1282,6 +1282,14 @@ Table=1234</programlisting></para>
unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>SuppressInterfaceGroup=</varname></term>
<listitem>
<para>Takes an integer in the range 0…2147483647 and rejects routing decisions that have
an interface with the same group id. It has the same meaning as
<option>suppress_ifgroup</option> in <command>ip rule</command>. Defaults to unset.</para>
</listitem>
</varlistentry>
<varlistentry>
<term><varname>Type=</varname></term>
<listitem>

View File

@ -171,6 +171,7 @@ RoutingPolicyRule.DestinationPort, config_parse_routing_policy_rule_po
RoutingPolicyRule.InvertRule, config_parse_routing_policy_rule_invert, 0, 0
RoutingPolicyRule.Family, config_parse_routing_policy_rule_family, 0, 0
RoutingPolicyRule.User, config_parse_routing_policy_rule_uid_range, 0, 0
RoutingPolicyRule.SuppressInterfaceGroup, config_parse_routing_policy_rule_suppress_ifgroup, 0, 0
RoutingPolicyRule.SuppressPrefixLength, config_parse_routing_policy_rule_suppress_prefixlen, 0, 0
RoutingPolicyRule.Type, config_parse_routing_policy_rule_type, 0, 0
Route.Gateway, config_parse_gateway, 0, 0

View File

@ -65,6 +65,7 @@ static int routing_policy_rule_new(RoutingPolicyRule **ret) {
.uid_range.start = UID_INVALID,
.uid_range.end = UID_INVALID,
.suppress_prefixlen = -1,
.suppress_ifgroup = -1,
.protocol = RTPROT_UNSPEC,
.type = FR_ACT_TO_TBL,
};
@ -165,6 +166,7 @@ void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash
siphash24_compress(&rule->priority, sizeof(rule->priority), state);
siphash24_compress(&rule->table, sizeof(rule->table), state);
siphash24_compress(&rule->suppress_prefixlen, sizeof(rule->suppress_prefixlen), state);
siphash24_compress(&rule->suppress_ifgroup, sizeof(rule->suppress_ifgroup), state);
siphash24_compress(&rule->ipproto, sizeof(rule->ipproto), state);
siphash24_compress(&rule->protocol, sizeof(rule->protocol), state);
@ -240,6 +242,10 @@ int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const RoutingPo
if (r != 0)
return r;
r = CMP(a->suppress_ifgroup, b->suppress_ifgroup);
if (r != 0)
return r;
r = CMP(a->ipproto, b->ipproto);
if (r != 0)
return r;
@ -534,6 +540,12 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
return log_link_error_errno(link, r, "Could not append FRA_SUPPRESS_PREFIXLEN attribute: %m");
}
if (rule->suppress_ifgroup >= 0) {
r = sd_netlink_message_append_u32(m, FRA_SUPPRESS_IFGROUP, (uint32_t) rule->suppress_ifgroup);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FRA_SUPPRESS_IFGROUP attribute: %m");
}
r = sd_rtnl_message_routing_policy_rule_set_fib_type(m, rule->type);
if (r < 0)
return log_link_error_errno(link, r, "Could not append FIB rule type attribute: %m");
@ -855,11 +867,11 @@ int request_process_routing_policy_rule(Request *req) {
}
static const RoutingPolicyRule kernel_rules[] = {
{ .family = AF_INET, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET, .priority_set = true, .priority = 32767, .table = RT_TABLE_DEFAULT, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 0, .table = RT_TABLE_LOCAL, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
{ .family = AF_INET6, .priority_set = true, .priority = 32766, .table = RT_TABLE_MAIN, .type = FR_ACT_TO_TBL, .uid_range.start = UID_INVALID, .uid_range.end = UID_INVALID, .suppress_prefixlen = -1, .suppress_ifgroup = -1, },
};
static bool routing_policy_rule_is_created_by_kernel(const RoutingPolicyRule *rule) {
@ -1049,8 +1061,28 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_PREFIXLEN attribute, ignoring: %m");
return 0;
}
if (r >= 0)
tmp->suppress_prefixlen = (int) suppress_prefixlen;
if (r >= 0) {
/* kernel does not limit this value, but we do. */
if (suppress_prefixlen > 128) {
log_warning("rtnl: received invalid FRA_SUPPRESS_PREFIXLEN attribute value %"PRIu32", ignoring.", suppress_prefixlen);
return 0;
}
tmp->suppress_prefixlen = (int32_t) suppress_prefixlen;
}
uint32_t suppress_ifgroup;
r = sd_netlink_message_read_u32(message, FRA_SUPPRESS_IFGROUP, &suppress_ifgroup);
if (r < 0 && r != -ENODATA) {
log_warning_errno(r, "rtnl: could not get FRA_SUPPRESS_IFGROUP attribute, ignoring: %m");
return 0;
}
if (r >= 0) {
if (suppress_ifgroup > INT32_MAX) {
log_warning("rtnl: received invalid FRA_SUPPRESS_IFGROUP attribute value %"PRIu32", ignoring.", suppress_ifgroup);
return 0;
}
tmp->suppress_ifgroup = (int32_t) suppress_ifgroup;
}
if (adjust_protocol)
/* As .network files does not have setting to specify protocol, we can assume the
@ -1622,6 +1654,54 @@ int config_parse_routing_policy_rule_suppress_prefixlen(
return 0;
}
int config_parse_routing_policy_rule_suppress_ifgroup(
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;
int32_t suppress_ifgroup;
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 log_oom();
if (isempty(rvalue)) {
n->suppress_ifgroup = -1;
return 0;
}
r = safe_atoi32(rvalue, &suppress_ifgroup);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r,
"Failed to parse SuppressInterfaceGroup=, ignoring assignment: %s", rvalue);
return 0;
}
if (suppress_ifgroup < 0) {
log_syntax(unit, LOG_WARNING, filename, line, 0,
"Value of SuppressInterfaceGroup= must be in the range 0…2147483647, ignoring assignment: %s", rvalue);
return 0;
}
n->suppress_ifgroup = suppress_ifgroup;
TAKE_PTR(n);
return 0;
}
int config_parse_routing_policy_rule_type(
const char *unit,
const char *filename,

View File

@ -51,6 +51,7 @@ typedef struct RoutingPolicyRule {
struct fib_rule_uid_range uid_range;
int suppress_prefixlen;
int32_t suppress_ifgroup;
} RoutingPolicyRule;
RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule);
@ -88,4 +89,5 @@ CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_invert);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_family);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_uid_range);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_suppress_prefixlen);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_suppress_ifgroup);
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_type);

View File

@ -315,6 +315,7 @@ IPProtocol=
InvertRule=
Family=
SuppressPrefixLength=
SuppressInterfaceGroup=
User=
Type=
[IPv6SendRA]

View File

@ -561,6 +561,7 @@ Scope=
SendHostname=
Source=
SuppressPrefixLength=
SuppressInterfaceGroup=
TCP6SegmentationOffload=
TCPSegmentationOffload=
TOS=