mirror of
https://github.com/systemd/systemd.git
synced 2025-08-31 09:49:54 +03:00
network: add SuppressPrefixLength option to RoutingPolicyRule (#14736)
Closes #14724.
This commit is contained in:
@ -1071,7 +1071,7 @@
|
||||
<varlistentry>
|
||||
<term><varname>InvertRule=</varname></term>
|
||||
<listitem>
|
||||
<para>A boolean. Specifies whether the rule to be inverted. Defaults to false.</para>
|
||||
<para>A boolean. Specifies whether the rule is to be inverted. Defaults to false.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
@ -1091,6 +1091,14 @@
|
||||
unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
<varlistentry>
|
||||
<term><varname>SuppressPrefixLength=</varname></term>
|
||||
<listitem>
|
||||
<para>Takes a number <replaceable>N</replaceable> in the range 0-128 and rejects routing
|
||||
decisions that have a prefix length of <replaceable>N</replaceable> or less. Defaults to
|
||||
unset.</para>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
</variablelist>
|
||||
</refsect1>
|
||||
|
||||
|
@ -698,6 +698,22 @@ int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_ip_prefix_length(const char *s, int *ret) {
|
||||
unsigned l;
|
||||
int r;
|
||||
|
||||
r = safe_atou(s, &l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (l > 128)
|
||||
return -ERANGE;
|
||||
|
||||
*ret = (int) l;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int parse_dev(const char *s, dev_t *ret) {
|
||||
const char *major;
|
||||
unsigned x, y;
|
||||
|
@ -112,4 +112,6 @@ int parse_nice(const char *p, int *ret);
|
||||
int parse_ip_port(const char *s, uint16_t *ret);
|
||||
int parse_ip_port_range(const char *s, uint16_t *low, uint16_t *high);
|
||||
|
||||
int parse_ip_prefix_length(const char *s, int *ret);
|
||||
|
||||
int parse_oom_score_adjust(const char *s, int *ret);
|
||||
|
@ -962,6 +962,7 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
|
||||
_cleanup_free_ char *from = NULL, *to = NULL;
|
||||
RoutingPolicyRule *rule = NULL;
|
||||
const char *iif = NULL, *oif = NULL;
|
||||
uint32_t suppress_prefixlen;
|
||||
Manager *m = userdata;
|
||||
unsigned flags;
|
||||
uint16_t type;
|
||||
@ -1144,6 +1145,14 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, voi
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = sd_netlink_message_read_u32(message, FRA_SUPPRESS_PREFIXLEN, &suppress_prefixlen);
|
||||
if (r < 0 && r != -ENODATA) {
|
||||
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;
|
||||
|
||||
(void) routing_policy_rule_get(m, tmp, &rule);
|
||||
|
||||
if (DEBUG_LOGGING) {
|
||||
|
@ -131,6 +131,7 @@ RoutingPolicyRule.DestinationPort, config_parse_routing_policy_rule_port_ra
|
||||
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.SuppressPrefixLength, config_parse_routing_policy_rule_suppress_prefixlen, 0, 0
|
||||
Route.Gateway, config_parse_gateway, 0, 0
|
||||
Route.Destination, config_parse_destination, 0, 0
|
||||
Route.Source, config_parse_destination, 0, 0
|
||||
|
@ -30,6 +30,7 @@ int routing_policy_rule_new(RoutingPolicyRule **ret) {
|
||||
.table = RT_TABLE_MAIN,
|
||||
.uid_range.start = UID_INVALID,
|
||||
.uid_range.end = UID_INVALID,
|
||||
.suppress_prefixlen = -1,
|
||||
};
|
||||
|
||||
*ret = rule;
|
||||
@ -98,6 +99,7 @@ static int routing_policy_rule_copy(RoutingPolicyRule *dest, RoutingPolicyRule *
|
||||
dest->sport = src->sport;
|
||||
dest->dport = src->dport;
|
||||
dest->uid_range = src->uid_range;
|
||||
dest->suppress_prefixlen = src->suppress_prefixlen;
|
||||
|
||||
return 0;
|
||||
}
|
||||
@ -123,6 +125,7 @@ static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct
|
||||
siphash24_compress(&rule->fwmask, sizeof(rule->fwmask), state);
|
||||
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->protocol, sizeof(rule->protocol), state);
|
||||
siphash24_compress(&rule->sport, sizeof(rule->sport), state);
|
||||
@ -192,6 +195,10 @@ static int routing_policy_rule_compare_func(const RoutingPolicyRule *a, const Ro
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = CMP(a->suppress_prefixlen, b->suppress_prefixlen);
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
r = CMP(a->protocol, b->protocol);
|
||||
if (r != 0)
|
||||
return r;
|
||||
@ -576,6 +583,12 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
|
||||
return log_link_error_errno(link, r, "Could not append FIB_RULE_INVERT attribute: %m");
|
||||
}
|
||||
|
||||
if (rule->suppress_prefixlen >= 0) {
|
||||
r = sd_netlink_message_append_u32(m, FRA_SUPPRESS_PREFIXLEN, (uint32_t) rule->suppress_prefixlen);
|
||||
if (r < 0)
|
||||
return log_link_error_errno(link, r, "Could not append FRA_SUPPRESS_PREFIXLEN attribute: %m");
|
||||
}
|
||||
|
||||
rule->link = link;
|
||||
|
||||
r = netlink_call_async(link->manager->rtnl, NULL, m,
|
||||
@ -1114,6 +1127,48 @@ int config_parse_routing_policy_rule_uid_range(
|
||||
n->uid_range.start = start;
|
||||
n->uid_range.end = end;
|
||||
n = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int config_parse_routing_policy_rule_suppress_prefixlen(
|
||||
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;
|
||||
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;
|
||||
|
||||
r = parse_ip_prefix_length(rvalue, &n->suppress_prefixlen);
|
||||
if (r == -ERANGE) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Prefix length outside of valid range 0-128, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", rvalue);
|
||||
return 0;
|
||||
}
|
||||
|
||||
n = NULL;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1239,6 +1294,13 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
|
||||
space = true;
|
||||
}
|
||||
|
||||
if (rule->suppress_prefixlen >= 0) {
|
||||
fprintf(f, "%ssuppress_prefixlen=%d",
|
||||
space ? " " : "",
|
||||
rule->suppress_prefixlen);
|
||||
space = true;
|
||||
}
|
||||
|
||||
fprintf(f, "%stable=%"PRIu32 "\n",
|
||||
space ? " " : "",
|
||||
rule->table);
|
||||
@ -1338,14 +1400,12 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
continue;
|
||||
}
|
||||
} else if (streq(a, "fwmark")) {
|
||||
|
||||
r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse RPDB rule firewall mark or mask, ignoring: %s", a);
|
||||
continue;
|
||||
}
|
||||
} else if (streq(a, "iif")) {
|
||||
|
||||
if (free_and_strdup(&rule->iif, b) < 0)
|
||||
return log_oom();
|
||||
|
||||
@ -1360,7 +1420,6 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
continue;
|
||||
}
|
||||
} else if (streq(a, "sourceport")) {
|
||||
|
||||
r = parse_ip_port_range(b, &low, &high);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Invalid routing policy rule source port range, ignoring assignment: '%s'", b);
|
||||
@ -1369,9 +1428,7 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
|
||||
rule->sport.start = low;
|
||||
rule->sport.end = high;
|
||||
|
||||
} else if (streq(a, "destinationport")) {
|
||||
|
||||
r = parse_ip_port_range(b, &low, &high);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Invalid routing policy rule destination port range, ignoring assignment: '%s'", b);
|
||||
@ -1380,7 +1437,6 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
|
||||
rule->dport.start = low;
|
||||
rule->dport.end = high;
|
||||
|
||||
} else if (streq(a, "uidrange")) {
|
||||
uid_t lower, upper;
|
||||
|
||||
@ -1392,6 +1448,16 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
|
||||
rule->uid_range.start = lower;
|
||||
rule->uid_range.end = upper;
|
||||
} else if (streq(a, "suppress_prefixlen")) {
|
||||
r = parse_ip_prefix_length(b, &rule->suppress_prefixlen);
|
||||
if (r == -ERANGE) {
|
||||
log_error_errno(r, "Prefix length outside of valid range 0-128, ignoring: %s", b);
|
||||
continue;
|
||||
}
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse RPDB rule suppress_prefixlen, ignoring: %s", b);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -51,6 +51,8 @@ struct RoutingPolicyRule {
|
||||
struct fib_rule_port_range dport;
|
||||
struct fib_rule_uid_range uid_range;
|
||||
|
||||
int suppress_prefixlen;
|
||||
|
||||
LIST_FIELDS(RoutingPolicyRule, rules);
|
||||
};
|
||||
|
||||
@ -81,3 +83,4 @@ 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);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_uid_range);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_routing_policy_rule_suppress_prefixlen);
|
||||
|
@ -225,6 +225,7 @@ DestinationPort=
|
||||
IPProtocol=
|
||||
InvertRule=
|
||||
Family=
|
||||
SuppressPrefixLength=
|
||||
User=
|
||||
[IPv6PrefixDelegation]
|
||||
RouterPreference=
|
||||
|
@ -538,6 +538,7 @@ STP=
|
||||
Scope=
|
||||
SendHostname=
|
||||
Source=
|
||||
SuppressPrefixLength=
|
||||
TCP6SegmentationOffload=
|
||||
TCPSegmentationOffload=
|
||||
TOS=
|
||||
|
Reference in New Issue
Block a user