mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Merge pull request #34014 from yuwata/network-ip-masquerade
network: make IPMasquerade= imply global IP forwarding settings again
This commit is contained in:
commit
a16079fccc
@ -131,6 +131,12 @@
|
||||
for more details about the sysctl options. Defaults to unset and the sysctl options will not be
|
||||
changed.</para>
|
||||
|
||||
<para>If an interface is configured with a .network file that enables <varname>IPMasquerade=</varname>
|
||||
for IPv4 (that is, <literal>ipv4</literal> or <literal>both</literal>), this setting is implied
|
||||
unless explicitly specified. See <varname>IPMasquerade=</varname> in
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for more details.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v256"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
@ -145,6 +151,12 @@
|
||||
for more details about the sysctl options. Defaults to unset and the sysctl options will not be
|
||||
changed.</para>
|
||||
|
||||
<para>If an interface is configured with a .network file that enables <varname>IPMasquerade=</varname>
|
||||
for IPv6 (that is, <literal>ipv6</literal> or <literal>both</literal>), this setting is implied
|
||||
unless explicitly specified. See <varname>IPMasquerade=</varname> in
|
||||
<citerefentry><refentrytitle>systemd.network</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for more details.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v256"/>
|
||||
</listitem>
|
||||
</varlistentry>
|
||||
|
@ -888,15 +888,15 @@ DuplicateAddressDetection=none</programlisting></para>
|
||||
<literal>ipv6</literal>, <literal>both</literal>, or <literal>no</literal>. Defaults to
|
||||
<literal>no</literal>. Note. Any positive boolean values such as <literal>yes</literal> or
|
||||
<literal>true</literal> are now deprecated. Please use one of the values above. Specifying
|
||||
<literal>ipv4</literal> or <literal>both</literal> implies <varname>IPv4Forwarding=</varname>,
|
||||
unless it is explicitly specified. Similarly for <varname>IPv6Forwarding=</varname> when
|
||||
<literal>ipv6</literal> or <literal>both</literal> is specified. These implications are only on
|
||||
this interface. Hence, to make the IP packet forwarding works,
|
||||
<varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> need to be enabled on an
|
||||
upstream interface, or globally enabled by specifying them in
|
||||
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
|
||||
See <varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> in the above for more
|
||||
details.</para>
|
||||
<literal>ipv4</literal> or <literal>both</literal> implies <varname>IPv4Forwarding=</varname>
|
||||
settings in both .network file for this interface and the global
|
||||
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
unless they are explicitly specified. Similarly for <varname>IPv6Forwarding=</varname> when
|
||||
<literal>ipv6</literal> or <literal>both</literal> is specified. See
|
||||
<varname>IPv4Forwarding=</varname>/<varname>IPv6Forwarding=</varname> in the above for the per-link
|
||||
settings, and
|
||||
<citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
|
||||
for the global settings.</para>
|
||||
|
||||
<xi:include href="version-info.xml" xpointer="v219"/>
|
||||
</listitem>
|
||||
|
@ -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;
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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
|
||||
|
@ -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")"
|
||||
|
@ -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
|
||||
@ -1003,11 +1014,46 @@ EOF
|
||||
rm -fr "$root"
|
||||
}
|
||||
|
||||
run_testcases
|
||||
testcase_ip_masquerade() {
|
||||
local root
|
||||
|
||||
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
|
||||
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 <<EOF
|
||||
[Service]
|
||||
Environment=SYSTEMD_LOG_LEVEL=debug
|
||||
EOF
|
||||
systemctl start systemd-networkd.service
|
||||
|
||||
root="$(mktemp -d /var/lib/machines/TEST-13-NSPAWN.ip_masquerade.XXX)"
|
||||
create_dummy_container "$root"
|
||||
|
||||
systemd-run --unit=nspawn-hoge.service \
|
||||
systemd-nspawn \
|
||||
--register=no \
|
||||
--directory="$root" \
|
||||
--ephemeral \
|
||||
--machine=hoge \
|
||||
--network-veth \
|
||||
bash -x -c "ip link set host0 up; sleep 30s"
|
||||
|
||||
/usr/lib/systemd/systemd-networkd-wait-online -i ve-hoge --timeout 30s
|
||||
|
||||
# Check IPMasquerade= for ve-* and friends enabled IP forwarding.
|
||||
[[ "$(cat /proc/sys/net/ipv4/conf/all/forwarding)" == "1" ]]
|
||||
[[ "$(cat /proc/sys/net/ipv4/conf/default/forwarding)" == "1" ]]
|
||||
[[ "$(cat /proc/sys/net/ipv6/conf/all/forwarding)" == "1" ]]
|
||||
[[ "$(cat /proc/sys/net/ipv6/conf/default/forwarding)" == "1" ]]
|
||||
|
||||
systemctl stop nspawn-hoge.service || :
|
||||
systemctl stop systemd-networkd.service
|
||||
systemctl mask systemd-networkd.service
|
||||
|
||||
rm -fr "$root"
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
Loading…
Reference in New Issue
Block a user