mirror of
https://github.com/systemd/systemd-stable.git
synced 2024-12-22 13:33:56 +03:00
Merge pull request #13235 from yuwata/network-routing-policy-rule-family-13233
network: add RoutingPolicyRule.Family= setting
This commit is contained in:
commit
4eaa2486b8
@ -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>
|
||||
|
||||
|
@ -18,7 +18,7 @@ int config_parse_dhcp(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
AddressFamilyBoolean *dhcp = data, s;
|
||||
AddressFamily *dhcp = data, s;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
@ -26,10 +26,10 @@ int config_parse_dhcp(
|
||||
assert(data);
|
||||
|
||||
/* Note that this is mostly like
|
||||
* config_parse_address_family_boolean(), except that it
|
||||
* config_parse_address_family(), except that it
|
||||
* understands some old names for the enum values */
|
||||
|
||||
s = address_family_boolean_from_string(rvalue);
|
||||
s = address_family_from_string(rvalue);
|
||||
if (s < 0) {
|
||||
|
||||
/* Previously, we had a slightly different enum here,
|
||||
@ -51,7 +51,7 @@ int config_parse_dhcp(
|
||||
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"DHCP=%s is deprecated, please use DHCP=%s instead.",
|
||||
rvalue, address_family_boolean_to_string(s));
|
||||
rvalue, address_family_to_string(s));
|
||||
}
|
||||
|
||||
*dhcp = s;
|
||||
|
@ -251,7 +251,7 @@ int config_parse_ipv4ll(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
AddressFamilyBoolean *link_local = data;
|
||||
AddressFamily *link_local = data;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@ -260,7 +260,7 @@ int config_parse_ipv4ll(
|
||||
assert(data);
|
||||
|
||||
/* Note that this is mostly like
|
||||
* config_parse_address_family_boolean(), except that it
|
||||
* config_parse_address_family(), except that it
|
||||
* applies only to IPv4 */
|
||||
|
||||
r = parse_boolean(rvalue);
|
||||
@ -276,7 +276,7 @@ int config_parse_ipv4ll(
|
||||
|
||||
log_syntax(unit, LOG_WARNING, filename, line, 0,
|
||||
"%s=%s is deprecated, please use LinkLocalAddressing=%s instead.",
|
||||
lvalue, rvalue, address_family_boolean_to_string(*link_local));
|
||||
lvalue, rvalue, address_family_to_string(*link_local));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -150,7 +150,7 @@ static bool link_dhcp4_server_enabled(Link *link) {
|
||||
return link->network->dhcp_server;
|
||||
}
|
||||
|
||||
bool link_ipv4ll_enabled(Link *link, AddressFamilyBoolean mask) {
|
||||
bool link_ipv4ll_enabled(Link *link, AddressFamily mask) {
|
||||
assert(link);
|
||||
assert((mask & ~(ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_FALLBACK_IPV4)) == 0);
|
||||
|
||||
@ -242,7 +242,7 @@ static bool link_ipv4_forward_enabled(Link *link) {
|
||||
if (!link->network)
|
||||
return false;
|
||||
|
||||
if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
|
||||
if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
|
||||
return false;
|
||||
|
||||
return link->network->ip_forward & ADDRESS_FAMILY_IPV4;
|
||||
@ -260,7 +260,7 @@ static bool link_ipv6_forward_enabled(Link *link) {
|
||||
if (!link->network)
|
||||
return false;
|
||||
|
||||
if (link->network->ip_forward == _ADDRESS_FAMILY_BOOLEAN_INVALID)
|
||||
if (link->network->ip_forward == _ADDRESS_FAMILY_INVALID)
|
||||
return false;
|
||||
|
||||
if (link_sysctl_ipv6_enabled(link) == 0)
|
||||
|
@ -188,7 +188,7 @@ int link_ipv6ll_gained(Link *link, const struct in6_addr *address);
|
||||
|
||||
int link_set_mtu(Link *link, uint32_t mtu);
|
||||
|
||||
bool link_ipv4ll_enabled(Link *link, AddressFamilyBoolean mask);
|
||||
bool link_ipv4ll_enabled(Link *link, AddressFamily mask);
|
||||
|
||||
int link_stop_clients(Link *link, bool may_keep_dhcp);
|
||||
|
||||
|
@ -59,7 +59,7 @@ Network.Xfrm, config_parse_stacked_netdev,
|
||||
Network.VRF, config_parse_ifname, 0, offsetof(Network, vrf_name)
|
||||
Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp)
|
||||
Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server)
|
||||
Network.LinkLocalAddressing, config_parse_link_local_address_family_boolean, 0, offsetof(Network, link_local)
|
||||
Network.LinkLocalAddressing, config_parse_link_local_address_family, 0, offsetof(Network, link_local)
|
||||
Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route)
|
||||
Network.DefaultRouteOnDevice, config_parse_bool, 0, offsetof(Network, default_route_on_device)
|
||||
Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token)
|
||||
@ -76,7 +76,7 @@ Network.DNSOverTLS, config_parse_dns_over_tls_mode,
|
||||
Network.DNSSEC, config_parse_dnssec_mode, 0, offsetof(Network, dnssec_mode)
|
||||
Network.DNSSECNegativeTrustAnchors, config_parse_dnssec_negative_trust_anchors, 0, 0
|
||||
Network.NTP, config_parse_ntp, 0, offsetof(Network, ntp)
|
||||
Network.IPForward, config_parse_address_family_boolean_with_kernel, 0, offsetof(Network, ip_forward)
|
||||
Network.IPForward, config_parse_address_family_with_kernel, 0, offsetof(Network, ip_forward)
|
||||
Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade)
|
||||
Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions)
|
||||
Network.IPv6AcceptRA, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
|
||||
@ -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
|
||||
|
@ -281,7 +281,7 @@ int network_verify(Network *network) {
|
||||
prefix_free(prefix);
|
||||
|
||||
LIST_FOREACH_SAFE(rules, rule, rule_next, network->rules)
|
||||
if (section_is_invalid(rule->section))
|
||||
if (routing_policy_rule_section_verify(rule) < 0)
|
||||
routing_policy_rule_free(rule);
|
||||
|
||||
return 0;
|
||||
@ -395,7 +395,7 @@ int network_load_one(Manager *manager, const char *filename) {
|
||||
.dns_over_tls_mode = _DNS_OVER_TLS_MODE_INVALID,
|
||||
|
||||
/* If LinkLocalAddressing= is not set, then set to ADDRESS_FAMILY_IPV6 later. */
|
||||
.link_local = _ADDRESS_FAMILY_BOOLEAN_INVALID,
|
||||
.link_local = _ADDRESS_FAMILY_INVALID,
|
||||
|
||||
.ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_NO,
|
||||
.ipv6_accept_ra = -1,
|
||||
|
@ -77,7 +77,7 @@ struct Network {
|
||||
Hashmap *stacked_netdev_names;
|
||||
|
||||
/* DHCP Client Support */
|
||||
AddressFamilyBoolean dhcp;
|
||||
AddressFamily dhcp;
|
||||
DHCPClientIdentifier dhcp_client_identifier;
|
||||
char *dhcp_vendor_class_identifier;
|
||||
char **dhcp_user_class;
|
||||
@ -123,7 +123,7 @@ struct Network {
|
||||
uint32_t dhcp_server_pool_size;
|
||||
|
||||
/* IPV4LL Support */
|
||||
AddressFamilyBoolean link_local;
|
||||
AddressFamily link_local;
|
||||
bool ipv4ll_route;
|
||||
|
||||
bool default_route_on_device;
|
||||
@ -171,7 +171,7 @@ struct Network {
|
||||
usec_t can_restart_us;
|
||||
int can_triple_sampling;
|
||||
|
||||
AddressFamilyBoolean ip_forward;
|
||||
AddressFamily ip_forward;
|
||||
bool ip_masquerade;
|
||||
|
||||
int ipv6_accept_ra;
|
||||
|
@ -3,6 +3,7 @@
|
||||
#include <net/if.h>
|
||||
#include <linux/fib_rules.h>
|
||||
|
||||
#include "af-list.h"
|
||||
#include "alloc-util.h"
|
||||
#include "conf-parser.h"
|
||||
#include "fileio.h"
|
||||
@ -10,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"
|
||||
@ -23,7 +25,6 @@ int routing_policy_rule_new(RoutingPolicyRule **ret) {
|
||||
return -ENOMEM;
|
||||
|
||||
*rule = (RoutingPolicyRule) {
|
||||
.family = AF_INET,
|
||||
.table = RT_TABLE_MAIN,
|
||||
};
|
||||
|
||||
@ -58,6 +59,44 @@ void routing_policy_rule_free(RoutingPolicyRule *rule) {
|
||||
free(rule);
|
||||
}
|
||||
|
||||
static int routing_policy_rule_copy(RoutingPolicyRule *dest, RoutingPolicyRule *src) {
|
||||
_cleanup_free_ char *iif = NULL, *oif = NULL;
|
||||
|
||||
assert(dest);
|
||||
assert(src);
|
||||
|
||||
if (src->iif) {
|
||||
iif = strdup(src->iif);
|
||||
if (!iif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (src->oif) {
|
||||
oif = strdup(src->oif);
|
||||
if (!oif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
dest->family = src->family;
|
||||
dest->from = src->from;
|
||||
dest->from_prefixlen = src->from_prefixlen;
|
||||
dest->to = src->to;
|
||||
dest->to_prefixlen = src->to_prefixlen;
|
||||
dest->invert_rule = src->invert_rule;
|
||||
dest->tos = src->tos;
|
||||
dest->fwmark = src->fwmark;
|
||||
dest->fwmask = src->fwmask;
|
||||
dest->priority = src->priority;
|
||||
dest->table = src->table;
|
||||
dest->iif = TAKE_PTR(iif);
|
||||
dest->oif = TAKE_PTR(oif);
|
||||
dest->protocol = src->protocol;
|
||||
dest->sport = src->sport;
|
||||
dest->dport = src->dport;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void routing_policy_rule_hash_func(const RoutingPolicyRule *rule, struct siphash *state) {
|
||||
assert(rule);
|
||||
|
||||
@ -221,46 +260,21 @@ int routing_policy_rule_make_local(Manager *m, RoutingPolicyRule *rule) {
|
||||
|
||||
static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPolicyRule *in, RoutingPolicyRule **ret) {
|
||||
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
|
||||
_cleanup_free_ char *iif = NULL, *oif = NULL;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(rules);
|
||||
assert(in);
|
||||
|
||||
if (in->iif) {
|
||||
iif = strdup(in->iif);
|
||||
if (!iif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
if (in->oif) {
|
||||
oif = strdup(in->oif);
|
||||
if (!oif)
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
r = routing_policy_rule_new(&rule);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
rule->manager = m;
|
||||
rule->family = in->family;
|
||||
rule->from = in->from;
|
||||
rule->from_prefixlen = in->from_prefixlen;
|
||||
rule->to = in->to;
|
||||
rule->to_prefixlen = in->to_prefixlen;
|
||||
rule->invert_rule = in->invert_rule;
|
||||
rule->tos = in->tos;
|
||||
rule->fwmark = in->fwmark;
|
||||
rule->fwmask = in->fwmask;
|
||||
rule->priority = in->priority;
|
||||
rule->table = in->table;
|
||||
rule->iif = TAKE_PTR(iif);
|
||||
rule->oif = TAKE_PTR(oif);
|
||||
rule->protocol = in->protocol;
|
||||
rule->sport = in->sport;
|
||||
rule->dport = in->dport;
|
||||
|
||||
r = routing_policy_rule_copy(rule, in);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = set_ensure_allocated(rules, &routing_policy_rule_hash_ops);
|
||||
if (r < 0)
|
||||
@ -555,6 +569,50 @@ int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link, link_netl
|
||||
return 1;
|
||||
}
|
||||
|
||||
int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
|
||||
int r;
|
||||
|
||||
if (section_is_invalid(rule->section))
|
||||
return -EINVAL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
static int parse_fwmark_fwmask(const char *s, uint32_t *fwmark, uint32_t *fwmask) {
|
||||
_cleanup_free_ char *f = NULL;
|
||||
char *p;
|
||||
@ -767,7 +825,10 @@ int config_parse_routing_policy_rule_prefix(
|
||||
prefixlen = &n->from_prefixlen;
|
||||
}
|
||||
|
||||
r = in_addr_prefix_from_string_auto(rvalue, &n->family, buffer, prefixlen);
|
||||
if (n->family == AF_UNSPEC)
|
||||
r = in_addr_prefix_from_string_auto(rvalue, &n->family, buffer, prefixlen);
|
||||
else
|
||||
r = in_addr_prefix_from_string(rvalue, n->family, buffer, prefixlen);
|
||||
if (r < 0) {
|
||||
log_syntax(unit, LOG_ERR, filename, line, r, "RPDB rule prefix is invalid, ignoring assignment: %s", rvalue);
|
||||
return 0;
|
||||
@ -947,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;
|
||||
@ -977,6 +1078,7 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
|
||||
SET_FOREACH(rule, rules, i) {
|
||||
_cleanup_free_ char *from_str = NULL, *to_str = NULL;
|
||||
bool space = false;
|
||||
const char *family_str;
|
||||
|
||||
fputs("RULE=", f);
|
||||
|
||||
@ -1001,6 +1103,12 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
|
||||
space = true;
|
||||
}
|
||||
|
||||
family_str = af_to_name(rule->family);
|
||||
if (family_str)
|
||||
fprintf(f, "%sfamily=%s",
|
||||
space ? " " : "",
|
||||
family_str);
|
||||
|
||||
if (rule->tos != 0) {
|
||||
fprintf(f, "%stos=%hhu",
|
||||
space ? " " : "",
|
||||
@ -1008,6 +1116,10 @@ int routing_policy_serialize_rules(Set *rules, FILE *f) {
|
||||
space = true;
|
||||
}
|
||||
|
||||
fprintf(f, "%spriority=%"PRIu32,
|
||||
space ? " " : "",
|
||||
rule->priority);
|
||||
|
||||
if (rule->fwmark != 0) {
|
||||
fprintf(f, "%sfwmark=%"PRIu32"/%"PRIu32,
|
||||
space ? " " : "",
|
||||
@ -1123,6 +1235,13 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
continue;
|
||||
}
|
||||
|
||||
} else if (streq(a, "family")) {
|
||||
r = af_from_name(b);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse RPDB rule family, ignoring: %s", b);
|
||||
continue;
|
||||
}
|
||||
rule->family = r;
|
||||
} else if (streq(a, "tos")) {
|
||||
r = safe_atou8(b, &rule->tos);
|
||||
if (r < 0) {
|
||||
@ -1135,6 +1254,12 @@ int routing_policy_load_rules(const char *state_file, Set **rules) {
|
||||
log_error_errno(r, "Failed to parse RPDB rule table, ignoring: %s", b);
|
||||
continue;
|
||||
}
|
||||
} else if (streq(a, "priority")) {
|
||||
r = safe_atou32(b, &rule->priority);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to parse RPDB rule priority, ignoring: %s", b);
|
||||
continue;
|
||||
}
|
||||
} else if (streq(a, "fwmark")) {
|
||||
|
||||
r = parse_fwmark_fwmask(b, &rule->fwmark, &rule->fwmask);
|
||||
|
@ -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;
|
||||
|
||||
@ -56,6 +57,7 @@ int routing_policy_rule_new(RoutingPolicyRule **ret);
|
||||
void routing_policy_rule_free(RoutingPolicyRule *rule);
|
||||
|
||||
DEFINE_NETWORK_SECTION_FUNCTIONS(RoutingPolicyRule, routing_policy_rule_free);
|
||||
int routing_policy_rule_section_verify(RoutingPolicyRule *rule);
|
||||
|
||||
int routing_policy_rule_configure(RoutingPolicyRule *address, Link *link, link_netlink_message_handler_t callback);
|
||||
int routing_policy_rule_remove(RoutingPolicyRule *routing_policy_rule, Link *link, link_netlink_message_handler_t callback);
|
||||
@ -76,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);
|
||||
|
@ -8,14 +8,14 @@
|
||||
#include "string-util.h"
|
||||
#include "util.h"
|
||||
|
||||
static const char * const address_family_boolean_table[_ADDRESS_FAMILY_BOOLEAN_MAX] = {
|
||||
static const char * const address_family_table[_ADDRESS_FAMILY_MAX] = {
|
||||
[ADDRESS_FAMILY_NO] = "no",
|
||||
[ADDRESS_FAMILY_YES] = "yes",
|
||||
[ADDRESS_FAMILY_IPV4] = "ipv4",
|
||||
[ADDRESS_FAMILY_IPV6] = "ipv6",
|
||||
};
|
||||
|
||||
static const char * const link_local_address_family_boolean_table[_ADDRESS_FAMILY_BOOLEAN_MAX] = {
|
||||
static const char * const link_local_address_family_table[_ADDRESS_FAMILY_MAX] = {
|
||||
[ADDRESS_FAMILY_NO] = "no",
|
||||
[ADDRESS_FAMILY_YES] = "yes",
|
||||
[ADDRESS_FAMILY_IPV4] = "ipv4",
|
||||
@ -24,12 +24,19 @@ static const char * const link_local_address_family_boolean_table[_ADDRESS_FAMIL
|
||||
[ADDRESS_FAMILY_FALLBACK_IPV4] = "ipv4-fallback",
|
||||
};
|
||||
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(address_family_boolean, AddressFamilyBoolean, ADDRESS_FAMILY_YES);
|
||||
DEFINE_STRING_TABLE_LOOKUP_WITH_BOOLEAN(link_local_address_family_boolean, AddressFamilyBoolean, ADDRESS_FAMILY_YES);
|
||||
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family_boolean, link_local_address_family_boolean,
|
||||
AddressFamilyBoolean, "Failed to parse option");
|
||||
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",
|
||||
};
|
||||
|
||||
int config_parse_address_family_boolean_with_kernel(
|
||||
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");
|
||||
|
||||
int config_parse_address_family_with_kernel(
|
||||
const char* unit,
|
||||
const char *filename,
|
||||
unsigned line,
|
||||
@ -41,7 +48,7 @@ int config_parse_address_family_boolean_with_kernel(
|
||||
void *data,
|
||||
void *userdata) {
|
||||
|
||||
AddressFamilyBoolean *fwd = data, s;
|
||||
AddressFamily *fwd = data, s;
|
||||
|
||||
assert(filename);
|
||||
assert(lvalue);
|
||||
@ -56,7 +63,7 @@ int config_parse_address_family_boolean_with_kernel(
|
||||
* is gone, hence silently accept the old setting, but turn it
|
||||
* to "no". */
|
||||
|
||||
s = address_family_boolean_from_string(rvalue);
|
||||
s = address_family_from_string(rvalue);
|
||||
if (s < 0) {
|
||||
if (streq(rvalue, "kernel"))
|
||||
s = ADDRESS_FAMILY_NO;
|
||||
|
@ -5,7 +5,7 @@
|
||||
#include "hash-funcs.h"
|
||||
#include "macro.h"
|
||||
|
||||
typedef enum AddressFamilyBoolean {
|
||||
typedef enum AddressFamily {
|
||||
/* This is a bitmask, though it usually doesn't feel that way! */
|
||||
ADDRESS_FAMILY_NO = 0,
|
||||
ADDRESS_FAMILY_IPV4 = 1 << 0,
|
||||
@ -13,9 +13,9 @@ typedef enum AddressFamilyBoolean {
|
||||
ADDRESS_FAMILY_YES = ADDRESS_FAMILY_IPV4 | ADDRESS_FAMILY_IPV6,
|
||||
ADDRESS_FAMILY_FALLBACK_IPV4 = 1 << 2,
|
||||
ADDRESS_FAMILY_FALLBACK = ADDRESS_FAMILY_FALLBACK_IPV4 | ADDRESS_FAMILY_IPV6,
|
||||
_ADDRESS_FAMILY_BOOLEAN_MAX,
|
||||
_ADDRESS_FAMILY_BOOLEAN_INVALID = -1,
|
||||
} AddressFamilyBoolean;
|
||||
_ADDRESS_FAMILY_MAX,
|
||||
_ADDRESS_FAMILY_INVALID = -1,
|
||||
} AddressFamily;
|
||||
|
||||
typedef struct NetworkConfigSection {
|
||||
unsigned line;
|
||||
@ -23,14 +23,17 @@ typedef struct NetworkConfigSection {
|
||||
char filename[];
|
||||
} NetworkConfigSection;
|
||||
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family_boolean);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_family_boolean_with_kernel);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family);
|
||||
CONFIG_PARSER_PROTOTYPE(config_parse_address_family_with_kernel);
|
||||
|
||||
const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
|
||||
AddressFamilyBoolean address_family_boolean_from_string(const char *s) _pure_;
|
||||
const char *address_family_to_string(AddressFamily b) _const_;
|
||||
AddressFamily address_family_from_string(const char *s) _pure_;
|
||||
|
||||
const char *link_local_address_family_boolean_to_string(AddressFamilyBoolean b) _const_;
|
||||
AddressFamilyBoolean link_local_address_family_boolean_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);
|
||||
|
||||
|
@ -41,7 +41,7 @@ int main(int argc, char **argv) {
|
||||
|
||||
test_table_sparse(ipvlan_mode, NETDEV_IPVLAN_MODE);
|
||||
test_table_sparse(macvlan_mode, NETDEV_MACVLAN_MODE);
|
||||
test_table_sparse(address_family_boolean, ADDRESS_FAMILY_BOOLEAN);
|
||||
test_table_sparse(address_family, ADDRESS_FAMILY);
|
||||
|
||||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -62,31 +62,31 @@ int main(int argc, char **argv) {
|
||||
test_setup_logging(LOG_DEBUG);
|
||||
|
||||
test_rule_serialization("basic parsing",
|
||||
"RULE=from=1.2.3.4/32 to=2.3.4.5/32 tos=5 fwmark=1/2 table=10", NULL);
|
||||
"RULE=from=1.2.3.4/32 to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/2 table=10", NULL);
|
||||
|
||||
test_rule_serialization("ignored values",
|
||||
"RULE=something=to=ignore from=1.2.3.4/32 from=1.2.3.4/32"
|
||||
" \t to=2.3.4.5/24 to=2.3.4.5/32 tos=5 fwmark=2 fwmark=1 table=10 table=20",
|
||||
"RULE=from=1.2.3.4/32"
|
||||
" to=2.3.4.5/32 tos=5 fwmark=1/0 table=20");
|
||||
" to=2.3.4.5/32 family=AF_INET tos=5 priority=0 fwmark=1/0 table=20");
|
||||
|
||||
test_rule_serialization("ipv6",
|
||||
"RULE=from=1::2/64 to=2::3/64 table=6", NULL);
|
||||
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=6", NULL);
|
||||
|
||||
assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 table=%d", RT_TABLE_MAIN) >= 0);
|
||||
assert_se(asprintf(&p, "RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 table=%d", RT_TABLE_MAIN) >= 0);
|
||||
test_rule_serialization("default table",
|
||||
"RULE=from=1::2/64 to=2::3/64", p);
|
||||
|
||||
test_rule_serialization("incoming interface",
|
||||
"RULE=from=1::2/64 to=2::3/64 table=1 iif=lo",
|
||||
"RULE=from=1::2/64 to=2::3/64 iif=lo table=1");
|
||||
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=lo table=1");
|
||||
|
||||
test_rule_serialization("outgoing interface",
|
||||
"RULE=from=1::2/64 to=2::3/64 oif=eth0 table=1", NULL);
|
||||
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 oif=eth0 table=1", NULL);
|
||||
|
||||
test_rule_serialization("freeing interface names",
|
||||
"RULE=from=1::2/64 to=2::3/64 iif=e0 iif=e1 oif=e0 oif=e1 table=1",
|
||||
"RULE=from=1::2/64 to=2::3/64 iif=e1 oif=e1 table=1");
|
||||
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 iif=e0 iif=e1 oif=e0 oif=e1 table=1",
|
||||
"RULE=from=1::2/64 to=2::3/64 family=AF_INET6 priority=0 iif=e1 oif=e1 table=1");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -208,6 +208,7 @@ SourcePort=
|
||||
DestinationPort=
|
||||
IPProtocol=
|
||||
InvertRule=
|
||||
Family=
|
||||
[IPv6PrefixDelegation]
|
||||
RouterPreference=
|
||||
DNSLifetimeSec=
|
||||
|
@ -8,3 +8,15 @@ From= 192.168.100.18
|
||||
Priority=111
|
||||
IncomingInterface=test1
|
||||
OutgoingInterface=test1
|
||||
|
||||
[RoutingPolicyRule]
|
||||
IncomingInterface=test1
|
||||
Table=8
|
||||
Priority=100
|
||||
Family=ipv6
|
||||
|
||||
[RoutingPolicyRule]
|
||||
IncomingInterface=test1
|
||||
Table=9
|
||||
Priority=101
|
||||
Family=both
|
||||
|
@ -1439,7 +1439,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
'routing-policy-rule-dummy98.network',
|
||||
'routing-policy-rule-test1.network']
|
||||
|
||||
routing_policy_rule_tables = ['7', '8']
|
||||
routing_policy_rule_tables = ['7', '8', '9']
|
||||
routes = [['blackhole', '202.54.1.2'], ['unreachable', '202.54.1.3'], ['prohibit', '202.54.1.4']]
|
||||
|
||||
def setUp(self):
|
||||
@ -1523,15 +1523,36 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
start_networkd()
|
||||
self.wait_online(['test1:degraded'])
|
||||
|
||||
output = check_output('ip rule')
|
||||
output = check_output('ip rule list iif test1 priority 111')
|
||||
print(output)
|
||||
self.assertRegex(output, '111')
|
||||
self.assertRegex(output, '111:')
|
||||
self.assertRegex(output, 'from 192.168.100.18')
|
||||
self.assertRegex(output, r'tos (?:0x08|throughput)\s')
|
||||
self.assertRegex(output, 'iif test1')
|
||||
self.assertRegex(output, 'oif test1')
|
||||
self.assertRegex(output, 'lookup 7')
|
||||
|
||||
output = check_output('ip rule list iif test1 priority 101')
|
||||
print(output)
|
||||
self.assertRegex(output, '101:')
|
||||
self.assertRegex(output, 'from all')
|
||||
self.assertRegex(output, 'iif test1')
|
||||
self.assertRegex(output, 'lookup 9')
|
||||
|
||||
output = check_output('ip -6 rule list iif test1 priority 100')
|
||||
print(output)
|
||||
self.assertRegex(output, '100:')
|
||||
self.assertRegex(output, 'from all')
|
||||
self.assertRegex(output, 'iif test1')
|
||||
self.assertRegex(output, 'lookup 8')
|
||||
|
||||
output = check_output('ip -6 rule list iif test1 priority 101')
|
||||
print(output)
|
||||
self.assertRegex(output, '101:')
|
||||
self.assertRegex(output, 'from all')
|
||||
self.assertRegex(output, 'iif test1')
|
||||
self.assertRegex(output, 'lookup 9')
|
||||
|
||||
def test_routing_policy_rule_issue_11280(self):
|
||||
copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev',
|
||||
'routing-policy-rule-dummy98.network', '12-dummy.netdev')
|
||||
|
Loading…
Reference in New Issue
Block a user