mirror of
https://github.com/systemd/systemd.git
synced 2025-03-31 14:50:15 +03:00
network: allow to configure routing policy rule even if requesting interface is not activated yet (#36257)
Fixes a regression caused by 4f8b153d903fd4a6e8d7d3e49113582d70d1525a (v257). Fixes #36244.
This commit is contained in:
commit
382e8a03ca
@ -200,6 +200,17 @@ bool link_is_ready_to_configure(Link *link, bool allow_unmanaged) {
|
||||
return check_ready_for_all_sr_iov_ports(link, allow_unmanaged, link_is_ready_to_configure_one);
|
||||
}
|
||||
|
||||
bool link_is_ready_to_configure_by_name(Manager *manager, const char *name, bool allow_unmanaged) {
|
||||
assert(manager);
|
||||
assert(name);
|
||||
|
||||
Link *link;
|
||||
if (link_get_by_name(manager, name, &link) < 0)
|
||||
return false;
|
||||
|
||||
return link_is_ready_to_configure(link, allow_unmanaged);
|
||||
}
|
||||
|
||||
void link_ntp_settings_clear(Link *link) {
|
||||
link->ntp = strv_free(link->ntp);
|
||||
}
|
||||
|
@ -225,6 +225,7 @@ typedef struct Link {
|
||||
typedef int (*link_netlink_message_handler_t)(sd_netlink*, sd_netlink_message*, Link*);
|
||||
|
||||
bool link_is_ready_to_configure(Link *link, bool allow_unmanaged);
|
||||
bool link_is_ready_to_configure_by_name(Manager *manager, const char *name, bool allow_unmanaged);
|
||||
|
||||
void link_ntp_settings_clear(Link *link);
|
||||
void link_dns_settings_clear(Link *link);
|
||||
|
@ -872,6 +872,31 @@ int link_drop_routing_policy_rules(Link *link, bool only_static) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_is_ready_to_configure(const RoutingPolicyRule *rule, Link *link) {
|
||||
assert(rule);
|
||||
assert(link);
|
||||
assert(link->manager);
|
||||
|
||||
/* For routing policy rules, it is not necessary to check operstate and friends of the interface.
|
||||
* Hence, here we refuse to configure rules only when the interface is already removed, or in the
|
||||
* failed state. */
|
||||
if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED))
|
||||
return false;
|
||||
|
||||
/* Strictly speaking checking existence of IIF and OIF below is not necessary. But, configuring
|
||||
* routing policy rule with non-existent IIF or OIF is mostly meaningless, and 'ip rule' command
|
||||
* shows [detached] for such rules, that may confuse users. Let's postpone to configure if one of
|
||||
* IIF/OIF does not exist. */
|
||||
|
||||
if (rule->iif && !link_is_ready_to_configure_by_name(link->manager, rule->iif, /* allow_unmanaged = */ true))
|
||||
return false;
|
||||
|
||||
if (rule->oif && !link_is_ready_to_configure_by_name(link->manager, rule->oif, /* allow_unmanaged = */ true))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int routing_policy_rule_process_request(Request *req, Link *link, RoutingPolicyRule *rule) {
|
||||
RoutingPolicyRule *existing;
|
||||
int r;
|
||||
@ -881,7 +906,7 @@ static int routing_policy_rule_process_request(Request *req, Link *link, Routing
|
||||
assert(link->manager);
|
||||
assert(rule);
|
||||
|
||||
if (!link_is_ready_to_configure(link, false))
|
||||
if (!routing_policy_rule_is_ready_to_configure(rule, link))
|
||||
return 0;
|
||||
|
||||
r = routing_policy_rule_configure(rule, link, req);
|
||||
|
23
test/test-network/conf/25-routing-policy-rule-manual.network
Normal file
23
test/test-network/conf/25-routing-policy-rule-manual.network
Normal file
@ -0,0 +1,23 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test1
|
||||
Name=test2
|
||||
|
||||
[Link]
|
||||
ActivationPolicy=manual
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
|
||||
[RoutingPolicyRule]
|
||||
Family=both
|
||||
Priority=10
|
||||
SuppressPrefixLength=0
|
||||
Table=51819
|
||||
|
||||
[RoutingPolicyRule]
|
||||
Family=both
|
||||
FirewallMark=911
|
||||
InvertRule=true
|
||||
Priority=11
|
||||
Table=51820
|
@ -3999,6 +3999,45 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
print(output)
|
||||
self.assertIn('10113: from all iif test1 lookup 1011', output)
|
||||
|
||||
def test_routing_policy_rule_manual(self):
|
||||
# For issue #36244.
|
||||
copy_network_unit(
|
||||
'11-dummy.netdev',
|
||||
'25-routing-policy-rule-manual.network')
|
||||
start_networkd()
|
||||
self.wait_operstate('test1', operstate='off', setup_state='configuring', setup_timeout=20)
|
||||
|
||||
check_output('ip link add test2 type dummy')
|
||||
self.wait_operstate('test2', operstate='off', setup_state='configuring', setup_timeout=20)
|
||||
|
||||
networkctl('up', 'test2')
|
||||
self.wait_online('test2:degraded')
|
||||
|
||||
# The request for the routing policy rules are bound to test1. Hence, we need to wait for the rules
|
||||
# being configured explicitly.
|
||||
for _ in range(20):
|
||||
time.sleep(0.5)
|
||||
|
||||
output = check_output('ip -4 rule list table 51819')
|
||||
if output != '10: from all lookup 51819 suppress_prefixlength 0 proto static':
|
||||
continue
|
||||
|
||||
output = check_output('ip -6 rule list table 51819')
|
||||
if output != '10: from all lookup 51819 suppress_prefixlength 0 proto static':
|
||||
continue
|
||||
|
||||
output = check_output('ip -4 rule list table 51820')
|
||||
if output != '11: not from all fwmark 0x38f lookup 51820 proto static':
|
||||
continue
|
||||
|
||||
output = check_output('ip -6 rule list table 51820')
|
||||
if output != '11: not from all fwmark 0x38f lookup 51820 proto static':
|
||||
continue
|
||||
|
||||
break
|
||||
else:
|
||||
self.assertFalse(True)
|
||||
|
||||
@expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
|
||||
def test_routing_policy_rule_port_range(self):
|
||||
copy_network_unit('25-fibrule-port-range.network', '11-dummy.netdev')
|
||||
|
Loading…
x
Reference in New Issue
Block a user