network/routing-policy-rule: use in_addr_prefix for From= and To=

Also, this makes the settings parsed independently, and the
inconsistency will be checked in the section verifier.

No functional change, just refactoring.
This commit is contained in:
Yu Watanabe
2024-09-23 01:51:43 +09:00
parent 8cde9f6c5a
commit f8a31c90cc
4 changed files with 44 additions and 78 deletions

View File

@@ -298,12 +298,12 @@ static int routing_policy_rule_append_json(RoutingPolicyRule *rule, sd_json_vari
return sd_json_variant_append_arraybo(
array,
SD_JSON_BUILD_PAIR_INTEGER("Family", rule->family),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("FromPrefix", &rule->from, rule->family),
SD_JSON_BUILD_PAIR_CONDITION(in_addr_is_set(rule->family, &rule->from),
"FromPrefixLength", SD_JSON_BUILD_UNSIGNED(rule->from_prefixlen)),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ToPrefix", &rule->to, rule->family),
SD_JSON_BUILD_PAIR_CONDITION(in_addr_is_set(rule->family, &rule->to),
"ToPrefixLength", SD_JSON_BUILD_UNSIGNED(rule->to_prefixlen)),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("FromPrefix", &rule->from.address, rule->family),
SD_JSON_BUILD_PAIR_CONDITION(in_addr_is_set(rule->family, &rule->from.address),
"FromPrefixLength", SD_JSON_BUILD_UNSIGNED(rule->from.prefixlen)),
JSON_BUILD_PAIR_IN_ADDR_NON_NULL("ToPrefix", &rule->to.address, rule->family),
SD_JSON_BUILD_PAIR_CONDITION(in_addr_is_set(rule->family, &rule->to.address),
"ToPrefixLength", SD_JSON_BUILD_UNSIGNED(rule->to.prefixlen)),
SD_JSON_BUILD_PAIR_UNSIGNED("Protocol", rule->protocol),
SD_JSON_BUILD_PAIR_STRING("ProtocolString", protocol),
SD_JSON_BUILD_PAIR_UNSIGNED("TOS", rule->tos),

View File

@@ -177,12 +177,12 @@ Neighbor.Address, config_parse_neighbor_section,
Neighbor.LinkLayerAddress, config_parse_neighbor_section, NEIGHBOR_LINK_LAYER_ADDRESS, 0
Neighbor.MACAddress, config_parse_neighbor_section, NEIGHBOR_LINK_LAYER_ADDRESS, 0 /* deprecated */
RoutingPolicyRule.TypeOfService, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_TOS, 0
RoutingPolicyRule.Priority, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PRIORITY, 0
RoutingPolicyRule.Priority, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PRIORITY, 0
RoutingPolicyRule.GoTo, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_GOTO, 0
RoutingPolicyRule.Table, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_TABLE, 0
RoutingPolicyRule.FirewallMark, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_FWMARK, 0
RoutingPolicyRule.From, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PREFIX, 0
RoutingPolicyRule.To, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_PREFIX, 0
RoutingPolicyRule.From, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_FROM, 0
RoutingPolicyRule.To, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_TO, 0
RoutingPolicyRule.IncomingInterface, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_IIF, 0
RoutingPolicyRule.OutgoingInterface, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_OIF, 0
RoutingPolicyRule.IPProtocol, config_parse_routing_policy_rule, ROUTING_POLICY_RULE_IP_PROTOCOL, 0

View File

@@ -215,12 +215,12 @@ static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct
siphash24_compress_typesafe(rule->dport, state);
/* See fib4_rule_compare() in net/ipv4/fib_rules.c, and fib6_rule_compare() in net/ipv6/fib6_rules.c. */
siphash24_compress_typesafe(rule->from_prefixlen, state);
siphash24_compress_typesafe(rule->to_prefixlen, state);
siphash24_compress_typesafe(rule->from.prefixlen, state);
siphash24_compress_typesafe(rule->to.prefixlen, state);
siphash24_compress_typesafe(rule->tos, state);
siphash24_compress_typesafe(rule->realms, state);
in_addr_hash_func(&rule->from, rule->family, state);
in_addr_hash_func(&rule->to, rule->family, state);
in_addr_hash_func(&rule->from.address, rule->family, state);
in_addr_hash_func(&rule->to.address, rule->family, state);
}
static int routing_policy_rule_compare_func_full(const RoutingPolicyRule *a, const RoutingPolicyRule *b, bool all) {
@@ -301,11 +301,11 @@ static int routing_policy_rule_compare_func_full(const RoutingPolicyRule *a, con
if (r != 0)
return r;
r = CMP(a->from_prefixlen, b->from_prefixlen);
r = CMP(a->from.prefixlen, b->from.prefixlen);
if (r != 0)
return r;
r = CMP(a->to_prefixlen, b->to_prefixlen);
r = CMP(a->to.prefixlen, b->to.prefixlen);
if (r != 0)
return r;
@@ -318,11 +318,11 @@ static int routing_policy_rule_compare_func_full(const RoutingPolicyRule *a, con
return r;
if (all) {
r = memcmp(&a->from, &b->from, FAMILY_ADDRESS_SIZE(a->family));
r = memcmp(&a->from.address, &b->from.address, FAMILY_ADDRESS_SIZE(a->family));
if (r != 0)
return r;
r = memcmp(&a->to, &b->to, FAMILY_ADDRESS_SIZE(a->family));
r = memcmp(&a->to.address, &b->to.address, FAMILY_ADDRESS_SIZE(a->family));
if (r != 0)
return r;
}
@@ -544,8 +544,8 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, const c
"%s %s routing policy rule (%s): priority: %"PRIu32", %s -> %s, iif: %s, oif: %s, table: %s",
str, strna(network_config_source_to_string(rule->source)), strna(state),
rule->priority,
IN_ADDR_PREFIX_TO_STRING(rule->family, &rule->from, rule->from_prefixlen),
IN_ADDR_PREFIX_TO_STRING(rule->family, &rule->to, rule->to_prefixlen),
IN_ADDR_PREFIX_TO_STRING(rule->family, &rule->from.address, rule->from.prefixlen),
IN_ADDR_PREFIX_TO_STRING(rule->family, &rule->to.address, rule->to.prefixlen),
strna(rule->iif), strna(rule->oif), strna(table));
}
@@ -555,22 +555,22 @@ static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule
assert(rule);
assert(m);
if (rule->from_prefixlen > 0) {
r = netlink_message_append_in_addr_union(m, FRA_SRC, rule->family, &rule->from);
if (rule->from.prefixlen > 0) {
r = netlink_message_append_in_addr_union(m, FRA_SRC, rule->family, &rule->from.address);
if (r < 0)
return r;
r = sd_rtnl_message_routing_policy_rule_set_src_prefixlen(m, rule->from_prefixlen);
r = sd_rtnl_message_routing_policy_rule_set_src_prefixlen(m, rule->from.prefixlen);
if (r < 0)
return r;
}
if (rule->to_prefixlen > 0) {
r = netlink_message_append_in_addr_union(m, FRA_DST, rule->family, &rule->to);
if (rule->to.prefixlen > 0) {
r = netlink_message_append_in_addr_union(m, FRA_DST, rule->family, &rule->to.address);
if (r < 0)
return r;
r = sd_rtnl_message_routing_policy_rule_set_dst_prefixlen(m, rule->to_prefixlen);
r = sd_rtnl_message_routing_policy_rule_set_dst_prefixlen(m, rule->to.prefixlen);
if (r < 0)
return r;
}
@@ -1100,24 +1100,24 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
return 0;
}
r = netlink_message_read_in_addr_union(message, FRA_SRC, tmp->family, &tmp->from);
r = netlink_message_read_in_addr_union(message, FRA_SRC, tmp->family, &tmp->from.address);
if (r < 0 && r != -ENODATA) {
log_warning_errno(r, "rtnl: could not get FRA_SRC attribute, ignoring: %m");
return 0;
} else if (r >= 0) {
r = sd_rtnl_message_routing_policy_rule_get_src_prefixlen(message, &tmp->from_prefixlen);
r = sd_rtnl_message_routing_policy_rule_get_src_prefixlen(message, &tmp->from.prefixlen);
if (r < 0) {
log_warning_errno(r, "rtnl: received rule message without valid source prefix length, ignoring: %m");
return 0;
}
}
r = netlink_message_read_in_addr_union(message, FRA_DST, tmp->family, &tmp->to);
r = netlink_message_read_in_addr_union(message, FRA_DST, tmp->family, &tmp->to.address);
if (r < 0 && r != -ENODATA) {
log_warning_errno(r, "rtnl: could not get FRA_DST attribute, ignoring: %m");
return 0;
} else if (r >= 0) {
r = sd_rtnl_message_routing_policy_rule_get_dst_prefixlen(message, &tmp->to_prefixlen);
r = sd_rtnl_message_routing_policy_rule_get_dst_prefixlen(message, &tmp->to.prefixlen);
if (r < 0) {
log_warning_errno(r, "rtnl: received rule message without valid destination prefix length, ignoring: %m");
return 0;
@@ -1469,46 +1469,6 @@ static int config_parse_routing_policy_rule_fwmark(
return 1;
}
static int config_parse_routing_policy_rule_prefix(
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) {
RoutingPolicyRule *rule = ASSERT_PTR(userdata);
union in_addr_union *buffer;
uint8_t *prefixlen;
int r;
assert(rvalue);
if (streq_ptr(lvalue, "To")) {
buffer = &rule->to;
prefixlen = &rule->to_prefixlen;
} else if (streq_ptr(lvalue, "From")) {
buffer = &rule->from;
prefixlen = &rule->from_prefixlen;
} else
assert_not_reached();
if (rule->family == AF_UNSPEC)
r = in_addr_prefix_from_string_auto(rvalue, &rule->family, buffer, prefixlen);
else
r = in_addr_prefix_from_string(rvalue, rule->family, buffer, prefixlen);
if (r < 0) {
log_syntax(unit, LOG_WARNING, filename, line, r, "RPDB rule prefix is invalid, ignoring assignment: %s", rvalue);
return 0;
}
return 1;
}
static int config_parse_routing_policy_rule_port_range(
const char *unit,
const char *filename,
@@ -1662,7 +1622,8 @@ int config_parse_routing_policy_rule(
[ROUTING_POLICY_RULE_L3MDEV] = { .parser = config_parse_bool, .ltype = 0, .offset = offsetof(RoutingPolicyRule, l3mdev), },
[ROUTING_POLICY_RULE_SPORT] = { .parser = config_parse_routing_policy_rule_port_range, .ltype = 0, .offset = offsetof(RoutingPolicyRule, sport), },
[ROUTING_POLICY_RULE_DPORT] = { .parser = config_parse_routing_policy_rule_port_range, .ltype = 0, .offset = offsetof(RoutingPolicyRule, dport), },
[ROUTING_POLICY_RULE_PREFIX] = { .parser = config_parse_routing_policy_rule_prefix, .ltype = 0, .offset = 0, },
[ROUTING_POLICY_RULE_FROM] = { .parser = config_parse_in_addr_prefix, .ltype = 0, .offset = offsetof(RoutingPolicyRule, from), },
[ROUTING_POLICY_RULE_TO] = { .parser = config_parse_in_addr_prefix, .ltype = 0, .offset = offsetof(RoutingPolicyRule, to), },
[ROUTING_POLICY_RULE_PRIORITY] = { .parser = config_parse_routing_policy_rule_priority, .ltype = 0, .offset = 0, },
[ROUTING_POLICY_RULE_SUPPRESS_IFGROUP] = { .parser = config_parse_routing_policy_rule_suppress, .ltype = INT32_MAX, .offset = offsetof(RoutingPolicyRule, suppress_ifgroup), },
[ROUTING_POLICY_RULE_SUPPRESS_PREFIXLEN] = { .parser = config_parse_routing_policy_rule_suppress, .ltype = 128, .offset = offsetof(RoutingPolicyRule, suppress_prefixlen), },
@@ -1707,6 +1668,12 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
if (section_is_invalid(rule->section))
return -EINVAL;
rule->family = rule->from.family;
if (rule->family == AF_UNSPEC)
rule->family = rule->to.family;
else if (rule->to.family != AF_UNSPEC && rule->to.family != rule->family)
return log_rule_section(rule, "From= and To= settings for routing policy rule contradict each other.");
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_rule_section(rule, "Address family specified by Family= conflicts with To= and/or From=.");

View File

@@ -6,7 +6,7 @@
#include <stdbool.h>
#include "conf-parser.h"
#include "in-addr-util.h"
#include "in-addr-prefix-util.h"
#include "networkd-util.h"
typedef struct Link Link;
@@ -23,17 +23,15 @@ typedef struct RoutingPolicyRule {
unsigned n_ref;
/* struct fib_rule_hdr */
AddressFamily address_family; /* Specified by Family= */
int family; /* Automatically determined by From= or To= */
uint8_t to_prefixlen;
uint8_t from_prefixlen;
AddressFamily address_family; /* Used when parsing Family= */
int family; /* Automatically determined by From=, To=, and Family= */
uint8_t tos;
uint8_t action;
uint32_t flags;
/* attributes */
union in_addr_union to; /* FRA_DST */
union in_addr_union from; /* FRA_SRC */
struct in_addr_prefix to; /* FRA_DST */
struct in_addr_prefix from; /* FRA_SRC */
char *iif; /* FRA_IIFNAME */
uint32_t priority_goto; /* FRA_GOTO */
bool priority_set;
@@ -88,7 +86,8 @@ typedef enum RoutingPolicyRuleConfParserType {
ROUTING_POLICY_RULE_L3MDEV,
ROUTING_POLICY_RULE_SPORT,
ROUTING_POLICY_RULE_DPORT,
ROUTING_POLICY_RULE_PREFIX,
ROUTING_POLICY_RULE_FROM,
ROUTING_POLICY_RULE_TO,
ROUTING_POLICY_RULE_PRIORITY,
ROUTING_POLICY_RULE_SUPPRESS_IFGROUP,
ROUTING_POLICY_RULE_SUPPRESS_PREFIXLEN,