From fbcd7e054bd4bc3e25afa41535d08ab2f2f0a095 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 23:29:36 +0900 Subject: [PATCH 1/5] sd-lldp-tx: insert missing empty line --- src/libsystemd-network/sd-lldp-tx.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libsystemd-network/sd-lldp-tx.c b/src/libsystemd-network/sd-lldp-tx.c index 2b822af01a..01c476ecde 100644 --- a/src/libsystemd-network/sd-lldp-tx.c +++ b/src/libsystemd-network/sd-lldp-tx.c @@ -590,6 +590,7 @@ int sd_lldp_tx_stop(sd_lldp_tx *lldp_tx) { return 1; } + int sd_lldp_tx_start(sd_lldp_tx *lldp_tx) { usec_t delay; int r; From 8ceca83141ffea2e383d1205957bdc47f5492875 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Fri, 16 Aug 2024 23:30:02 +0900 Subject: [PATCH 2/5] network/lldp-tx: introduce link_lldp_tx_update_capabilities() Currently it is unused, but it will be used later. --- src/network/networkd-lldp-tx.c | 30 ++++++++++++++++++++++++++++++ src/network/networkd-lldp-tx.h | 1 + 2 files changed, 31 insertions(+) diff --git a/src/network/networkd-lldp-tx.c b/src/network/networkd-lldp-tx.c index f48781ef8b..cc22fbf2d6 100644 --- a/src/network/networkd-lldp-tx.c +++ b/src/network/networkd-lldp-tx.c @@ -86,6 +86,36 @@ int link_lldp_tx_configure(Link *link) { return 0; } +int link_lldp_tx_update_capabilities(Link *link) { + int r; + + assert(link); + + if (!link->lldp_tx) + return 0; /* disabled, or not configured yet. */ + + r = sd_lldp_tx_set_capabilities(link->lldp_tx, + SD_LLDP_SYSTEM_CAPABILITIES_STATION | + SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE | + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER, + (link_get_ip_forwarding(link, AF_INET) > 0 || link_get_ip_forwarding(link, AF_INET6) > 0) ? + SD_LLDP_SYSTEM_CAPABILITIES_ROUTER : SD_LLDP_SYSTEM_CAPABILITIES_STATION); + if (r < 0) + return r; + + if (sd_lldp_tx_is_running(link->lldp_tx)) { + r = sd_lldp_tx_stop(link->lldp_tx); + if (r < 0) + return r; + + r = sd_lldp_tx_start(link->lldp_tx); + if (r < 0) + return r; + } + + return 0; +} + static const char * const lldp_multicast_mode_table[_SD_LLDP_MULTICAST_MODE_MAX] = { [SD_LLDP_MULTICAST_MODE_NEAREST_BRIDGE] = "nearest-bridge", [SD_LLDP_MULTICAST_MODE_NON_TPMR_BRIDGE] = "non-tpmr-bridge", diff --git a/src/network/networkd-lldp-tx.h b/src/network/networkd-lldp-tx.h index 73757f1725..346eb5cb1c 100644 --- a/src/network/networkd-lldp-tx.h +++ b/src/network/networkd-lldp-tx.h @@ -6,5 +6,6 @@ typedef struct Link Link; int link_lldp_tx_configure(Link *link); +int link_lldp_tx_update_capabilities(Link *link); CONFIG_PARSER_PROTOTYPE(config_parse_lldp_multicast_mode); From 0b695febb22ea5701eab4aee801e8a861ffdbaa6 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 17 Aug 2024 00:00:32 +0900 Subject: [PATCH 3/5] network: make IPMasquerade= imply global IP forwarding settings again After 3976c430927e1bfefa0413f80ebac84ab9a64350 (#31423), IPMasquerade= implies only per-interface IP forwarding. That means, nspawn users need to manually enable IPv4/IPv6Forwarding= in networkd.conf when --network-veth or friend is used. Even the change was announced in NEWS, the change itself breaks backward compatibility and extremely reduces usability. Let's make the setting imply the global setting again. Fixes #34010. --- man/networkd.conf.xml | 12 +++++++ man/systemd.network.xml | 18 +++++----- src/network/networkd-sysctl.c | 63 ++++++++++++++++++++++++++++++++++- 3 files changed, 83 insertions(+), 10 deletions(-) diff --git a/man/networkd.conf.xml b/man/networkd.conf.xml index cac1d3b6e7..9daa1254b6 100644 --- a/man/networkd.conf.xml +++ b/man/networkd.conf.xml @@ -131,6 +131,12 @@ for more details about the sysctl options. Defaults to unset and the sysctl options will not be changed. + If an interface is configured with a .network file that enables IPMasquerade= + for IPv4 (that is, ipv4 or both), this setting is implied + unless explicitly specified. See IPMasquerade= in + systemd.network5 + for more details. + @@ -145,6 +151,12 @@ for more details about the sysctl options. Defaults to unset and the sysctl options will not be changed. + If an interface is configured with a .network file that enables IPMasquerade= + for IPv6 (that is, ipv6 or both), this setting is implied + unless explicitly specified. See IPMasquerade= in + systemd.network5 + for more details. + diff --git a/man/systemd.network.xml b/man/systemd.network.xml index ebcb6d0481..0374dc7cdc 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -888,15 +888,15 @@ DuplicateAddressDetection=none ipv6, both, or no. Defaults to no. Note. Any positive boolean values such as yes or true are now deprecated. Please use one of the values above. Specifying - ipv4 or both implies IPv4Forwarding=, - unless it is explicitly specified. Similarly for IPv6Forwarding= when - ipv6 or both is specified. These implications are only on - this interface. Hence, to make the IP packet forwarding works, - IPv4Forwarding=/IPv6Forwarding= need to be enabled on an - upstream interface, or globally enabled by specifying them in - networkd.conf5. - See IPv4Forwarding=/IPv6Forwarding= in the above for more - details. + ipv4 or both implies IPv4Forwarding= + settings in both .network file for this interface and the global + networkd.conf5 + unless they are explicitly specified. Similarly for IPv6Forwarding= when + ipv6 or both is specified. See + IPv4Forwarding=/IPv6Forwarding= in the above for the per-link + settings, and + networkd.conf5 + for the global settings. diff --git a/src/network/networkd-sysctl.c b/src/network/networkd-sysctl.c index 68c23e0eb7..a454322fd0 100644 --- a/src/network/networkd-sysctl.c +++ b/src/network/networkd-sysctl.c @@ -7,7 +7,9 @@ #include "af-list.h" #include "missing_network.h" #include "networkd-link.h" +#include "networkd-lldp-tx.h" #include "networkd-manager.h" +#include "networkd-ndisc.h" #include "networkd-network.h" #include "networkd-sysctl.h" #include "socket-util.h" @@ -130,7 +132,7 @@ int link_get_ip_forwarding(Link *link, int family) { return link->manager->ip_forwarding[family == AF_INET6]; } -static int link_set_ip_forwarding(Link *link, int family) { +static int link_set_ip_forwarding_impl(Link *link, int family) { int r, t; assert(link); @@ -151,6 +153,65 @@ static int link_set_ip_forwarding(Link *link, int family) { return 0; } +static int link_reapply_ip_forwarding(Link *link, int family) { + int r, ret = 0; + + assert(link); + assert(IN_SET(family, AF_INET, AF_INET6)); + + if (!IN_SET(link->state, LINK_STATE_CONFIGURING, LINK_STATE_CONFIGURED)) + return 0; + + (void) link_set_ip_forwarding_impl(link, family); + + r = link_lldp_tx_update_capabilities(link); + if (r < 0) + RET_GATHER(ret, log_link_warning_errno(link, r, "Could not update LLDP capabilities, ignoring: %m")); + + if (family == AF_INET6 && !link_ndisc_enabled(link)) { + r = ndisc_stop(link); + if (r < 0) + RET_GATHER(ret, log_link_warning_errno(link, r, "Could not stop IPv6 Router Discovery, ignoring: %m")); + + ndisc_flush(link); + } + + return ret; +} + +static int link_set_ip_forwarding(Link *link, int family) { + int r; + + assert(link); + assert(link->manager); + assert(link->network); + assert(IN_SET(family, AF_INET, AF_INET6)); + + if (!link_is_configured_for_family(link, family)) + return 0; + + /* When IPMasquerade= is enabled and the global setting is unset, enable _global_ IP forwarding, and + * re-apply per-link setting for all links. */ + if (FLAGS_SET(link->network->ip_masquerade, family == AF_INET ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_IPV6) && + link->manager->ip_forwarding[family == AF_INET6] < 0) { + + link->manager->ip_forwarding[family == AF_INET6] = true; + manager_set_ip_forwarding(link->manager, family); + + Link *other; + HASHMAP_FOREACH(other, link->manager->links_by_index) { + r = link_reapply_ip_forwarding(other, family); + if (r < 0) + link_enter_failed(other); + } + + return 0; + } + + /* Otherwise, apply per-link setting for _this_ link. */ + return link_set_ip_forwarding_impl(link, family); +} + static int link_set_ipv4_rp_filter(Link *link) { assert(link); From 7908e1d459f5f2893d6aaf1d62009da7856f9410 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 17 Aug 2024 01:47:33 +0900 Subject: [PATCH 4/5] test: allow to skip matrix_run_one() if $TEST_MATCH_TESTCASE is set --- test/units/TEST-13-NSPAWN.nspawn.sh | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/test/units/TEST-13-NSPAWN.nspawn.sh b/test/units/TEST-13-NSPAWN.nspawn.sh index 0c74d2e16e..80ba5c97a3 100755 --- a/test/units/TEST-13-NSPAWN.nspawn.sh +++ b/test/units/TEST-13-NSPAWN.nspawn.sh @@ -943,6 +943,17 @@ matrix_run_one() { return 0 } +testcase_api_vfs() { + local api_vfs_writable + + for api_vfs_writable in yes no network; do + matrix_run_one no no $api_vfs_writable + matrix_run_one yes no $api_vfs_writable + matrix_run_one no yes $api_vfs_writable + matrix_run_one yes yes $api_vfs_writable + done +} + testcase_check_os_release() { # https://github.com/systemd/systemd/issues/29185 local base common_opts root @@ -1004,10 +1015,3 @@ EOF } run_testcases - -for api_vfs_writable in yes no network; do - matrix_run_one no no $api_vfs_writable - matrix_run_one yes no $api_vfs_writable - matrix_run_one no yes $api_vfs_writable - matrix_run_one yes yes $api_vfs_writable -done From 08779d7c55add3a3bad5228d35012c15e92c47a5 Mon Sep 17 00:00:00 2001 From: Yu Watanabe Date: Sat, 17 Aug 2024 01:48:50 +0900 Subject: [PATCH 5/5] test: add test case that 'nspawn --network-veth' enables IP forwarding --- test/TEST-13-NSPAWN/test.sh | 2 ++ test/test-functions | 25 +++++++++++++++-- test/units/TEST-13-NSPAWN.nspawn.sh | 42 +++++++++++++++++++++++++++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/test/TEST-13-NSPAWN/test.sh b/test/TEST-13-NSPAWN/test.sh index 5c85b0c5dc..3ab52d0eee 100755 --- a/test/TEST-13-NSPAWN/test.sh +++ b/test/TEST-13-NSPAWN/test.sh @@ -17,6 +17,8 @@ test_append_files() { # For virtual wlan interface. instmods mac80211_hwsim + # for IPMasquerade= + instmods "=net/netfilter" generate_module_dependencies # Create a dummy container "template" with a minimal toolset, which we can diff --git a/test/test-functions b/test/test-functions index e41e5792a3..8f08d84ad8 100644 --- a/test/test-functions +++ b/test/test-functions @@ -1454,10 +1454,31 @@ install_missing_libraries() { [[ -e "$libgcc_s" ]] && inst_library "$libgcc_s" done < <(ldconfig -p | awk '/\/libgcc_s.so.1$/ { print $4 }') - local lib path + local lib path libs # A number of dependencies is now optional via dlopen, so the install # script will not pick them up, since it looks at linkage. - for lib in libcryptsetup libidn libidn2 pwquality libqrencode tss2-esys tss2-rc tss2-mu tss2-tcti-device libfido2 libbpf libelf libdw xkbcommon p11-kit-1 libarchive libgcrypt libkmod; do + libs=( + libarchive + libbpf + libcryptsetup + libdw + libelf + libfido2 + libgcrypt + libidn + libidn2 + libip4tc + libkmod + libqrencode + p11-kit-1 + pwquality + tss2-esys + tss2-mu + tss2-rc + tss2-tcti-device + xkbcommon + ) + for lib in "${libs[@]}"; do ddebug "Searching for $lib via pkg-config" if pkg-config --exists "$lib"; then path="$(pkg-config --variable=libdir "$lib")" diff --git a/test/units/TEST-13-NSPAWN.nspawn.sh b/test/units/TEST-13-NSPAWN.nspawn.sh index 80ba5c97a3..2de9f9079f 100755 --- a/test/units/TEST-13-NSPAWN.nspawn.sh +++ b/test/units/TEST-13-NSPAWN.nspawn.sh @@ -1014,4 +1014,46 @@ EOF rm -fr "$root" } +testcase_ip_masquerade() { + local root + + if ! command -v networkctl >/dev/null; then + echo "This test requires systemd-networkd, skipping..." + return 0 + fi + + systemctl unmask systemd-networkd.service + systemctl edit --runtime --stdin systemd-networkd.service --drop-in=debug.conf <