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>
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>
<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>
#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"
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);
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);