From 5a0bd90b826e21d39c18d9aacd00cc8999d5b084 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sun, 31 Mar 2019 23:56:39 +0900 Subject: [PATCH 1/5] test-network: add test for drop-in [WireGuardPeer] section This also merges the two wireguard tests, and use wait_online() to speed up the test. --- .../conf/25-wireguard.netdev.d/peer.conf | 4 +++ test/test-network/conf/25-wireguard.network | 2 ++ test/test-network/systemd-networkd-tests.py | 25 ++++++++----------- 3 files changed, 17 insertions(+), 14 deletions(-) create mode 100644 test/test-network/conf/25-wireguard.netdev.d/peer.conf create mode 100644 test/test-network/conf/25-wireguard.network diff --git a/test/test-network/conf/25-wireguard.netdev.d/peer.conf b/test/test-network/conf/25-wireguard.netdev.d/peer.conf new file mode 100644 index 0000000000..7ba692378e --- /dev/null +++ b/test/test-network/conf/25-wireguard.netdev.d/peer.conf @@ -0,0 +1,4 @@ +[WireGuardPeer] +PublicKey=lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc= +AllowedIPs=fdbc:bae2:7871:0500:e1fe:0793:8636:dad1/128 +AllowedIPs=fdbc:bae2:7871:e1fe:0793:8636::/96 diff --git a/test/test-network/conf/25-wireguard.network b/test/test-network/conf/25-wireguard.network new file mode 100644 index 0000000000..ab30523915 --- /dev/null +++ b/test/test-network/conf/25-wireguard.network @@ -0,0 +1,2 @@ +[Match] +Name=wg99 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index 4e4858507f..fb5c033cd9 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -295,6 +295,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): '25-wireguard-23-peers.network', '25-wireguard-private-key.txt', '25-wireguard.netdev', + '25-wireguard.network', '6rd.network', 'erspan.network', 'gre.network', @@ -493,17 +494,25 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): @expectedFailureIfModuleIsNotAvailable('wireguard') def test_wireguard(self): - self.copy_unit_to_networkd_unit_path('25-wireguard.netdev') - self.start_networkd() + self.copy_unit_to_networkd_unit_path('25-wireguard.netdev', '25-wireguard.network', + '25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network', + '25-wireguard-private-key.txt') + self.start_networkd(0) + self.wait_online(['wg99:carrier', 'wg98:routable']) + + self.assertTrue(self.link_exits('wg99')) + self.assertTrue(self.link_exits('wg98')) if shutil.which('wg'): subprocess.call('wg') + output = subprocess.check_output(['wg', 'show', 'wg99', 'listen-port']).rstrip().decode('utf-8') self.assertTrue(output, '51820') output = subprocess.check_output(['wg', 'show', 'wg99', 'fwmark']).rstrip().decode('utf-8') self.assertTrue(output, '0x4d2') output = subprocess.check_output(['wg', 'show', 'wg99', 'allowed-ips']).rstrip().decode('utf-8') self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t192.168.26.0/24 fd31:bf08:57cb::/48') + self.assertTrue(output, 'lsDtM3AbjxNlauRKzHEPfgS1Zp7cp/VX5Use/P4PQSc=\tfdbc:bae2:7871:e1fe:793:8636::/96 fdbc:bae2:7871:500:e1fe:793:8636:dad1/128') output = subprocess.check_output(['wg', 'show', 'wg99', 'persistent-keepalive']).rstrip().decode('utf-8') self.assertTrue(output, 'RDf+LSpeEre7YEIKaxg+wbpsNV7du+ktR99uBEtIiCA=\t20') output = subprocess.check_output(['wg', 'show', 'wg99', 'endpoints']).rstrip().decode('utf-8') @@ -511,21 +520,9 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): output = subprocess.check_output(['wg', 'show', 'wg99', 'private-key']).rstrip().decode('utf-8') self.assertTrue(output, 'EEGlnEPYJV//kbvvIqxKkQwOiS+UENyPncC4bF46ong=') - self.assertTrue(self.link_exits('wg99')) - - @expectedFailureIfModuleIsNotAvailable('wireguard') - def test_wireguard_23_peers(self): - self.copy_unit_to_networkd_unit_path('25-wireguard-23-peers.netdev', '25-wireguard-23-peers.network', - '25-wireguard-private-key.txt') - self.start_networkd() - - if shutil.which('wg'): - subprocess.call('wg') output = subprocess.check_output(['wg', 'show', 'wg98', 'private-key']).rstrip().decode('utf-8') self.assertTrue(output, 'CJQUtcS9emY2fLYqDlpSZiE/QJyHkPWr+WHtZLZ90FU=') - self.assertTrue(self.link_exits('wg98')) - def test_geneve(self): self.copy_unit_to_networkd_unit_path('25-geneve.netdev') self.start_networkd() From b519908cace83fc57b7258c24f7f59919ae77837 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 1 Apr 2019 00:24:25 +0900 Subject: [PATCH 2/5] network: do not abort execution when NetDev.Name= conflicts This also changes that .netdev files are loaded in ascending order. Otherwise, when NetDev.ifname= setting conflicts with other .netdev file, then .netdev file with large prefix number wins. --- src/network/netdev/netdev.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index f6d3ef8153..df05cb465b 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -738,6 +738,19 @@ int netdev_load_one(Manager *manager, const char *filename) { return r; r = hashmap_put(netdev->manager->netdevs, netdev->ifname, netdev); + if (r == -EEXIST) { + NetDev *n = hashmap_get(netdev->manager->netdevs, netdev->ifname); + + assert(n); + log_netdev_warning_errno(netdev, r, + "The setting Name=%s in %s conflicts with the one in %s, ignoring", + netdev->ifname, netdev->filename, n->filename); + + /* Clear ifname before netdev_free() is called. Otherwise, the NetDev object 'n' is + * removed from the hashmap 'manager->netdevs'. */ + netdev->ifname = mfree(netdev->ifname); + return 0; + } if (r < 0) return r; @@ -810,7 +823,7 @@ int netdev_load(Manager *manager) { if (r < 0) return log_error_errno(r, "Failed to enumerate netdev files: %m"); - STRV_FOREACH_BACKWARDS(f, files) { + STRV_FOREACH(f, files) { r = netdev_load_one(manager, *f); if (r < 0) return r; From c6e77d7b22e9d3abc16bfc6be3f677198a7071e7 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 1 Apr 2019 00:37:58 +0900 Subject: [PATCH 3/5] network: add '=' to config key names in log Also, long lines are wrapped. --- src/network/netdev/netdev.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/network/netdev/netdev.c b/src/network/netdev/netdev.c index df05cb465b..c1bcfc66e6 100644 --- a/src/network/netdev/netdev.c +++ b/src/network/netdev/netdev.c @@ -684,12 +684,12 @@ int netdev_load_one(Manager *manager, const char *filename) { } if (netdev_raw->kind == _NETDEV_KIND_INVALID) { - log_warning("NetDev has no Kind configured in %s. Ignoring", filename); + log_warning("NetDev has no Kind= configured in %s. Ignoring", filename); return 0; } if (!netdev_raw->ifname) { - log_warning("NetDev without Name configured in %s. Ignoring", filename); + log_warning("NetDev without Name= configured in %s. Ignoring", filename); return 0; } @@ -704,7 +704,8 @@ int netdev_load_one(Manager *manager, const char *filename) { netdev->n_ref = 1; netdev->manager = manager; netdev->kind = netdev_raw->kind; - netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time, so that done() will be called on destruction */ + netdev->state = NETDEV_STATE_LOADING; /* we initialize the state here for the first time, + so that done() will be called on destruction */ if (NETDEV_VTABLE(netdev)->init) NETDEV_VTABLE(netdev)->init(netdev); @@ -730,7 +731,9 @@ int netdev_load_one(Manager *manager, const char *filename) { if (!netdev->mac && netdev->kind != NETDEV_KIND_VLAN) { r = netdev_get_mac(netdev->ifname, &netdev->mac); if (r < 0) - return log_error_errno(r, "Failed to generate predictable MAC address for %s: %m", netdev->ifname); + return log_netdev_error_errno(netdev, r, + "Failed to generate predictable MAC address for %s: %m", + netdev->ifname); } r = hashmap_ensure_allocated(&netdev->manager->netdevs, &string_hash_ops); From 4b4a6c9b415aef902edfc75eb2de330398f7f05a Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 1 Apr 2019 00:55:22 +0900 Subject: [PATCH 4/5] udev: shorten code a bit --- src/udev/net/link-config.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/udev/net/link-config.c b/src/udev/net/link-config.c index daa737a68d..14690e364b 100644 --- a/src/udev/net/link-config.c +++ b/src/udev/net/link-config.c @@ -166,9 +166,7 @@ int link_load_one(link_config_ctx *ctx, const char *filename) { log_debug("Parsed configuration file %s", filename); - LIST_PREPEND(links, ctx->links, link); - link = NULL; - + LIST_PREPEND(links, ctx->links, TAKE_PTR(link)); return 0; } From 753e0a24463125c9954d077c2d2b59d57e08b61c Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Mon, 1 Apr 2019 01:06:22 +0900 Subject: [PATCH 5/5] test-network: add test for NetDev.Name= conflict --- test/test-network/conf/15-name-conflict-test.netdev | 4 ++++ test/test-network/systemd-networkd-tests.py | 5 ++++- 2 files changed, 8 insertions(+), 1 deletion(-) create mode 100644 test/test-network/conf/15-name-conflict-test.netdev diff --git a/test/test-network/conf/15-name-conflict-test.netdev b/test/test-network/conf/15-name-conflict-test.netdev new file mode 100644 index 0000000000..c9d18d76b6 --- /dev/null +++ b/test/test-network/conf/15-name-conflict-test.netdev @@ -0,0 +1,4 @@ +[NetDev] +Name=dropin-test +Kind=dummy +MACAddress=00:50:56:c0:00:38 diff --git a/test/test-network/systemd-networkd-tests.py b/test/test-network/systemd-networkd-tests.py index fb5c033cd9..d43301ae33 100755 --- a/test/test-network/systemd-networkd-tests.py +++ b/test/test-network/systemd-networkd-tests.py @@ -245,6 +245,7 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): '10-dropin-test.netdev', '11-dummy.netdev', '12-dummy.netdev', + '15-name-conflict-test.netdev', '21-macvlan.netdev', '21-macvtap.netdev', '21-vlan-test1.network', @@ -322,11 +323,13 @@ class NetworkdNetDevTests(unittest.TestCase, Utilities): self.remove_unit_from_networkd_path(self.units) def test_dropin(self): - self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev') + self.copy_unit_to_networkd_unit_path('10-dropin-test.netdev', '15-name-conflict-test.netdev') self.start_networkd() self.assertTrue(self.link_exits('dropin-test')) + # This also tests NetDev.Name= conflict and basic networkctl functionalities + output = subprocess.check_output(['ip', 'link', 'show', 'dropin-test']).rstrip().decode('utf-8') print(output) self.assertRegex(output, '00:50:56:c0:00:28')