Compare commits

..

No commits in common. "7745379ea8c1d08ecde9ccd15af1a76cdac91cc5" and "2797d945d2c663120308b439957d8b4faf10707c" have entirely different histories.

5 changed files with 64 additions and 161 deletions

View File

@ -145,7 +145,7 @@ names for them in UIs.
## Links ## Links
[Boot Loader Specification](https://systemd.io/BOOT_LOADER_SPECIFICATION)<br> [Boot Loader Specification](https://systemd.io/BOOT_LOADER_INTERFACE)<br>
[Discoverable Partitions Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)<br> [Discoverable Partitions Specification](https://systemd.io/DISCOVERABLE_PARTITIONS)<br>
[systemd-boot(7)](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br> [systemd-boot(7)](https://www.freedesktop.org/software/systemd/man/systemd-boot.html)<br>
[bootctl(1)](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br> [bootctl(1)](https://www.freedesktop.org/software/systemd/man/bootctl.html)<br>

View File

@ -39,8 +39,10 @@ RoutingPolicyRule *routing_policy_rule_free(RoutingPolicyRule *rule) {
} }
if (rule->manager) { if (rule->manager) {
set_remove(rule->manager->rules, rule); if (set_get(rule->manager->rules, rule) == rule)
set_remove(rule->manager->rules_foreign, rule); set_remove(rule->manager->rules, rule);
if (set_get(rule->manager->rules_foreign, rule) == rule)
set_remove(rule->manager->rules_foreign, rule);
} }
network_config_section_free(rule->section); network_config_section_free(rule->section);
@ -112,7 +114,7 @@ static int routing_policy_rule_new_static(Network *network, const char *filename
return 0; return 0;
} }
static int routing_policy_rule_copy(RoutingPolicyRule *dest, const RoutingPolicyRule *src) { static int routing_policy_rule_copy(RoutingPolicyRule *dest, RoutingPolicyRule *src) {
_cleanup_free_ char *iif = NULL, *oif = NULL; _cleanup_free_ char *iif = NULL, *oif = NULL;
assert(dest); assert(dest);
@ -304,7 +306,8 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
routing_policy_rule_compare_func, routing_policy_rule_compare_func,
routing_policy_rule_free); routing_policy_rule_free);
static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, RoutingPolicyRule **ret) { static int routing_policy_rule_get(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret) {
RoutingPolicyRule *existing; RoutingPolicyRule *existing;
assert(m); assert(m);
@ -326,12 +329,12 @@ static int routing_policy_rule_get(Manager *m, const RoutingPolicyRule *rule, Ro
return -ENOENT; return -ENOENT;
} }
static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, int family, RoutingPolicyRule **ret) { static int routing_policy_rule_add_internal(Manager *m, Set **rules, RoutingPolicyRule *in, int family, RoutingPolicyRule **ret) {
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL; _cleanup_(routing_policy_rule_freep) RoutingPolicyRule *rule = NULL;
RoutingPolicyRule *existing;
int r; int r;
assert(m); assert(m);
assert(rules);
assert(in); assert(in);
assert(IN_SET(family, AF_INET, AF_INET6)); assert(IN_SET(family, AF_INET, AF_INET6));
assert(in->family == AF_UNSPEC || in->family == family); assert(in->family == AF_UNSPEC || in->family == family);
@ -340,56 +343,33 @@ static int routing_policy_rule_add(Manager *m, const RoutingPolicyRule *in, int
if (r < 0) if (r < 0)
return r; return r;
rule->manager = m;
r = routing_policy_rule_copy(rule, in); r = routing_policy_rule_copy(rule, in);
if (r < 0) if (r < 0)
return r; return r;
rule->family = family; rule->family = family;
r = routing_policy_rule_get(m, rule, &existing); r = set_ensure_put(rules, &routing_policy_rule_hash_ops, rule);
if (r == -ENOENT) { if (r < 0)
/* Rule does not exist, use a new one. */
r = set_ensure_put(&m->rules, &routing_policy_rule_hash_ops, rule);
if (r < 0)
return r;
assert(r > 0);
rule->manager = m;
existing = TAKE_PTR(rule);
} else if (r == 0) {
/* Take over a foreign rule. */
r = set_ensure_put(&m->rules, &routing_policy_rule_hash_ops, existing);
if (r < 0)
return r;
assert(r > 0);
set_remove(m->rules_foreign, existing);
} else if (r == 1) {
/* Already exists, do nothing. */
;
} else
return r; return r;
if (r == 0)
return -EEXIST;
if (ret) if (ret)
*ret = existing; *ret = rule;
TAKE_PTR(rule);
return 0; return 0;
} }
static int routing_policy_rule_consume_foreign(Manager *m, RoutingPolicyRule *rule) { static int routing_policy_rule_add(Manager *m, RoutingPolicyRule *rule, int family, RoutingPolicyRule **ret) {
int r; return routing_policy_rule_add_internal(m, &m->rules, rule, family, ret);
}
assert(m); static int routing_policy_rule_add_foreign(Manager *m, RoutingPolicyRule *rule, RoutingPolicyRule **ret) {
assert(rule); return routing_policy_rule_add_internal(m, &m->rules_foreign, rule, rule->family, ret);
assert(IN_SET(rule->family, AF_INET, AF_INET6));
r = set_ensure_consume(&m->rules_foreign, &routing_policy_rule_hash_ops, rule);
if (r <= 0)
return r;
rule->manager = m;
return 1;
} }
static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int family, const char *str, const Link *link) { static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int family, const char *str, const Link *link) {
@ -412,7 +392,7 @@ static void log_routing_policy_rule_debug(const RoutingPolicyRule *rule, int fam
} }
} }
static int routing_policy_rule_set_netlink_message(const RoutingPolicyRule *rule, sd_netlink_message *m, Link *link) { static int routing_policy_rule_set_netlink_message(RoutingPolicyRule *rule, sd_netlink_message *m, Link *link) {
int r; int r;
assert(rule); assert(rule);
@ -545,7 +525,7 @@ static int routing_policy_rule_remove_handler(sd_netlink *rtnl, sd_netlink_messa
return 1; return 1;
} }
static int routing_policy_rule_remove(const RoutingPolicyRule *rule, Manager *manager) { static int routing_policy_rule_remove(RoutingPolicyRule *rule, Manager *manager) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r; int r;
@ -603,7 +583,7 @@ static int routing_policy_rule_handler(sd_netlink *rtnl, sd_netlink_message *m,
return 1; return 1;
} }
static int routing_policy_rule_configure_internal(const RoutingPolicyRule *rule, int family, Link *link) { static int routing_policy_rule_configure_internal(RoutingPolicyRule *rule, int family, Link *link) {
_cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL; _cleanup_(sd_netlink_message_unrefp) sd_netlink_message *m = NULL;
int r; int r;
@ -639,7 +619,7 @@ static int routing_policy_rule_configure_internal(const RoutingPolicyRule *rule,
return 1; return 1;
} }
static int routing_policy_rule_configure(const RoutingPolicyRule *rule, Link *link) { static int routing_policy_rule_configure(RoutingPolicyRule *rule, Link *link) {
int r; int r;
if (IN_SET(rule->family, AF_INET, AF_INET6)) if (IN_SET(rule->family, AF_INET, AF_INET6))
@ -660,9 +640,8 @@ static int routing_policy_rule_configure(const RoutingPolicyRule *rule, Link *li
return 0; return 0;
} }
static int links_have_routing_policy_rule(const Manager *m, const RoutingPolicyRule *rule, const Link *except) { static bool links_have_routing_policy_rule(const Manager *m, const RoutingPolicyRule *rule, const Link *except) {
Link *link; Link *link;
int r;
assert(m); assert(m);
assert(rule); assert(rule);
@ -677,29 +656,8 @@ static int links_have_routing_policy_rule(const Manager *m, const RoutingPolicyR
continue; continue;
HASHMAP_FOREACH(link_rule, link->network->rules_by_section) HASHMAP_FOREACH(link_rule, link->network->rules_by_section)
if (IN_SET(link_rule->family, AF_INET, AF_INET6)) { if (routing_policy_rule_equal(link_rule, rule))
if (routing_policy_rule_equal(link_rule, rule)) return true;
return true;
} else {
/* The case Family=both. */
_cleanup_(routing_policy_rule_freep) RoutingPolicyRule *tmp = NULL;
r = routing_policy_rule_new(&tmp);
if (r < 0)
return r;
r = routing_policy_rule_copy(tmp, link_rule);
if (r < 0)
return r;
tmp->family = AF_INET;
if (routing_policy_rule_equal(tmp, rule))
return true;
tmp->family = AF_INET6;
if (routing_policy_rule_equal(tmp, rule))
return true;
}
} }
return false; return false;
@ -719,12 +677,8 @@ int manager_drop_routing_policy_rules_internal(Manager *m, bool foreign, const L
continue; continue;
/* The rule will be configured later, or already configured by a link. */ /* The rule will be configured later, or already configured by a link. */
k = links_have_routing_policy_rule(m, rule, except); if (links_have_routing_policy_rule(m, rule, except))
if (k != 0) {
if (k < 0 && r >= 0)
r = k;
continue; continue;
}
k = routing_policy_rule_remove(rule, m); k = routing_policy_rule_remove(rule, m);
if (k < 0 && r >= 0) if (k < 0 && r >= 0)
@ -749,6 +703,20 @@ int link_set_routing_policy_rules(Link *link) {
link->routing_policy_rules_configured = false; link->routing_policy_rules_configured = false;
HASHMAP_FOREACH(rule, link->network->rules_by_section) { HASHMAP_FOREACH(rule, link->network->rules_by_section) {
RoutingPolicyRule *existing;
r = routing_policy_rule_get(link->manager, rule, &existing);
if (r > 0)
continue;
if (r == 0) {
r = set_ensure_put(&link->manager->rules, &routing_policy_rule_hash_ops, existing);
if (r < 0)
return log_link_warning_errno(link, r, "Could not store existing routing policy rule: %m");
set_remove(link->manager->rules_foreign, existing);
continue;
}
r = routing_policy_rule_configure(rule, link); r = routing_policy_rule_configure(rule, link);
if (r < 0) if (r < 0)
return log_link_warning_errno(link, r, "Could not set routing policy rule: %m"); return log_link_warning_errno(link, r, "Could not set routing policy rule: %m");
@ -979,9 +947,11 @@ int manager_rtnl_process_rule(sd_netlink *rtnl, sd_netlink_message *message, Man
log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL); log_routing_policy_rule_debug(tmp, tmp->family, "Received remembered", NULL);
else { else {
log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL); log_routing_policy_rule_debug(tmp, tmp->family, "Remembering foreign", NULL);
r = routing_policy_rule_consume_foreign(m, TAKE_PTR(tmp)); r = routing_policy_rule_add_foreign(m, tmp, &rule);
if (r < 0) if (r < 0) {
log_warning_errno(r, "Could not remember foreign rule, ignoring: %m"); log_warning_errno(r, "Could not remember foreign rule, ignoring: %m");
return 0;
}
} }
break; break;
case RTM_DELRULE: case RTM_DELRULE:
@ -1579,13 +1549,8 @@ static int routing_policy_rule_section_verify(RoutingPolicyRule *rule) {
"specified by To= or From=. Ignoring [RoutingPolicyRule] section from line %u.", "specified by To= or From=. Ignoring [RoutingPolicyRule] section from line %u.",
rule->section->filename, rule->section->line); rule->section->filename, rule->section->line);
if (rule->family == AF_UNSPEC) { if (rule->family == AF_UNSPEC && rule->address_family == ADDRESS_FAMILY_NO)
if (IN_SET(rule->address_family, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_NO)) rule->family = AF_INET;
rule->family = AF_INET;
else if (rule->address_family == ADDRESS_FAMILY_IPV6)
rule->family = AF_INET6;
/* rule->family can be AF_UNSPEC only when Family=both. */
}
/* Currently, [RoutingPolicyRule] does not have a setting to set FRA_L3MDEV flag. Please also /* Currently, [RoutingPolicyRule] does not have a setting to set FRA_L3MDEV flag. Please also
* update routing_policy_rule_is_created_by_kernel() when a new setting which sets the flag is * update routing_policy_rule_is_created_by_kernel() when a new setting which sets the flag is

View File

@ -21,7 +21,7 @@ OutgoingInterface=test1
# iif # iif
[RoutingPolicyRule] [RoutingPolicyRule]
Table=1011 Table=1011
Family=both Family=ipv4
Priority=10113 Priority=10113
IncomingInterface=test1 IncomingInterface=test1

View File

@ -1,33 +0,0 @@
[Match]
Name=test1
[Network]
IPv6AcceptRA=no
# fwmark
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10111
FirewallMark=1011
# oif
[RoutingPolicyRule]
Table=1011
Family=both
Priority=10112
OutgoingInterface=test1
# iif
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10113
IncomingInterface=test1
# source
[RoutingPolicyRule]
Table=1011
Family=ipv4
Priority=10114
From=192.168.8.254

View File

@ -1800,8 +1800,7 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
'26-link-local-addressing-ipv6.network', '26-link-local-addressing-ipv6.network',
'routing-policy-rule-dummy98.network', 'routing-policy-rule-dummy98.network',
'routing-policy-rule-test1.network', 'routing-policy-rule-test1.network',
'routing-policy-rule-reconfigure1.network', 'routing-policy-rule-reconfigure.network',
'routing-policy-rule-reconfigure2.network',
] ]
routing_policy_rule_tables = ['7', '8', '9', '1011'] routing_policy_rule_tables = ['7', '8', '9', '1011']
@ -2085,65 +2084,37 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
stop_networkd(remove_state_files=False) stop_networkd(remove_state_files=False)
def test_routing_policy_rule_reconfigure(self): def test_routing_policy_rule_reconfigure(self):
copy_unit_to_networkd_unit_path('routing-policy-rule-reconfigure2.network', '11-dummy.netdev') copy_unit_to_networkd_unit_path('routing-policy-rule-reconfigure.network', '11-dummy.netdev')
start_networkd() start_networkd()
self.wait_online(['test1:degraded']) self.wait_online(['test1:degraded'])
output = check_output('ip rule list table 1011') output = check_output('ip rule list table 1011')
print(output) print(output)
self.assertIn('10111: from all fwmark 0x3f3 lookup 1011', output) self.assertRegex(output, '10111: from all fwmark 0x3f3 lookup 1011')
self.assertIn('10112: from all oif test1 lookup 1011', output) self.assertRegex(output, '10112: from all oif test1 lookup 1011')
self.assertIn('10113: from all iif test1 lookup 1011', output) self.assertRegex(output, '10113: from all iif test1 lookup 1011')
self.assertIn('10114: from 192.168.8.254 lookup 1011', output) self.assertRegex(output, '10114: from 192.168.8.254 lookup 1011')
output = check_output('ip -6 rule list table 1011')
print(output)
self.assertIn('10112: from all oif test1 lookup 1011', output)
copy_unit_to_networkd_unit_path('routing-policy-rule-reconfigure1.network', '11-dummy.netdev')
run(*networkctl_cmd, 'reload', env=env)
time.sleep(1)
self.wait_online(['test1:degraded'])
output = check_output('ip rule list table 1011')
print(output)
self.assertIn('10111: from all fwmark 0x3f3 lookup 1011', output)
self.assertIn('10112: from all oif test1 lookup 1011', output)
self.assertIn('10113: from all iif test1 lookup 1011', output)
self.assertIn('10114: from 192.168.8.254 lookup 1011', output)
output = check_output('ip -6 rule list table 1011')
print(output)
self.assertNotIn('10112: from all oif test1 lookup 1011', output)
self.assertIn('10113: from all iif test1 lookup 1011', output)
run('ip rule delete priority 10111') run('ip rule delete priority 10111')
run('ip rule delete priority 10112') run('ip rule delete priority 10112')
run('ip rule delete priority 10113') run('ip rule delete priority 10113')
run('ip rule delete priority 10114') run('ip rule delete priority 10114')
run('ip -6 rule delete priority 10113') run('ip rule delete priority 10115')
output = check_output('ip rule list table 1011') output = check_output('ip rule list table 1011')
print(output) print(output)
self.assertEqual(output, '') self.assertEqual(output, '')
output = check_output('ip -6 rule list table 1011')
print(output)
self.assertEqual(output, '')
run(*networkctl_cmd, 'reconfigure', 'test1', env=env) run(*networkctl_cmd, 'reconfigure', 'test1', env=env)
self.wait_online(['test1:degraded']) self.wait_online(['test1:degraded'])
output = check_output('ip rule list table 1011') output = check_output('ip rule list table 1011')
print(output) print(output)
self.assertIn('10111: from all fwmark 0x3f3 lookup 1011', output) self.assertRegex(output, '10111: from all fwmark 0x3f3 lookup 1011')
self.assertIn('10112: from all oif test1 lookup 1011', output) self.assertRegex(output, '10112: from all oif test1 lookup 1011')
self.assertIn('10113: from all iif test1 lookup 1011', output) self.assertRegex(output, '10113: from all iif test1 lookup 1011')
self.assertIn('10114: from 192.168.8.254 lookup 1011', output) self.assertRegex(output, '10114: from 192.168.8.254 lookup 1011')
output = check_output('ip -6 rule list table 1011')
print(output)
self.assertIn('10113: from all iif test1 lookup 1011', output)
@expectedFailureIfRoutingPolicyPortRangeIsNotAvailable() @expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
def test_routing_policy_rule_port_range(self): def test_routing_policy_rule_port_range(self):