def remove_fou_ports(ports):
for port in ports:
- call('ip fou del port', port)
+ call('ip fou del port', port, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def remove_routing_policy_rule_tables(tables):
for table in tables:
- call('ip rule del table', table)
+ rc = 0
+ while rc == 0:
+ rc = call('ip rule del table', table, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
def remove_routes(routes):
for route_type, addr in routes:
- call('ip route del', route_type, addr)
+ call('ip route del', route_type, addr, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
-def l2tp_tunnel_remove(tunnel_ids):
+def remove_l2tp_tunnels(tunnel_ids):
output = check_output('ip l2tp show tunnel')
for tid in tunnel_ids:
words='Tunnel ' + tid + ', encap'
'25-bond.netdev',
'25-bond-balanced-tlb.netdev',
'25-bridge.netdev',
+ '25-bridge-configure-without-carrier.network',
'25-bridge.network',
'25-erspan-tunnel-local-any.netdev',
'25-erspan-tunnel.netdev',
self.check_operstate('test1', 'degraded')
def test_bridge(self):
- copy_unit_to_networkd_unit_path('25-bridge.netdev')
+ copy_unit_to_networkd_unit_path('25-bridge.netdev', '25-bridge-configure-without-carrier.network')
start_networkd(0)
- wait_online(['bridge99:off'])
+ wait_online(['bridge99:no-carrier'])
tick = os.sysconf('SC_CLK_TCK')
self.assertEqual(9, round(float(read_link_attr('bridge99', 'bridge', 'hello_time')) / tick))
'25-ip6gre-tunnel.netdev', '25-tunnel.network',
'25-ip6gre-tunnel-local-any.netdev', '25-tunnel-local-any.network',
'25-ip6gre-tunnel-remote-any.netdev', '25-tunnel-remote-any.network')
- start_networkd()
+ start_networkd(5)
# Old kernels seem not to support IPv6LL address on ip6gre tunnel, So please do not use wait_online() here.
def test_nlmon(self):
copy_unit_to_networkd_unit_path('25-nlmon.netdev', 'netdev-link-local-addressing-yes.network')
- start_networkd()
+ start_networkd(0)
wait_online(['nlmon99:carrier'])
l2tp_tunnel_ids = [ '10' ]
def setUp(self):
- l2tp_tunnel_remove(self.l2tp_tunnel_ids)
+ remove_l2tp_tunnels(self.l2tp_tunnel_ids)
remove_links(self.links)
def tearDown(self):
- l2tp_tunnel_remove(self.l2tp_tunnel_ids)
+ remove_l2tp_tunnels(self.l2tp_tunnel_ids)
remove_links(self.links)
remove_unit_from_networkd_path(self.units)
'11-dummy.netdev',
'12-dummy.netdev',
'23-active-slave.network',
+ '24-keep-configuration-static.network',
'24-search-domain.network',
'25-address-link-section.network',
'25-address-preferred-lifetime-zero-ipv6.network',
def test_address_preferred_lifetime_zero_ipv6(self):
copy_unit_to_networkd_unit_path('25-address-preferred-lifetime-zero-ipv6.network', '12-dummy.netdev')
- start_networkd()
+ start_networkd(5)
self.check_link_exists('dummy98')
-
self.check_operstate('dummy98', 'routable', setup_state='configuring')
output = check_output('ip address show dummy98')
def test_configure_without_carrier(self):
copy_unit_to_networkd_unit_path('configure-without-carrier.network', '11-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('test1')
+ start_networkd(0)
+ wait_online(['test1:routable'])
output = check_output(*networkctl_cmd, 'status', 'test1')
print(output)
def test_routing_policy_rule(self):
copy_unit_to_networkd_unit_path('routing-policy-rule-test1.network', '11-dummy.netdev')
-
- start_networkd()
-
- self.check_link_exists('test1')
+ start_networkd(0)
+ wait_online(['test1:degraded'])
output = check_output('ip rule')
print(output)
for trial in range(3):
# Remove state files only first time
- start_networkd(remove_state_files=(trial == 0))
-
- self.check_link_exists('test1')
- self.check_link_exists('dummy98')
+ start_networkd(0, remove_state_files=(trial == 0))
+ wait_online(['test1:degraded', 'dummy98:degraded'])
+ time.sleep(1)
output = check_output('ip rule list table 7')
print(output)
@expectedFailureIfRoutingPolicyPortRangeIsNotAvailable()
def test_routing_policy_rule_port_range(self):
copy_unit_to_networkd_unit_path('25-fibrule-port-range.network', '11-dummy.netdev')
-
- start_networkd()
-
- self.check_link_exists('test1')
+ start_networkd(0)
+ wait_online(['test1:degraded'])
output = check_output('ip rule')
print(output)
@expectedFailureIfRoutingPolicyIPProtoIsNotAvailable()
def test_routing_policy_rule_invert(self):
copy_unit_to_networkd_unit_path('25-fibrule-invert.network', '11-dummy.netdev')
-
- start_networkd()
-
- self.check_link_exists('test1')
+ start_networkd(0)
+ wait_online(['test1:degraded'])
output = check_output('ip rule')
print(output)
def test_route_static(self):
copy_unit_to_networkd_unit_path('25-route-static.network', '12-dummy.netdev')
start_networkd(0)
-
wait_online(['dummy98:routable'])
output = check_output('ip -6 route show dev dummy98')
# reuse a bond from an earlier test, which does make the addresses go through
# tentative state, and do our test on that
copy_unit_to_networkd_unit_path('23-active-slave.network', '25-route-ipv6-src.network', '25-bond-active-backup-slave.netdev', '12-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('dummy98')
- self.check_link_exists('bond199')
+ start_networkd(0)
+ wait_online(['dummy98:enslaved', 'bond199:routable'])
output = check_output('ip -6 route list dev bond199')
print(output)
def test_ip_link_mac_address(self):
copy_unit_to_networkd_unit_path('25-address-link-section.network', '12-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('dummy98')
+ start_networkd(0)
+ wait_online(['dummy98:degraded'])
output = check_output('ip link show dummy98')
print(output)
def test_ip_link_unmanaged(self):
copy_unit_to_networkd_unit_path('25-link-section-unmanaged.network', '12-dummy.netdev')
- start_networkd()
+ start_networkd(5)
self.check_link_exists('dummy98')
- output = check_output(*networkctl_cmd, 'status', 'dummy98')
- print(output)
- self.assertRegex(output, 'unmanaged')
+ self.check_operstate('dummy98', 'off', setup_state='unmanaged')
def test_ipv6_address_label(self):
copy_unit_to_networkd_unit_path('25-ipv6-address-label-section.network', '12-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('dummy98')
+ start_networkd(0)
+ wait_online(['dummy98:degraded'])
output = check_output('ip addrlabel list')
print(output)
def test_ipv6_neighbor(self):
copy_unit_to_networkd_unit_path('25-neighbor-section.network', '12-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('dummy98')
+ start_networkd(0)
+ wait_online(['dummy98:degraded'], timeout='40s')
- output = check_output('ip neigh list')
+ output = check_output('ip neigh list dev dummy98')
print(output)
self.assertRegex(output, '192.168.10.1.*00:00:5e:00:02:65.*PERMANENT')
self.assertRegex(output, '2004:da8:1::1.*00:00:5e:00:02:66.*PERMANENT')
start_networkd(0)
wait_online(['test1:degraded', 'dummy98:carrier'])
- self.check_link_exists('test1')
- self.check_link_exists('dummy98')
-
output = check_output('ip address show dev test1')
print(output)
self.assertRegex(output, 'inet .* scope link')
print(output)
self.assertNotRegex(output, 'inet6* .* scope link')
- self.check_operstate('test1', 'degraded')
- self.check_operstate('dummy98', 'carrier')
-
'''
Documentation/networking/ip-sysctl.txt
output = check_output('ip -6 address show dummy98')
print(output)
self.assertEqual(output, '')
- self.check_operstate('dummy98', 'routable')
+ output = check_output('ip -4 route show dev dummy98')
+ print(output)
+ self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
+ output = check_output('ip -6 route show dev dummy98')
+ print(output)
+ self.assertEqual(output, '')
check_output('ip link del dummy98')
self.assertRegex(output, 'inet 10.2.3.4/16 brd 10.2.255.255 scope global dummy98')
output = check_output('ip -6 address show dummy98')
print(output)
+ self.assertRegex(output, 'inet6 2607:5300:203:3906::/64 scope global')
self.assertRegex(output, 'inet6 .* scope link')
- self.check_operstate('dummy98', 'routable')
+ output = check_output('ip -4 route show dev dummy98')
+ print(output)
+ self.assertEqual(output, '10.2.0.0/16 proto kernel scope link src 10.2.3.4')
+ output = check_output('ip -6 route show dev dummy98')
+ print(output)
+ self.assertRegex(output, 'default via 2607:5300:203:39ff:ff:ff:ff:ff proto static')
def test_bind_carrier(self):
copy_unit_to_networkd_unit_path('25-bind-carrier.network', '11-dummy.netdev')
- start_networkd()
-
- self.check_link_exists('test1')
+ start_networkd(0)
+ wait_online(['test1:routable'])
check_output('ip link add dummy98 type dummy')
check_output('ip link set dummy98 up')
self.assertRegex(output, 'DNS: 192.168.42.1')
self.assertRegex(output, 'Search Domains: one')
+ def test_keep_configuration_static(self):
+ check_output('systemctl stop systemd-networkd')
+
+ check_output('ip link add name dummy98 type dummy')
+ check_output('ip address add 10.1.2.3/16 dev dummy98')
+ check_output('ip address add 10.2.3.4/16 dev dummy98 valid_lft 600 preferred_lft 500')
+ output = check_output('ip address show dummy98')
+ print(output)
+ self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
+ self.assertRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
+ output = check_output('ip route show dev dummy98')
+ print(output)
+
+ copy_unit_to_networkd_unit_path('24-keep-configuration-static.network')
+ start_networkd(0)
+ wait_online(['dummy98:routable'])
+
+ output = check_output('ip address show dummy98')
+ print(output)
+ self.assertRegex(output, 'inet 10.1.2.3/16 scope global dummy98')
+ self.assertNotRegex(output, 'inet 10.2.3.4/16 scope global dynamic dummy98')
+
class NetworkdBondTests(unittest.TestCase, Utilities):
links = [
'bond199',
'25-vrf.netdev',
'25-vrf.network',
'dhcp-client-anonymize.network',
- 'dhcp-client-critical-connection.network',
'dhcp-client-gateway-onlink-implicit.network',
'dhcp-client-ipv4-dhcp-settings.network',
'dhcp-client-ipv4-only-ipv6-disabled.network',
'dhcp-client-ipv4-only.network',
'dhcp-client-ipv6-only.network',
'dhcp-client-ipv6-rapid-commit.network',
+ 'dhcp-client-keep-configuration-dhcp-on-stop.network',
+ 'dhcp-client-keep-configuration-dhcp.network',
'dhcp-client-listen-port.network',
'dhcp-client-route-metric.network',
'dhcp-client-route-table.network',
print(output)
self.assertRegex(output, 'metric 24')
- def test_dhcp_route_criticalconnection_true(self):
- copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-critical-connection.network')
+ def test_dhcp_keep_configuration_dhcp(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp.network')
start_networkd(0)
wait_online(['veth-peer:carrier'])
- start_dnsmasq()
+ start_dnsmasq(lease_time='2m')
wait_online(['veth99:routable', 'veth-peer:routable'])
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
print(output)
- self.assertRegex(output, '192.168.5.*')
+ self.assertRegex(output, r'192.168.5.*')
# Stopping dnsmasq as networkd won't be allowed to renew the DHCP lease.
stop_dnsmasq(dnsmasq_pid_file)
# Sleep for 120 sec as the dnsmasq minimum lease time can only be set to 120
+ print('Wait for the dynamic address to be expired')
time.sleep(125)
+ print('The lease address should be kept after lease expired')
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
print(output)
- self.assertRegex(output, '192.168.5.*')
+ self.assertRegex(output, r'192.168.5.*')
+
+ check_output('systemctl stop systemd-networkd')
+
+ print('The lease address should be kept after networkd stopped')
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ check_output('systemctl start systemd-networkd')
+ wait_online(['veth-peer:routable'])
+
+ print('Still the lease address should be kept after networkd restarted')
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ output = check_output(*networkctl_cmd, 'status', 'veth99', env=env)
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ def test_dhcp_keep_configuration_dhcp_on_stop(self):
+ copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-v4-server-veth-peer.network', 'dhcp-client-keep-configuration-dhcp-on-stop.network')
+ start_networkd(0)
+ wait_online(['veth-peer:carrier'])
+ start_dnsmasq(lease_time='2m')
+ wait_online(['veth99:routable', 'veth-peer:routable'])
+
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ stop_dnsmasq(dnsmasq_pid_file)
+ check_output('systemctl stop systemd-networkd')
+
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertRegex(output, r'192.168.5.*')
+
+ start_networkd(0)
+ wait_online(['veth-peer:routable'])
+
+ output = check_output('ip address show dev veth99 scope global')
+ print(output)
+ self.assertNotRegex(output, r'192.168.5.*')
def test_dhcp_client_reuse_address_as_static(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network', 'dhcp-client.network')
print(output)
self.assertEqual(output, '')
- self.check_operstate('vrf99', 'carrier')
- self.check_operstate('veth99', 'routable')
-
def test_dhcp_client_gateway_onlink_implicit(self):
copy_unit_to_networkd_unit_path('25-veth.netdev', 'dhcp-server-veth-peer.network',
'dhcp-client-gateway-onlink-implicit.network')