IPv6 RA: Support the Retrans Timer field (IPv6 Conformance Test: v6LC.2.1.5)
The RA's Retransmission Timer field was being ignored. This resolves the IPv6
Core Conformance test, v6LC.2.1.5 [1].
Retransmission Timer is a 32-bit unsigned integer. The time, in milliseconds,
between retransmitted Neighbor Solicitation messages. Used by the Address
Resolution and Neighbor Unreachability Detection (NUD) algorithm.
Support setting a default value for the neighbour retransmission timer value with:
[Network]
IPv6RetransmissionTimeSec=<int>
By default, upon receiving a Router Advertisement with the Retransmission Timer
field set to a non-zero value, it will update the kernel's retransmit timer value.
To disable this behaviour, configure the UseIPv6RetransmissionTime= under the
[IPv6AcceptRA] section.
[IPv6AcceptRA]
UseIPv6RetransmissionTime=<bool>
RFC4861: Neighbor Discovery in IPv6
* Section 4.2 RA Message Format.
* Section 6.3.4 Processing Received Router Advertisements
A Router Advertisement field (e.g., Cur Hop Limit, Reachable Time,
and Retrans Timer) may contain a value denoting that it is
unspecified. In such cases, the parameter should be ignored and the
host should continue using whatever value it is already using. In
particular, a host MUST NOT interpret the unspecified value as
meaning change back to the default value that was in use before the
first Router Advertisement was received.
The RetransTimer variable SHOULD be copied from the Retrans Timer
field, if the received value is non-zero.
References
[1] IPv6 Core Conformance Spec (PDF)
This commit is contained in:
committed by
Yu Watanabe
parent
afd08d7740
commit
d4c8de21a0
@@ -0,0 +1,4 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[NetDev]
|
||||
Name=test25
|
||||
Kind=dummy
|
||||
@@ -0,0 +1,6 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=0
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=3
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=4
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=infinity
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=-2
|
||||
@@ -0,0 +1,7 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
[Match]
|
||||
Name=test25
|
||||
|
||||
[Network]
|
||||
IPv6AcceptRA=no
|
||||
IPv6RetransmissionTimeSec=999999999999999999
|
||||
@@ -4,6 +4,16 @@
|
||||
|
||||
# These tests can be executed in the systemd mkosi image when booted in QEMU. After booting the QEMU VM,
|
||||
# simply run this file which can be found in the VM at /usr/lib/systemd/tests/testdata/test-network/systemd-networkd-tests.py.
|
||||
#
|
||||
# To run an individual test, specify it as a command line argument in the form
|
||||
# of <class>.<test_function>. E.g. the NetworkdMTUTests class has a test
|
||||
# function called test_ipv6_mtu(). To run just that test use:
|
||||
#
|
||||
# sudo ./systemd-networkd-tests.py NetworkdMTUTests.test_ipv6_mtu
|
||||
#
|
||||
# Similarly, other indivdual tests can be run, eg.:
|
||||
#
|
||||
# sudo ./systemd-networkd-tests.py NetworkdNetworkTests.test_ipv6_neigh_retrans_time
|
||||
|
||||
import argparse
|
||||
import datetime
|
||||
@@ -582,9 +592,16 @@ def read_ip_sysctl_attr(link, attribute, ipv):
|
||||
with open(os.path.join('/proc/sys/net', ipv, 'conf', link, attribute), encoding='utf-8') as f:
|
||||
return f.readline().strip()
|
||||
|
||||
def read_ip_neigh_sysctl_attr(link, attribute, ipv):
|
||||
with open(os.path.join('/proc/sys/net', ipv, 'neigh', link, attribute), encoding='utf-8') as f:
|
||||
return f.readline().strip()
|
||||
|
||||
def read_ipv6_sysctl_attr(link, attribute):
|
||||
return read_ip_sysctl_attr(link, attribute, 'ipv6')
|
||||
|
||||
def read_ipv6_neigh_sysctl_attr(link, attribute):
|
||||
return read_ip_neigh_sysctl_attr(link, attribute, 'ipv6')
|
||||
|
||||
def read_ipv4_sysctl_attr(link, attribute):
|
||||
return read_ip_sysctl_attr(link, attribute, 'ipv4')
|
||||
|
||||
@@ -915,6 +932,9 @@ class Utilities():
|
||||
def check_ipv6_sysctl_attr(self, link, attribute, expected):
|
||||
self.assertEqual(read_ipv6_sysctl_attr(link, attribute), expected)
|
||||
|
||||
def check_ipv6_neigh_sysctl_attr(self, link, attribute, expected):
|
||||
self.assertEqual(read_ipv6_neigh_sysctl_attr(link, attribute), expected)
|
||||
|
||||
def wait_links(self, *links, timeout=20, fail_assert=True):
|
||||
def links_exist(*links):
|
||||
for link in links:
|
||||
@@ -3505,6 +3525,56 @@ class NetworkdNetworkTests(unittest.TestCase, Utilities):
|
||||
for i in range(1, 5):
|
||||
self.assertRegex(output, f'2607:5300:203:5215:{i}::1 *proxy')
|
||||
|
||||
def test_ipv6_neigh_retrans_time(self):
|
||||
link='test25'
|
||||
copy_network_unit('25-dummy.netdev', '25-dummy.network')
|
||||
start_networkd()
|
||||
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
remove_network_unit('25-dummy.network')
|
||||
|
||||
# expect retrans_time_ms updated
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-3s.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '3000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-3s.network')
|
||||
|
||||
# expect retrans_time_ms unchanged
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-0s.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '3000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-0s.network')
|
||||
|
||||
# expect retrans_time_ms unchanged
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-toobig.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '3000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-toobig.network')
|
||||
|
||||
# expect retrans_time_ms unchanged
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-infinity.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '3000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-infinity.network')
|
||||
|
||||
# expect retrans_time_ms unchanged
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-invalid.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '3000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-invalid.network')
|
||||
|
||||
# expect retrans_time_ms updated
|
||||
copy_network_unit('25-ipv6-neigh-retrans-time-4s.network')
|
||||
networkctl_reload()
|
||||
self.wait_online([f'{link}:degraded'])
|
||||
self.check_ipv6_neigh_sysctl_attr(link, 'retrans_time_ms', '4000')
|
||||
remove_network_unit('25-ipv6-neigh-retrans-time-4s.network')
|
||||
|
||||
def test_neighbor(self):
|
||||
copy_network_unit('12-dummy.netdev', '25-neighbor-dummy.network', '25-neighbor-dummy.network.d/10-step1.conf',
|
||||
'25-gre-tunnel-remote-any.netdev', '25-neighbor-ip.network',
|
||||
|
||||
Reference in New Issue
Block a user