mirror of
https://github.com/systemd/systemd.git
synced 2024-11-23 02:03:37 +08:00
network/ndisc: process zero lifetime options at first (#35212)
Fixes two issues reported at #33468.
This commit is contained in:
commit
987156769b
@ -750,7 +750,7 @@ static int ndisc_option_parse_route(Set **options, size_t offset, size_t len, co
|
||||
usec_t lifetime = unaligned_be32_sec_to_usec(opt + 4, /* max_as_infinity = */ true);
|
||||
|
||||
struct in6_addr prefix;
|
||||
memcpy(&prefix, opt + 8, len - 8);
|
||||
memcpy_safe(&prefix, opt + 8, len - 8);
|
||||
in6_addr_mask(&prefix, prefixlen);
|
||||
|
||||
return ndisc_option_add_route(options, offset, preference, prefixlen, &prefix, lifetime);
|
||||
|
@ -1610,7 +1610,7 @@ static int ndisc_router_process_onlink_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
uint8_t flags, prefixlen;
|
||||
struct in6_addr a;
|
||||
int r;
|
||||
@ -1619,6 +1619,14 @@ static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
assert(link->network);
|
||||
assert(rt);
|
||||
|
||||
usec_t lifetime_usec;
|
||||
r = sd_ndisc_router_prefix_get_valid_lifetime(rt, &lifetime_usec);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get prefix lifetime: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_prefix_get_address(rt, &a);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get prefix address: %m");
|
||||
@ -1664,7 +1672,7 @@ static int ndisc_router_process_prefix(Link *link, sd_ndisc_router *rt) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
_cleanup_(route_unrefp) Route *route = NULL;
|
||||
uint8_t preference, prefixlen;
|
||||
struct in6_addr gateway, dst;
|
||||
@ -1680,6 +1688,9 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get route lifetime from RA: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_route_get_address(rt, &dst);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get route destination address: %m");
|
||||
@ -1712,10 +1723,6 @@ static int ndisc_router_process_route(Link *link, sd_ndisc_router *rt) {
|
||||
}
|
||||
|
||||
r = sd_ndisc_router_route_get_preference(rt, &preference);
|
||||
if (r == -EOPNOTSUPP) {
|
||||
log_link_debug_errno(link, r, "Received route prefix with unsupported preference, ignoring: %m");
|
||||
return 0;
|
||||
}
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get router preference from RA: %m");
|
||||
|
||||
@ -1759,7 +1766,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
ndisc_rdnss_compare_func,
|
||||
free);
|
||||
|
||||
static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
usec_t lifetime_usec;
|
||||
const struct in6_addr *a;
|
||||
struct in6_addr router;
|
||||
@ -1781,6 +1788,9 @@ static int ndisc_router_process_rdnss(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get RDNSS lifetime: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
n = sd_ndisc_router_rdnss_get_addresses(rt, &a);
|
||||
if (n < 0)
|
||||
return log_link_warning_errno(link, n, "Failed to get RDNSS addresses: %m");
|
||||
@ -1851,7 +1861,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
ndisc_dnssl_compare_func,
|
||||
free);
|
||||
|
||||
static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
char **l;
|
||||
usec_t lifetime_usec;
|
||||
struct in6_addr router;
|
||||
@ -1873,6 +1883,9 @@ static int ndisc_router_process_dnssl(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get DNSSL lifetime: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_dnssl_get_domains(rt, &l);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get DNSSL addresses: %m");
|
||||
@ -1953,7 +1966,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
ndisc_captive_portal_compare_func,
|
||||
ndisc_captive_portal_free);
|
||||
|
||||
static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
_cleanup_(ndisc_captive_portal_freep) NDiscCaptivePortal *new_entry = NULL;
|
||||
_cleanup_free_ char *captive_portal = NULL;
|
||||
const char *uri;
|
||||
@ -1980,6 +1993,9 @@ static int ndisc_router_process_captive_portal(Link *link, sd_ndisc_router *rt)
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get lifetime of RA message: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_get_captive_portal(rt, &uri);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get captive portal from RA: %m");
|
||||
@ -2068,7 +2084,7 @@ DEFINE_PRIVATE_HASH_OPS_WITH_KEY_DESTRUCTOR(
|
||||
ndisc_pref64_compare_func,
|
||||
mfree);
|
||||
|
||||
static int ndisc_router_process_pref64(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_pref64(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
_cleanup_free_ NDiscPREF64 *new_entry = NULL;
|
||||
usec_t lifetime_usec;
|
||||
struct in6_addr a, router;
|
||||
@ -2099,6 +2115,9 @@ static int ndisc_router_process_pref64(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get pref64 prefix lifetime: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
if (lifetime_usec == 0) {
|
||||
free(set_remove(link->ndisc_pref64,
|
||||
&(NDiscPREF64) {
|
||||
@ -2217,7 +2236,7 @@ static int sd_dns_resolver_copy(const sd_dns_resolver *a, sd_dns_resolver *b) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_encrypted_dns(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_encrypted_dns(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
int r;
|
||||
|
||||
assert(link);
|
||||
@ -2240,6 +2259,9 @@ static int ndisc_router_process_encrypted_dns(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get lifetime of RA message: %m");
|
||||
|
||||
if ((lifetime_usec == 0) != zero_lifetime)
|
||||
return 0;
|
||||
|
||||
r = sd_ndisc_router_encrypted_dns_get_resolver(rt, &res);
|
||||
if (r < 0)
|
||||
return log_link_warning_errno(link, r, "Failed to get encrypted dns resolvers: %m");
|
||||
@ -2292,7 +2314,7 @@ static int ndisc_router_process_encrypted_dns(Link *link, sd_ndisc_router *rt) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt, bool zero_lifetime) {
|
||||
size_t n_captive_portal = 0;
|
||||
int r;
|
||||
|
||||
@ -2314,19 +2336,19 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
|
||||
switch (type) {
|
||||
case SD_NDISC_OPTION_PREFIX_INFORMATION:
|
||||
r = ndisc_router_process_prefix(link, rt);
|
||||
r = ndisc_router_process_prefix(link, rt, zero_lifetime);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_ROUTE_INFORMATION:
|
||||
r = ndisc_router_process_route(link, rt);
|
||||
r = ndisc_router_process_route(link, rt, zero_lifetime);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_RDNSS:
|
||||
r = ndisc_router_process_rdnss(link, rt);
|
||||
r = ndisc_router_process_rdnss(link, rt, zero_lifetime);
|
||||
break;
|
||||
|
||||
case SD_NDISC_OPTION_DNSSL:
|
||||
r = ndisc_router_process_dnssl(link, rt);
|
||||
r = ndisc_router_process_dnssl(link, rt, zero_lifetime);
|
||||
break;
|
||||
case SD_NDISC_OPTION_CAPTIVE_PORTAL:
|
||||
if (n_captive_portal > 0) {
|
||||
@ -2336,15 +2358,15 @@ static int ndisc_router_process_options(Link *link, sd_ndisc_router *rt) {
|
||||
n_captive_portal++;
|
||||
continue;
|
||||
}
|
||||
r = ndisc_router_process_captive_portal(link, rt);
|
||||
r = ndisc_router_process_captive_portal(link, rt, zero_lifetime);
|
||||
if (r > 0)
|
||||
n_captive_portal++;
|
||||
break;
|
||||
case SD_NDISC_OPTION_PREF64:
|
||||
r = ndisc_router_process_pref64(link, rt);
|
||||
r = ndisc_router_process_pref64(link, rt, zero_lifetime);
|
||||
break;
|
||||
case SD_NDISC_OPTION_ENCRYPTED_DNS:
|
||||
r = ndisc_router_process_encrypted_dns(link, rt);
|
||||
r = ndisc_router_process_encrypted_dns(link, rt, zero_lifetime);
|
||||
break;
|
||||
}
|
||||
if (r < 0 && r != -EBADMSG)
|
||||
@ -2652,10 +2674,6 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_router_process_default(link, rt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_router_process_reachable_time(link, rt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -2672,7 +2690,15 @@ static int ndisc_router_handler(Link *link, sd_ndisc_router *rt) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_router_process_options(link, rt);
|
||||
r = ndisc_router_process_options(link, rt, /* zero_lifetime = */ true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_router_process_default(link, rt);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = ndisc_router_process_options(link, rt, /* zero_lifetime = */ false);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
@ -1,18 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=router-low
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6SendRA=yes
|
||||
|
||||
[IPv6SendRA]
|
||||
# changed from low to high
|
||||
RouterPreference=high
|
||||
EmitDNS=no
|
||||
EmitDomains=no
|
||||
|
||||
[IPv6Prefix]
|
||||
Prefix=2002:da8:1:98::/64
|
||||
PreferredLifetimeSec=1000s
|
||||
ValidLifetimeSec=2100s
|
@ -1,18 +0,0 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=router-high
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6SendRA=yes
|
||||
|
||||
[IPv6SendRA]
|
||||
# changed from high to low
|
||||
RouterPreference=low
|
||||
EmitDNS=no
|
||||
EmitDomains=no
|
||||
|
||||
[IPv6Prefix]
|
||||
Prefix=2002:da8:1:99::/64
|
||||
PreferredLifetimeSec=1000s
|
||||
ValidLifetimeSec=2100s
|
@ -6391,6 +6391,27 @@ class NetworkdRATests(unittest.TestCase, Utilities):
|
||||
|
||||
self.check_ipv6_sysctl_attr('client', 'hop_limit', '43')
|
||||
|
||||
def check_router_preference(self, suffix, metric_1, preference_1, metric_2, preference_2):
|
||||
self.wait_online('client:routable')
|
||||
self.wait_address('client', f'2002:da8:1:99:1034:56ff:fe78:9a{suffix}/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_address('client', f'2002:da8:1:98:1034:56ff:fe78:9a{suffix}/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric {metric_1}', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric {metric_2}', ipv='-6', timeout_sec=10)
|
||||
|
||||
print('### ip -6 route show dev client default')
|
||||
output = check_output('ip -6 route show dev client default')
|
||||
print(output)
|
||||
self.assertRegex(output, rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric {metric_1} expires [0-9]*sec pref {preference_1}')
|
||||
self.assertRegex(output, rf'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric {metric_2} expires [0-9]*sec pref {preference_2}')
|
||||
|
||||
for i in [100, 200, 300, 512, 1024, 2048]:
|
||||
if i not in [metric_1, metric_2]:
|
||||
self.assertNotIn(f'{i}', output)
|
||||
|
||||
for i in ['low', 'medium', 'high']:
|
||||
if i not in [preference_1, preference_2]:
|
||||
self.assertNotIn(f'{i}', output)
|
||||
|
||||
def test_router_preference(self):
|
||||
copy_network_unit('25-veth-client.netdev',
|
||||
'25-veth-router-high.netdev',
|
||||
@ -6409,72 +6430,47 @@ class NetworkdRATests(unittest.TestCase, Utilities):
|
||||
|
||||
networkctl_reconfigure('client')
|
||||
self.wait_online('client:routable')
|
||||
self.check_router_preference('00', 512, 'high', 2048, 'low')
|
||||
|
||||
self.wait_address('client', '2002:da8:1:99:1034:56ff:fe78:9a00/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_address('client', '2002:da8:1:98:1034:56ff:fe78:9a00/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 512', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 2048', ipv='-6', timeout_sec=10)
|
||||
|
||||
print('### ip -6 route show dev client default')
|
||||
output = check_output('ip -6 route show dev client default')
|
||||
print(output)
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 512 expires [0-9]*sec pref high')
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 2048 expires [0-9]*sec pref low')
|
||||
|
||||
# change the map from preference to metric.
|
||||
with open(os.path.join(network_unit_dir, '25-veth-client.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[Link]\nMACAddress=12:34:56:78:9a:01\n[IPv6AcceptRA]\nRouteMetric=100:200:300\n')
|
||||
|
||||
networkctl_reload()
|
||||
self.wait_online('client:routable')
|
||||
|
||||
self.wait_address('client', '2002:da8:1:99:1034:56ff:fe78:9a01/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_address('client', '2002:da8:1:98:1034:56ff:fe78:9a01/64', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 100', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 300', ipv='-6', timeout_sec=10)
|
||||
|
||||
print('### ip -6 route show dev client default')
|
||||
output = check_output('ip -6 route show dev client default')
|
||||
print(output)
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 100 expires [0-9]*sec pref high')
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 300 expires [0-9]*sec pref low')
|
||||
self.assertNotIn('metric 512', output)
|
||||
self.assertNotIn('metric 2048', output)
|
||||
self.check_router_preference('01', 100, 'high', 300, 'low')
|
||||
|
||||
# swap the preference (for issue #28439)
|
||||
remove_network_unit('25-veth-router-high.network', '25-veth-router-low.network')
|
||||
copy_network_unit('25-veth-router-high2.network', '25-veth-router-low2.network')
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=low\n')
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=high\n')
|
||||
networkctl_reload()
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 300', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 100', ipv='-6', timeout_sec=10)
|
||||
|
||||
print('### ip -6 route show dev client default')
|
||||
output = check_output('ip -6 route show dev client default')
|
||||
print(output)
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 300 expires [0-9]*sec pref low')
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 100 expires [0-9]*sec pref high')
|
||||
self.assertNotRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 100')
|
||||
self.assertNotRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 300')
|
||||
self.assertNotIn('metric 512', output)
|
||||
self.assertNotIn('metric 2048', output)
|
||||
self.check_router_preference('01', 300, 'low', 100, 'high')
|
||||
|
||||
# Use the same preference, and check if the two routes are not coalesced. See issue #33470.
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-high2.network'), mode='a', encoding='utf-8') as f:
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=medium\n')
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-low2.network'), mode='a', encoding='utf-8') as f:
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=medium\n')
|
||||
networkctl_reload()
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 200', ipv='-6', timeout_sec=10)
|
||||
self.wait_route('client', r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 200', ipv='-6', timeout_sec=10)
|
||||
self.check_router_preference('01', 200, 'medium', 200, 'medium')
|
||||
|
||||
print('### ip -6 route show dev client default')
|
||||
output = check_output('ip -6 route show dev client default')
|
||||
print(output)
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a99 proto ra metric 200 expires [0-9]*sec pref medium')
|
||||
self.assertRegex(output, r'default nhid [0-9]* via fe80::1034:56ff:fe78:9a98 proto ra metric 200 expires [0-9]*sec pref medium')
|
||||
self.assertNotIn('pref high', output)
|
||||
self.assertNotIn('pref low', output)
|
||||
self.assertNotIn('metric 512', output)
|
||||
self.assertNotIn('metric 2048', output)
|
||||
# Use route options to configure default routes.
|
||||
# The preference specified in the RA header should be ignored. See issue #33468.
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=high\n[IPv6RoutePrefix]\nRoute=::/0\nLifetimeSec=1200\n')
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('\n[IPv6SendRA]\nRouterPreference=low\n[IPv6RoutePrefix]\nRoute=::/0\nLifetimeSec=1200\n')
|
||||
networkctl_reload()
|
||||
self.check_router_preference('01', 200, 'medium', 200, 'medium')
|
||||
|
||||
# Set zero lifetime to the route options.
|
||||
# The preference specified in the RA header should be used.
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-high.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('LifetimeSec=0\n')
|
||||
with open(os.path.join(network_unit_dir, '25-veth-router-low.network'), mode='a', encoding='utf-8') as f:
|
||||
f.write('LifetimeSec=0\n')
|
||||
networkctl_reload()
|
||||
self.check_router_preference('01', 100, 'high', 300, 'low')
|
||||
|
||||
def _test_ndisc_vs_static_route(self, manage_foreign_nexthops):
|
||||
if not manage_foreign_nexthops:
|
||||
|
Loading…
Reference in New Issue
Block a user