From 059d7b6eae827e73c73633bcc40fe74f3696f3f6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 07:52:30 +0900 Subject: [PATCH 01/10] sd-radv: send RA when prefix is updated --- src/libsystemd-network/sd-radv.c | 50 ++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 22 deletions(-) diff --git a/src/libsystemd-network/sd-radv.c b/src/libsystemd-network/sd-radv.c index f8ffb6358f..a305171902 100644 --- a/src/libsystemd-network/sd-radv.c +++ b/src/libsystemd-network/sd-radv.c @@ -617,7 +617,8 @@ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { strna(addr_p), FORMAT_TIMESPAN(p->lifetime_preferred_usec, USEC_PER_SEC), FORMAT_TIMESPAN(p->lifetime_valid_usec, USEC_PER_SEC)); - return 0; + + goto announce; } _cleanup_free_ char *addr_cur = NULL; @@ -631,19 +632,21 @@ int sd_radv_add_prefix(sd_radv *ra, sd_radv_prefix *p) { LIST_APPEND(prefix, ra->prefixes, p); ra->n_prefixes++; - if (ra->state == RADV_STATE_IDLE) { - log_radv(ra, "Added prefix %s", strna(addr_p)); + log_radv(ra, "Added prefix %s", strna(addr_p)); + + if (ra->state == RADV_STATE_IDLE) + return 0; + +announce: + if (ra->ra_sent == 0) return 0; - } /* If RAs have already been sent, send an RA immediately to announce the newly-added prefix */ - if (ra->ra_sent > 0) { - r = radv_send(ra, NULL, ra->lifetime_usec); - if (r < 0) - log_radv_errno(ra, r, "Unable to send Router Advertisement for added prefix: %m"); - else - log_radv(ra, "Sent Router Advertisement for added prefix"); - } + r = radv_send(ra, NULL, ra->lifetime_usec); + if (r < 0) + log_radv_errno(ra, r, "Unable to send Router Advertisement for added prefix: %m"); + else + log_radv(ra, "Sent Router Advertisement for added/updated prefix"); return 0; } @@ -709,7 +712,8 @@ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p) { log_radv(ra, "Updated/replaced IPv6 route prefix %s (lifetime: %s)", strna(addr_p), FORMAT_TIMESPAN(p->lifetime_usec, USEC_PER_SEC)); - return 0; + + goto announce; } _cleanup_free_ char *addr_cur = NULL; @@ -723,19 +727,21 @@ int sd_radv_add_route_prefix(sd_radv *ra, sd_radv_route_prefix *p) { LIST_APPEND(prefix, ra->route_prefixes, p); ra->n_route_prefixes++; - if (ra->state == RADV_STATE_IDLE) { - log_radv(ra, "Added route prefix %s", strna(addr_p)); + log_radv(ra, "Added route prefix %s", strna(addr_p)); + + if (ra->state == RADV_STATE_IDLE) + return 0; + +announce: + if (ra->ra_sent == 0) return 0; - } /* If RAs have already been sent, send an RA immediately to announce the newly-added route prefix */ - if (ra->ra_sent > 0) { - r = radv_send(ra, NULL, ra->lifetime_usec); - if (r < 0) - log_radv_errno(ra, r, "Unable to send Router Advertisement for added route prefix: %m"); - else - log_radv(ra, "Sent Router Advertisement for added route prefix"); - } + r = radv_send(ra, NULL, ra->lifetime_usec); + if (r < 0) + log_radv_errno(ra, r, "Unable to send Router Advertisement for added route prefix: %m"); + else + log_radv(ra, "Sent Router Advertisement for added route prefix"); return 0; } From 277521a1ac6b4246f9f35c5a288dfdc190a99386 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:46:23 +0900 Subject: [PATCH 02/10] network: dhcp-pd: fix condition in dhcp_pd_prefix_lost() --- src/network/networkd-dhcp-prefix-delegation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/network/networkd-dhcp-prefix-delegation.c b/src/network/networkd-dhcp-prefix-delegation.c index 5f2555fe6e..949c74bd58 100644 --- a/src/network/networkd-dhcp-prefix-delegation.c +++ b/src/network/networkd-dhcp-prefix-delegation.c @@ -667,7 +667,7 @@ void dhcp_pd_prefix_lost(Link *uplink) { } SET_FOREACH(route, uplink->manager->routes) { - if (IN_SET(route->source, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6)) + if (!IN_SET(route->source, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6)) continue; if (route->family != AF_INET6) continue; From d0f17cfda6e6df7748de1e49721ab4c0a064bf27 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:46:55 +0900 Subject: [PATCH 03/10] network: route: do not drop unreachable route on reconfiguring downstream interface Previously, when a downstream is reconfigured, the unreachable route was removed as there is no corresponding static config in .network files. --- src/network/networkd-route.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index 156476066a..d7fb9094fa 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -792,6 +792,10 @@ static void manager_mark_routes(Manager *manager, bool foreign, const Link *exce if (foreign && route->source != NETWORK_CONFIG_SOURCE_FOREIGN) continue; + /* Do not touch dynamic routes. They will removed by dhcp_pd_prefix_lost() */ + if (IN_SET(route->source, NETWORK_CONFIG_SOURCE_DHCP4, NETWORK_CONFIG_SOURCE_DHCP6)) + continue; + /* Ignore routes not assigned yet or already removed. */ if (!route_exists(route)) continue; From 42e7ce69e46aa50cf3615af0a5a1346ce0c51327 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:50:08 +0900 Subject: [PATCH 04/10] network: route: update expiration timer in link_request_route() --- src/network/networkd-route.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/network/networkd-route.c b/src/network/networkd-route.c index d7fb9094fa..ee7a535075 100644 --- a/src/network/networkd-route.c +++ b/src/network/networkd-route.c @@ -1346,6 +1346,16 @@ int link_request_route( existing->lifetime_usec = route->lifetime_usec; if (consume_object) route_free(route); + + if (existing->expire) { + /* When re-configuring an existing route, kernel does not send RTM_NEWROUTE + * message, so we need to update the timer here. */ + r = route_setup_timer(existing, NULL); + if (r < 0) + log_link_warning_errno(link, r, "Failed to update expiration timer for route, ignoring: %m"); + if (r > 0) + log_route_debug(existing, "Updated expiration timer for", link, link->manager); + } } log_route_debug(existing, "Requesting", link, link->manager); From fe87807eaa3a6af26c30e79a26140530eff4efcd Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 10:06:59 +0900 Subject: [PATCH 05/10] network: dhcp-pd: do not stack 6rd sit tunnel --- src/network/netdev/tunnel.c | 4 ---- test/test-network/systemd-networkd-tests.py | 1 - 2 files changed, 5 deletions(-) diff --git a/src/network/netdev/tunnel.c b/src/network/netdev/tunnel.c index 59da4d4376..97e534fe99 100644 --- a/src/network/netdev/tunnel.c +++ b/src/network/netdev/tunnel.c @@ -124,10 +124,6 @@ int dhcp4_pd_create_6rd_tunnel(Link *link, link_netlink_message_handler_t callba if (r < 0) return log_link_debug_errno(link, r, "Could not append IFLA_INFO_DATA attribute: %m"); - r = sd_netlink_message_append_u32(m, IFLA_IPTUN_LINK, link->ifindex); - if (r < 0) - return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_LINK attribute: %m"); - r = sd_netlink_message_append_in_addr(m, IFLA_IPTUN_LOCAL, &ipv4address); if (r < 0) return log_link_debug_errno(link, r, "Could not append IFLA_IPTUN_LOCAL attribute: %m"); diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index a55ac4de7e..151270b8a2 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5444,7 +5444,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print(output) self.assertIn('link/sit 10.100.100.', output) self.assertIn('local 10.100.100.', output) - self.assertIn('dev veth99', output) self.assertIn('ttl 64', output) self.assertIn('6rd-prefix 2001:db8::/32', output) self.assertIn('6rd-relay_prefix 10.0.0.0/8', output) From 897f720602e501309a4dc2f1eb48a1909140ea81 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:53:27 +0900 Subject: [PATCH 06/10] sd-dhcp-client: add log message when a message is received --- src/libsystemd-network/sd-dhcp-client.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/libsystemd-network/sd-dhcp-client.c b/src/libsystemd-network/sd-dhcp-client.c index 16574d28c7..c33be947b7 100644 --- a/src/libsystemd-network/sd-dhcp-client.c +++ b/src/libsystemd-network/sd-dhcp-client.c @@ -1994,6 +1994,7 @@ static int client_receive_message_udp( return 0; } + log_dhcp_client(client, "Received message from UDP socket, processing."); (void) client_handle_message(client, message, len); return 0; } @@ -2060,6 +2061,7 @@ static int client_receive_message_raw( len -= DHCP_IP_UDP_SIZE; + log_dhcp_client(client, "Received message from RAW socket, processing."); (void) client_handle_message(client, &packet->dhcp, len); return 0; } From f56af3b4c837362d1c36a02cc1a0f82f76901b43 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 07:55:07 +0900 Subject: [PATCH 07/10] test-network: use --bind-interfaces option for dnsmasq Also make the interface name and router address configurable. --- test/test-network/systemd-networkd-tests.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 151270b8a2..0f4f7a3bd6 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -502,8 +502,8 @@ def remove_networkd_conf_dropin(dropins): if (os.path.exists(os.path.join(networkd_conf_dropin_path, dropin))): os.remove(os.path.join(networkd_conf_dropin_path, dropin)) -def start_dnsmasq(additional_options='', ipv4_range='192.168.5.10,192.168.5.200', ipv6_range='2600::10,2600::20', lease_time='1h'): - dnsmasq_command = f'dnsmasq -8 {dnsmasq_log_file} --log-queries=extra --log-dhcp --pid-file={dnsmasq_pid_file} --conf-file=/dev/null --interface=veth-peer --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile={dnsmasq_lease_file} --dhcp-option=26,1492 --dhcp-option=option:router,192.168.5.1 --port=0 ' + additional_options +def start_dnsmasq(additional_options='', interface='veth-peer', ipv4_range='192.168.5.10,192.168.5.200', ipv4_router='192.168.5.1', ipv6_range='2600::10,2600::20', lease_time='1h'): + dnsmasq_command = f'dnsmasq -8 {dnsmasq_log_file} --log-queries=extra --log-dhcp --pid-file={dnsmasq_pid_file} --conf-file=/dev/null --bind-interfaces --interface={interface} --enable-ra --dhcp-range={ipv6_range},{lease_time} --dhcp-range={ipv4_range},{lease_time} -R --dhcp-leasefile={dnsmasq_lease_file} --dhcp-option=26,1492 --dhcp-option=option:router,{ipv4_router} --port=0 ' + additional_options check_output(dnsmasq_command) def stop_by_pid_file(pid_file): From 4862fb693dda5e15254ed8180374cb3d8bca1fed Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 07:56:42 +0900 Subject: [PATCH 08/10] test-network: use dnsmasq for testing DHCP4-6RD --- test/test-network/conf/isc-dhcpd-6rd.conf | 22 --------------------- test/test-network/systemd-networkd-tests.py | 9 ++++++++- 2 files changed, 8 insertions(+), 23 deletions(-) delete mode 100644 test/test-network/conf/isc-dhcpd-6rd.conf diff --git a/test/test-network/conf/isc-dhcpd-6rd.conf b/test/test-network/conf/isc-dhcpd-6rd.conf deleted file mode 100644 index 0b32f4b696..0000000000 --- a/test/test-network/conf/isc-dhcpd-6rd.conf +++ /dev/null @@ -1,22 +0,0 @@ -default-lease-time 2592000; -preferred-lifetime 604800; - -default-lease-time 600; -max-lease-time 7200; - -option domain-name-servers 10.0.0.2; -option domain-search "test.example.com","example.com"; - -# ipv4masklen = 8 -# 6rd prefix = 2001:db8::/32 -# BR address = 10.0.0.1 -option option-6rd code 212 = { - integer 8, integer 8, ip6-address, array of ip-address -}; - -option option-6rd 8 32 2001:db8:: 10.0.0.1; - -subnet 10.0.0.0 netmask 255.0.0.0 { - # Addresses available to clients - range 10.100.100.100 10.100.100.199; -} diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 0f4f7a3bd6..009ab70699 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5028,11 +5028,13 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): def setUp(self): stop_isc_dhcpd() + stop_dnsmasq() remove_links(self.links) stop_networkd(show_logs=False) def tearDown(self): stop_isc_dhcpd() + stop_dnsmasq() remove_links(self.links) remove_unit_from_networkd_path(self.units) stop_networkd(show_logs=True) @@ -5243,7 +5245,12 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): start_networkd() self.wait_online(['veth-peer:routable']) - start_isc_dhcpd('veth-peer', 'isc-dhcpd-6rd.conf', ip='-4') + ''' + ipv4masklen: 8 + 6rd-prefix: 2001:db8::/32 + br-addresss: 10.0.0.1 + ''' + start_dnsmasq(additional_options='--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:01', ipv4_range='10.100.100.100,10.100.100.200', ipv4_router='10.0.0.1', lease_time='2m') self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded', 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) From 2616b5285fd209c867e028a60e8ab9bfc4fb19b4 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:55:54 +0900 Subject: [PATCH 09/10] test-network: introduce dump_dnsmasq_log_file() --- test/test-network/systemd-networkd-tests.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 009ab70699..28a54dc4f7 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -526,6 +526,11 @@ def stop_by_pid_file(pid_file): def stop_dnsmasq(): stop_by_pid_file(dnsmasq_pid_file) +def dump_dnsmasq_log_file(): + if os.path.exists(dnsmasq_log_file): + with open (dnsmasq_log_file) as in_file: + print(in_file.read()) + def search_words_in_dnsmasq_log(words, show_all=False): if os.path.exists(dnsmasq_log_file): with open (dnsmasq_log_file) as in_file: From 6a936c9c9ab77a884a579636d6349770f21b2adc Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 18 Dec 2021 09:52:04 +0900 Subject: [PATCH 10/10] test-network: add tests for renewing/rebinding lease --- test/test-network/systemd-networkd-tests.py | 121 ++++++++++---------- 1 file changed, 60 insertions(+), 61 deletions(-) diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 28a54dc4f7..cc450aeb96 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -5238,27 +5238,7 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print(output) self.assertRegex(output, '3ffe:501:ffff:[2-9a-f]03::/64 proto dhcp metric [0-9]* expires') - def test_dhcp4_6rd(self): - copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp4-6rd-server.network', 'dhcp4-6rd-upstream.network', - '25-veth-downstream-veth97.netdev', 'dhcp-pd-downstream-veth97.network', 'dhcp-pd-downstream-veth97-peer.network', - '25-veth-downstream-veth98.netdev', 'dhcp-pd-downstream-veth98.network', 'dhcp-pd-downstream-veth98-peer.network', - '11-dummy.netdev', 'dhcp-pd-downstream-test1.network', - 'dhcp-pd-downstream-dummy97.network', - '12-dummy.netdev', 'dhcp-pd-downstream-dummy98.network', - '13-dummy.netdev', 'dhcp-pd-downstream-dummy99.network', - '80-6rd-tunnel.network') - - start_networkd() - self.wait_online(['veth-peer:routable']) - ''' - ipv4masklen: 8 - 6rd-prefix: 2001:db8::/32 - br-addresss: 10.0.0.1 - ''' - start_dnsmasq(additional_options='--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:01', ipv4_range='10.100.100.100,10.100.100.200', ipv4_router='10.0.0.1', lease_time='2m') - self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded', - 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) - + def verify_dhcp4_6rd(self, tunnel_name): print('### ip -4 address show dev veth-peer scope global') output = check_output('ip -4 address show dev veth-peer scope global') print(output) @@ -5398,10 +5378,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print(output) self.assertRegex(output, '2001:db8:6464:[0-9a-f]+09::/64 proto ra metric [0-9]* expires') - # Test case for a downstream which appears later - check_output('ip link add dummy97 type dummy') - self.wait_online(['dummy97:routable']) - print('### ip -6 address show dev dummy97 scope global') output = check_output('ip -6 address show dev dummy97 scope global') print(output) @@ -5415,42 +5391,6 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): print(output) self.assertRegex(output, '2001:db8:6464:[0-9a-f]+01::/64 proto kernel metric [0-9]* expires') - # Test case for reconfigure - check_output(*networkctl_cmd, 'reconfigure', 'dummy98', 'dummy99', env=env) - self.wait_online(['dummy98:routable']) - - print('### ip -6 address show dev dummy98 scope global') - output = check_output('ip -6 address show dev dummy98 scope global') - print(output) - # address in IA_PD (Token=static) - self.assertRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+02:1a:2b:3c:4d/64 (metric 256 |)scope global dynamic mngtmpaddr') - # address in IA_PD (temporary) - self.wait_address('dummy98', 'inet6 2001:db8:6464:[0-9a-f]+02:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*:[0-9a-f]*/64 (metric 256 |)scope global temporary dynamic', ipv='-6') - - print('### ip -6 address show dev dummy99 scope global') - output = check_output('ip -6 address show dev dummy99 scope global') - print(output) - # Assign=no - self.assertNotRegex(output, 'inet6 2001:db8:6464:[0-9a-f]+03') - - print('### ip -6 route show dev dummy98') - output = check_output('ip -6 route show dev dummy98') - print(output) - self.assertRegex(output, '2001:db8:6464:[0-9a-f]+02::/64 proto kernel metric [0-9]* expires') - - print('### ip -6 route show dev dummy99') - output = check_output('ip -6 route show dev dummy99') - print(output) - self.assertRegex(output, '2001:db8:6464:[0-9a-f]+03::/64 proto dhcp metric [0-9]* expires') - - tunnel_name = None - for name in os.listdir('/sys/class/net/'): - if name.startswith('6rd-'): - tunnel_name = name - break - - self.wait_online(['{}:routable'.format(tunnel_name)]) - print('### ip -d link show dev {}'.format(tunnel_name)) output = check_output('ip -d link show dev {}'.format(tunnel_name)) print(output) @@ -5478,6 +5418,65 @@ class NetworkdDHCPPDTests(unittest.TestCase, Utilities): self.assertIn('default', output) self.assertIn('via ::10.0.0.1 dev {}'.format(tunnel_name), output) + def test_dhcp4_6rd(self): + copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp4-6rd-server.network', 'dhcp4-6rd-upstream.network', + '25-veth-downstream-veth97.netdev', 'dhcp-pd-downstream-veth97.network', 'dhcp-pd-downstream-veth97-peer.network', + '25-veth-downstream-veth98.netdev', 'dhcp-pd-downstream-veth98.network', 'dhcp-pd-downstream-veth98-peer.network', + '11-dummy.netdev', 'dhcp-pd-downstream-test1.network', + 'dhcp-pd-downstream-dummy97.network', + '12-dummy.netdev', 'dhcp-pd-downstream-dummy98.network', + '13-dummy.netdev', 'dhcp-pd-downstream-dummy99.network', + '80-6rd-tunnel.network') + + start_networkd() + self.wait_online(['veth-peer:routable']) + ''' + ipv4masklen: 8 + 6rd-prefix: 2001:db8::/32 + br-addresss: 10.0.0.1 + ''' + start_dnsmasq(additional_options='--dhcp-option=212,08:20:20:01:0d:b8:00:00:00:00:00:00:00:00:00:00:00:00:0a:00:00:01', ipv4_range='10.100.100.100,10.100.100.200', ipv4_router='10.0.0.1', lease_time='2m') + self.wait_online(['veth99:routable', 'test1:routable', 'dummy98:routable', 'dummy99:degraded', + 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) + + # Test case for a downstream which appears later + check_output('ip link add dummy97 type dummy') + self.wait_online(['dummy97:routable']) + + # Find tunnel name + tunnel_name = None + for name in os.listdir('/sys/class/net/'): + if name.startswith('6rd-'): + tunnel_name = name + break + + self.wait_online(['{}:routable'.format(tunnel_name)]) + + self.verify_dhcp4_6rd(tunnel_name) + + # Test case for reconfigure + check_output(*networkctl_cmd, 'reconfigure', 'dummy98', 'dummy99', env=env) + self.wait_online(['dummy98:routable', 'dummy99:degraded']) + + self.verify_dhcp4_6rd(tunnel_name) + + # Test for renewing/rebinding lease + print('wait for 120 sec') + time.sleep(30) + print('wait for 90 sec') + time.sleep(30) + print('wait for 60 sec') + time.sleep(30) + print('wait for 30 sec') + time.sleep(30) + + dump_dnsmasq_log_file() + + self.wait_online(['veth99:routable', 'test1:routable', 'dummy97:routable', 'dummy98:routable', 'dummy99:degraded', + 'veth97:routable', 'veth97-peer:routable', 'veth98:routable', 'veth98-peer:routable']) + + self.verify_dhcp4_6rd(tunnel_name) + class NetworkdIPv6PrefixTests(unittest.TestCase, Utilities): links = [ 'dummy98',