]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
network: introduce per-interface IP forwarding settings
authorYu Watanabe <watanabe.yu+github@gmail.com>
Tue, 20 Feb 2024 21:20:45 +0000 (06:20 +0900)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 22 Feb 2024 19:24:12 +0000 (19:24 +0000)
This deprecates IPForward= setting, which unconditionally controled
the global setting, even though it is a setting in .network file.

Instead, this introduces new IPv4Forwarding= and IPv6Forwarding=
settings both in .network and networkd.conf.
If these settings are specified in a .network file, then the
per-interface forwarding setting will be configured.
If specified in networkd.conf, then the global IP forwarding setting will
be configured.

Closes #30648.

24 files changed:
man/networkd.conf.xml
man/systemd.network.xml
src/network/networkd-gperf.gperf
src/network/networkd-lldp-tx.c
src/network/networkd-manager.c
src/network/networkd-manager.h
src/network/networkd-ndisc.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd-network.h
src/network/networkd-route-nexthop.c
src/network/networkd-sysctl.c
src/network/networkd-sysctl.h
src/network/networkd-util.c
src/network/networkd-util.h
test/test-network/conf/25-agent-client-peer.network
test/test-network/conf/25-agent-client.network
test/test-network/conf/25-agent-server-peer.network
test/test-network/conf/25-agent-server.network
test/test-network/conf/25-ipv6-proxy-ndp.network
test/test-network/conf/25-sysctl.network
test/test-network/conf/26-bridge-vlan-master-issue-20373.network
test/test-network/conf/26-bridge-vlan-slave-issue-20373.network
test/test-network/systemd-networkd-tests.py

index 9477bfe5afd9293cf236c1247a19c3809714c323..2ab5cf1d7906c8ab004fb653448250d584260c38 100644 (file)
         <xi:include href="version-info.xml" xpointer="v248"/></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><varname>IPv4Forwarding=</varname></term>
+        <listitem>
+          <para>Configures IPv4 packet forwarding for the system. Takes a boolean value. This controls the
+          <filename>net.ipv4.conf.default.forwarding</filename> and
+          <filename>net.ipv4.conf.all.forwarding</filename>sysctl options. See
+          <ulink url="https://docs.kernel.org/networking/ip-sysctl.html">IP Sysctl</ulink>
+          for more details about the sysctl options. Defaults to unset and the sysctl options will not be
+          changed.</para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
+
+      <varlistentry>
+        <term><varname>IPv6Forwarding=</varname></term>
+        <listitem>
+          <para>Configures IPv6 packet forwarding for the system. Takes a boolean value. This controls the
+          <filename>net.ipv6.conf.default.forwarding</filename> and
+          <filename>net.ipv6.conf.all.forwarding</filename> sysctl options. See
+          <ulink url="https://docs.kernel.org/networking/ip-sysctl.html">IP Sysctl</ulink>
+          for more details about the sysctl options. Defaults to unset and the sysctl options will not be
+          changed.</para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><varname>IPv6PrivacyExtensions=</varname></term>
         <listitem>
index adff23d1fedfa19ec6bb3adb6bcabf9dbb2c32f4..96228fc1985d800d1e6ced7d41c174b9def92e5a 100644 (file)
@@ -803,26 +803,43 @@ Table=1234</programlisting></para>
       </varlistentry>
 
       <varlistentry>
-        <term><varname>IPForward=</varname></term>
-        <listitem>
-          <para>Configures IP packet forwarding for the system. If enabled, incoming packets on any
-          network interface will be forwarded to any other interfaces according to the routing table.
-          Takes a boolean, or the values <literal>ipv4</literal> or <literal>ipv6</literal>, which only
-          enable IP packet forwarding for the specified address family. This controls the
-          <filename>net.ipv4.ip_forward</filename> and <filename>net.ipv6.conf.all.forwarding</filename>
-          sysctl options of the network interface (see
+        <term><varname>IPv4Forwarding=</varname></term>
+        <listitem>
+          <para>Configures IPv4 packet forwarding for the interface. Takes a boolean value. This controls the
+          <filename>net.ipv4.conf.<replaceable>INTERFACE</replaceable>.forwarding</filename> sysctl option of
+          the network interface. See
           <ulink url="https://docs.kernel.org/networking/ip-sysctl.html">IP Sysctl</ulink>
-          for details about sysctl options). Defaults to <literal>no</literal>.</para>
+          for more details about the sysctl option. Defaults to true if <varname>IPMasquerade=</varname> is
+          enabled for IPv4, otherwise the value specified to the same setting in
+          <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+          will be used. If none of them are specified, the sysctl option will not be changed.</para>
+
+          <para>To control the global setting, use the same setting in
+          <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
+          </para>
+
+          <xi:include href="version-info.xml" xpointer="v256"/>
+        </listitem>
+      </varlistentry>
 
-          <para>Note: this setting controls a global kernel option, and does so one way only: if a
-          network that has this setting enabled is set up the global setting is turned on. However,
-          it is never turned off again, even after all networks with this setting enabled are shut
-          down again.</para>
+      <varlistentry>
+        <term><varname>IPv6Forwarding=</varname></term>
+        <listitem>
+          <para>Configures IPv6 packet forwarding for the interface. Takes a boolean value. This controls the
+          <filename>net.ipv6.conf.<replaceable>INTERFACE</replaceable>.forwarding</filename> sysctl option of
+          the network interface. See
+          <ulink url="https://docs.kernel.org/networking/ip-sysctl.html">IP Sysctl</ulink>
+          for more details about the sysctl option. Defaults to true if <varname>IPMasquerade=</varname> is
+          enabled for IPv6 or <varname>IPv6SendRA=</varname> is enabled, otherwise the value specified to the
+          same setting in
+          <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+          will be used. If none of them are specified, the sysctl option will not be changed.</para>
 
-          <para>To allow IP packet forwarding only between specific network interfaces use a firewall.
+          <para>To control the global setting, use the same setting in
+          <citerefentry><refentrytitle>networkd.conf</refentrytitle><manvolnum>5</manvolnum></citerefentry>.
           </para>
 
-          <xi:include href="version-info.xml" xpointer="v219"/>
+          <xi:include href="version-info.xml" xpointer="v256"/>
         </listitem>
       </varlistentry>
 
@@ -832,9 +849,7 @@ Table=1234</programlisting></para>
           <para>Configures IP masquerading for the network interface. If enabled, packets forwarded
           from the network interface will be appear as coming from the local host. Takes one of
           <literal>ipv4</literal>, <literal>ipv6</literal>, <literal>both</literal>, or
-          <literal>no</literal>. Defaults to <literal>no</literal>. If enabled, this automatically sets
-          <varname>IPForward=</varname> to one of <literal>ipv4</literal>, <literal>ipv6</literal> or
-          <literal>yes</literal>.</para>
+          <literal>no</literal>. Defaults to <literal>no</literal>.</para>
           <para>Note. Any positive boolean values such as <literal>yes</literal> or
           <literal>true</literal> are now deprecated. Please use one of the values in the above.</para>
 
index c9e3c937f47ff7376be5b94528afccc31836c03b..bff64633e03da13bdcab5fd5044e54a861c7fd63 100644 (file)
@@ -27,6 +27,8 @@ Network.ManageForeignRoutingPolicyRules, config_parse_bool,
 Network.ManageForeignRoutes,             config_parse_bool,                      0,          offsetof(Manager, manage_foreign_routes)
 Network.ManageForeignNextHops,           config_parse_bool,                      0,          offsetof(Manager, manage_foreign_nexthops)
 Network.RouteTable,                      config_parse_route_table_names,         0,          0
+Network.IPv4Forwarding,                  config_parse_tristate,                  0,          offsetof(Manager, ip_forwarding[0])
+Network.IPv6Forwarding,                  config_parse_tristate,                  0,          offsetof(Manager, ip_forwarding[1])
 Network.IPv6PrivacyExtensions,           config_parse_ipv6_privacy_extensions,   0,          offsetof(Manager, ipv6_privacy_extensions)
 DHCPv4.DUIDType,                         config_parse_duid_type,                 0,          offsetof(Manager, dhcp_duid)
 DHCPv4.DUIDRawData,                      config_parse_duid_rawdata,              0,          offsetof(Manager, dhcp_duid)
index fc9196fc8be13ca81a15f66a2f35fd32f4d335a8..f48781ef8bb61c20cb6c148cae6e37470f8e32ad 100644 (file)
@@ -8,6 +8,7 @@
 #include "networkd-link.h"
 #include "networkd-lldp-tx.h"
 #include "networkd-manager.h"
+#include "networkd-sysctl.h"
 #include "parse-util.h"
 #include "string-table.h"
 #include "string-util.h"
@@ -69,9 +70,8 @@ int link_lldp_tx_configure(Link *link) {
                                         SD_LLDP_SYSTEM_CAPABILITIES_STATION |
                                         SD_LLDP_SYSTEM_CAPABILITIES_BRIDGE |
                                         SD_LLDP_SYSTEM_CAPABILITIES_ROUTER,
-                                        (link->network->ip_forward != ADDRESS_FAMILY_NO) ?
-                                        SD_LLDP_SYSTEM_CAPABILITIES_ROUTER :
-                                        SD_LLDP_SYSTEM_CAPABILITIES_STATION);
+                                        (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;
 
index 42c6371be5b18cbc98607f4242ad31f2a92424ef..c0d368ab1154b16cf0726ad47904a98b8ba877c6 100644 (file)
@@ -577,6 +577,7 @@ int manager_new(Manager **ret, bool test_mode) {
                 .dhcp_duid.type = DUID_TYPE_EN,
                 .dhcp6_duid.type = DUID_TYPE_EN,
                 .duid_product_uuid.type = DUID_TYPE_UUID,
+                .ip_forwarding = { -1, -1, },
         };
 
         *ret = TAKE_PTR(m);
@@ -659,6 +660,8 @@ int manager_start(Manager *m) {
 
         assert(m);
 
+        manager_set_sysctl(m);
+
         r = manager_start_speed_meter(m);
         if (r < 0)
                 return log_error_errno(r, "Failed to initialize speed meter: %m");
index 7788ce7d6f0835cf16775bf4f05de7f679db0062..8088e20b380b4b36abaaad8c722047e1f6a51c5c 100644 (file)
@@ -107,6 +107,9 @@ struct Manager {
         Hashmap *tuntap_fds_by_name;
 
         unsigned reloading;
+
+        /* sysctl */
+        int ip_forwarding[2];
 };
 
 int manager_new(Manager **ret, bool test_mode);
index d110482c0031b612dcb9d7be42bcef8810c684b2..b7b1475f6832f057885043e6b8f1a468264a0e30 100644 (file)
@@ -20,6 +20,7 @@
 #include "networkd-queue.h"
 #include "networkd-route.h"
 #include "networkd-state-file.h"
+#include "networkd-sysctl.h"
 #include "string-table.h"
 #include "string-util.h"
 #include "strv.h"
@@ -52,8 +53,16 @@ bool link_ipv6_accept_ra_enabled(Link *link) {
         if (!link_may_have_ipv6ll(link, /* check_multicast = */ true))
                 return false;
 
-        assert(link->network->ipv6_accept_ra >= 0);
-        return link->network->ipv6_accept_ra;
+        if (link->network->ipv6_accept_ra >= 0)
+                return link->network->ipv6_accept_ra;
+
+        /* Accept RAs if IPv6 forwarding is disabled, and ignore RAs if IPv6 forwarding is enabled. */
+        int t = link_get_ip_forwarding(link, AF_INET6);
+        if (t >= 0)
+                return !t;
+
+        /* Otherwise, defaults to true. */
+        return true;
 }
 
 void network_adjust_ipv6_accept_ra(Network *network) {
@@ -66,10 +75,6 @@ void network_adjust_ipv6_accept_ra(Network *network) {
                 network->ipv6_accept_ra = false;
         }
 
-        if (network->ipv6_accept_ra < 0)
-                /* default to accept RA if ip_forward is disabled and ignore RA if ip_forward is enabled */
-                network->ipv6_accept_ra = !FLAGS_SET(network->ip_forward, ADDRESS_FAMILY_IPV6);
-
         /* When RouterAllowList=, PrefixAllowList= or RouteAllowList= are specified, then
          * RouterDenyList=, PrefixDenyList= or RouteDenyList= are ignored, respectively. */
         if (!set_isempty(network->ndisc_allow_listed_router))
index 236bac7aa674d7b6fdcfdc5132955dc2c412ee70..12023772f96e4a70e5839347e6b536ddd1ef5dcb 100644 (file)
@@ -124,7 +124,9 @@ Network.DNSOverTLS,                          config_parse_dns_over_tls_mode,
 Network.DNSSEC,                              config_parse_dnssec_mode,                                 0,                             offsetof(Network, dnssec_mode)
 Network.DNSSECNegativeTrustAnchors,          config_parse_dnssec_negative_trust_anchors,               0,                             offsetof(Network, dnssec_negative_trust_anchors)
 Network.NTP,                                 config_parse_ntp,                                         0,                             offsetof(Network, ntp)
-Network.IPForward,                           config_parse_address_family_with_kernel,                  0,                             offsetof(Network, ip_forward)
+Network.IPForward,                           config_parse_ip_forward_deprecated,                       0,                             0
+Network.IPv4Forwarding,                      config_parse_tristate,                                    0,                             offsetof(Network, ip_forwarding[0])
+Network.IPv6Forwarding,                      config_parse_tristate,                                    0,                             offsetof(Network, ip_forwarding[1])
 Network.IPMasquerade,                        config_parse_ip_masquerade,                               0,                             offsetof(Network, ip_masquerade)
 Network.IPv6PrivacyExtensions,               config_parse_ipv6_privacy_extensions,                     0,                             offsetof(Network, ipv6_privacy_extensions)
 Network.IPv6AcceptRA,                        config_parse_tristate,                                    0,                             offsetof(Network, ipv6_accept_ra)
index 4101296275de0b8967eea52f29979f233f9be690..2ecbbff8208e5fd6e15c4b97d1aad17f9fff1e87 100644 (file)
@@ -225,9 +225,6 @@ int network_verify(Network *network) {
             network->ipv6ll_address_gen_mode < 0)
                 network->ipv6ll_address_gen_mode = IPV6_LINK_LOCAL_ADDRESSS_GEN_MODE_STABLE_PRIVACY;
 
-        /* IPMasquerade implies IPForward */
-        network->ip_forward |= network->ip_masquerade;
-
         network_adjust_ipv6_proxy_ndp(network);
         network_adjust_ipv6_accept_ra(network);
         network_adjust_dhcp(network);
@@ -465,6 +462,7 @@ int network_load_one(Manager *manager, OrderedHashmap **networks, const char *fi
                 .link_local = _ADDRESS_FAMILY_INVALID,
                 .ipv6ll_address_gen_mode = _IPV6_LINK_LOCAL_ADDRESS_GEN_MODE_INVALID,
 
+                .ip_forwarding = { -1, -1, },
                 .ipv4_accept_local = -1,
                 .ipv4_route_localnet = -1,
                 .ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID,
index e9ee556312b09f6bf7a1d25df4ba3a20d065f6c3..e9236ded01c406bd98d561737168c22438d39f1f 100644 (file)
@@ -320,7 +320,7 @@ struct Network {
         int ipoib_umcast;
 
         /* sysctl settings */
-        AddressFamily ip_forward;
+        int ip_forwarding[2];
         int ipv4_accept_local;
         int ipv4_route_localnet;
         int ipv6_dad_transmits;
index f7a2201b6b0a0b7ed70a50b777d1328e95488c7d..23bf0b330633eeccdbe79823127a8c89b1a8ad6d 100644 (file)
@@ -840,7 +840,7 @@ int route_section_verify_nexthops(Route *route) {
                                                  "Ignoring [Route] section from line %u.",
                                                  route->section->filename, route->section->line);
 
-                if (route->nexthop.family == AF_INET6 && !route->network->ipv6_accept_ra)
+                if (route->nexthop.family == AF_INET6 && route->network->ipv6_accept_ra == 0)
                         return log_warning_errno(SYNTHETIC_ERRNO(EINVAL),
                                                  "%s: Gateway=\"_ipv6ra\" is specified but IPv6AcceptRA= is disabled. "
                                                  "Ignoring [Route] section from line %u.",
index 8fa0ede5c2aee0057f4ce06dc905ae1006bf4770..f9db1f7f4af16c4c3085231d9f7aa234ebe33708 100644 (file)
@@ -4,6 +4,7 @@
 #include <linux/if.h>
 #include <linux/if_arp.h>
 
+#include "af-list.h"
 #include "missing_network.h"
 #include "networkd-link.h"
 #include "networkd-manager.h"
 #include "string-table.h"
 #include "sysctl-util.h"
 
+static void manager_set_ip_forwarding(Manager *manager, int family) {
+        int r, t;
+
+        assert(manager);
+        assert(IN_SET(family, AF_INET, AF_INET6));
+
+        if (family == AF_INET6 && !socket_ipv6_is_supported())
+                return;
+
+        t = manager->ip_forwarding[family == AF_INET6];
+        if (t < 0)
+                return; /* keep */
+
+        /* First, set the default value. */
+        r = sysctl_write_ip_property_boolean(family, "default", "forwarding", t);
+        if (r < 0)
+                log_warning_errno(r, "Failed to %s the default %s forwarding: %m",
+                                  enable_disable(t), af_to_ipv4_ipv6(family));
+
+        /* Then, set the value to all interfaces. */
+        r = sysctl_write_ip_property_boolean(family, "all", "forwarding", t);
+        if (r < 0)
+                log_warning_errno(r, "Failed to %s %s forwarding for all interfaces: %m",
+                                  enable_disable(t), af_to_ipv4_ipv6(family));
+}
+
+void manager_set_sysctl(Manager *manager) {
+        assert(manager);
+        assert(!manager->test_mode);
+
+        manager_set_ip_forwarding(manager, AF_INET);
+        manager_set_ip_forwarding(manager, AF_INET6);
+}
+
 static bool link_is_configured_for_family(Link *link, int family) {
         assert(link);
 
@@ -70,48 +105,50 @@ static int link_set_proxy_arp_pvlan(Link *link) {
         return sysctl_write_ip_property_boolean(AF_INET, link->ifname, "proxy_arp_pvlan", link->network->proxy_arp_pvlan > 0);
 }
 
-static bool link_ip_forward_enabled(Link *link, int family) {
+int link_get_ip_forwarding(Link *link, int family) {
         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 false;
-
-        return link->network->ip_forward & (family == AF_INET ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_IPV6);
-}
+        /* If it is explicitly specified, then honor the setting. */
+        int t = link->network->ip_forwarding[family == AF_INET6];
+        if (t >= 0)
+                return t;
 
-static int link_set_ipv4_forward(Link *link) {
-        assert(link);
-
-        if (!link_ip_forward_enabled(link, AF_INET))
-                return 0;
+        /* If IPMasquerade= is enabled, also enable IP forwarding. */
+        if (family == AF_INET && FLAGS_SET(link->network->ip_masquerade, ADDRESS_FAMILY_IPV4))
+                return true;
+        if (family == AF_INET6 && FLAGS_SET(link->network->ip_masquerade, ADDRESS_FAMILY_IPV6))
+                return true;
 
-        /* We propagate the forwarding flag from one interface to the
-         * global setting one way. This means: as long as at least one
-         * interface was configured at any time that had IP forwarding
-         * enabled the setting will stay on for good. We do this
-         * primarily to keep IPv4 and IPv6 packet forwarding behaviour
-         * somewhat in sync (see below). */
+        /* If IPv6SendRA= is enabled, also enable IPv6 forwarding. */
+        if (family == AF_INET6 && link_radv_enabled(link))
+                return true;
 
-        return sysctl_write_ip_property(AF_INET, NULL, "ip_forward", "1");
+        /* Otherwise, use the global setting. */
+        return link->manager->ip_forwarding[family == AF_INET6];
 }
 
-static int link_set_ipv6_forward(Link *link) {
+static int link_set_ip_forwarding(Link *link, int family) {
+        int r, t;
+
         assert(link);
+        assert(IN_SET(family, AF_INET, AF_INET6));
 
-        if (!link_ip_forward_enabled(link, AF_INET6))
+        if (!link_is_configured_for_family(link, family))
                 return 0;
 
-        /* On Linux, the IPv6 stack does not know a per-interface
-         * packet forwarding setting: either packet forwarding is on
-         * for all, or off for all. We hence don't bother with a
-         * per-interface setting, but simply propagate the interface
-         * flag, if it is set, to the global flag, one-way. Note that
-         * while IPv4 would allow a per-interface flag, we expose the
-         * same behaviour there and also propagate the setting from
-         * one to all, to keep things simple (see above). */
+        t = link_get_ip_forwarding(link, family);
+        if (t < 0)
+                return 0; /* keep */
 
-        return sysctl_write_ip_property(AF_INET6, "all", "forwarding", "1");
+        r = sysctl_write_ip_property_boolean(family, link->ifname, "forwarding", t);
+        if (r < 0)
+                return log_link_warning_errno(link, r, "Failed to %s %s forwarding, ignoring: %m",
+                                              enable_disable(t), af_to_ipv4_ipv6(family));
+
+        return 0;
 }
 
 static int link_set_ipv4_rp_filter(Link *link) {
@@ -291,13 +328,8 @@ int link_set_sysctl(Link *link) {
         if (r < 0)
                 log_link_warning_errno(link, r, "Cannot configure proxy ARP private VLAN for interface, ignoring: %m");
 
-        r = link_set_ipv4_forward(link);
-        if (r < 0)
-                log_link_warning_errno(link, r, "Cannot turn on IPv4 packet forwarding, ignoring: %m");
-
-        r = link_set_ipv6_forward(link);
-        if (r < 0)
-                log_link_warning_errno(link, r, "Cannot configure IPv6 packet forwarding, ignoring: %m");
+        (void) link_set_ip_forwarding(link, AF_INET);
+        (void) link_set_ip_forwarding(link, AF_INET6);
 
         r = link_set_ipv6_privacy_extensions(link);
         if (r < 0)
@@ -371,3 +403,24 @@ static const char* const ip_reverse_path_filter_table[_IP_REVERSE_PATH_FILTER_MA
 DEFINE_STRING_TABLE_LOOKUP(ip_reverse_path_filter, IPReversePathFilter);
 DEFINE_CONFIG_PARSE_ENUM(config_parse_ip_reverse_path_filter, ip_reverse_path_filter, IPReversePathFilter,
                          "Failed to parse IP reverse path filter option");
+
+int config_parse_ip_forward_deprecated(
+                const char* unit,
+                const char *filename,
+                unsigned line,
+                const char *section,
+                unsigned section_line,
+                const char *lvalue,
+                int ltype,
+                const char *rvalue,
+                void *data,
+                void *userdata) {
+
+        assert(filename);
+
+        log_syntax(unit, LOG_WARNING, filename, line, 0,
+                   "IPForward= setting is deprecated. "
+                   "Please use IPv4Forwarding= and/or IPv6Forwarding= in networkd.conf for global setting, "
+                   "and the same settings in .network files for per-interface setting.");
+        return 0;
+}
index 064438462c014276faf0aa31a225d88903edca2d..a47dda015defbb86579f2a04e89b63dea05dfbcd 100644 (file)
@@ -6,6 +6,7 @@
 #include "conf-parser.h"
 
 typedef struct Link Link;
+typedef struct Manager Manager;
 
 typedef enum IPv6PrivacyExtensions {
         /* These values map to the kernel's /proc/sys/net/ipv6/conf/xxx/use_tempaddr values. Do not reorder! */
@@ -26,6 +27,9 @@ typedef enum IPReversePathFilter {
         _IP_REVERSE_PATH_FILTER_INVALID = -EINVAL,
 } IPReversePathFilter;
 
+void manager_set_sysctl(Manager *manager);
+
+int link_get_ip_forwarding(Link *link, int family);
 int link_set_sysctl(Link *link);
 int link_set_ipv6_mtu(Link *link);
 
@@ -37,3 +41,4 @@ IPReversePathFilter ip_reverse_path_filter_from_string(const char *s) _pure_;
 
 CONFIG_PARSER_PROTOTYPE(config_parse_ipv6_privacy_extensions);
 CONFIG_PARSER_PROTOTYPE(config_parse_ip_reverse_path_filter);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_forward_deprecated);
index 33352ba772ec34c722408bff13073d26c8d20536..46f90088790e0203ddb75489952d12bf9f9fdeab 100644 (file)
@@ -116,48 +116,6 @@ DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_deprecated_address_family, AddressFa
 DEFINE_PRIVATE_STRING_TABLE_LOOKUP_FROM_STRING(ip_masquerade_address_family, AddressFamily);
 DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type_t);
 
-int config_parse_address_family_with_kernel(
-                const char* unit,
-                const char *filename,
-                unsigned line,
-                const char *section,
-                unsigned section_line,
-                const char *lvalue,
-                int ltype,
-                const char *rvalue,
-                void *data,
-                void *userdata) {
-
-        AddressFamily *fwd = data, s;
-
-        assert(filename);
-        assert(lvalue);
-        assert(rvalue);
-        assert(data);
-
-        /* This function is mostly obsolete now. It simply redirects
-         * "kernel" to "no". In older networkd versions we used to
-         * distinguish IPForward=off from IPForward=kernel, where the
-         * former would explicitly turn off forwarding while the
-         * latter would simply not touch the setting. But that logic
-         * is gone, hence silently accept the old setting, but turn it
-         * to "no". */
-
-        s = address_family_from_string(rvalue);
-        if (s < 0) {
-                if (streq(rvalue, "kernel"))
-                        s = ADDRESS_FAMILY_NO;
-                else {
-                        log_syntax(unit, LOG_WARNING, filename, line, 0, "Failed to parse IPForward= option, ignoring: %s", rvalue);
-                        return 0;
-                }
-        }
-
-        *fwd = s;
-
-        return 0;
-}
-
 int config_parse_ip_masquerade(
                 const char *unit,
                 const char *filename,
index 9c360f55264f2db1ce6d56b6e392a959cbe1a4d0..c3b4586caead7d2df9b37981a9393efca323417d 100644 (file)
@@ -52,7 +52,6 @@ static inline uint32_t usec_to_sec(usec_t usec, usec_t now_usec) {
 }
 
 CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family);
-CONFIG_PARSER_PROTOTYPE(config_parse_address_family_with_kernel);
 CONFIG_PARSER_PROTOTYPE(config_parse_ip_masquerade);
 CONFIG_PARSER_PROTOTYPE(config_parse_mud_url);
 
index e31108b3418bb42636f6f9a47e0cd8013d503839..4d7d758d2977820ca2c38253b8cc303a74f60d91 100644 (file)
@@ -5,7 +5,7 @@ Name=client-peer
 [Network]
 Address=192.168.6.2/24
 DHCPServer=yes
-IPForward=ipv4
+IPv4Forwarding=yes
 IPv6AcceptRA=no
 
 [DHCPServer]
index cfa7e5a17d28791d9c2fb5c3d90c400e5e79e81d..219d40a9b7ca3f205360f787bf1a509a43694dfb 100644 (file)
@@ -4,5 +4,5 @@ Name=client
 
 [Network]
 DHCP=yes
-IPForward=ipv4
+IPv4Forwarding=yes
 IPv6AcceptRA=no
index 1f6fa4b5bb1781392e0715d3d008546be3c78813..5e005c79ecd09ffcec9f3bf1bf6e1f6be8fc88a6 100644 (file)
@@ -4,5 +4,5 @@ Name=server-peer
 
 [Network]
 Address=192.168.5.2/24
-IPForward=ipv4
+IPv4Forwarding=yes
 IPv6AcceptRA=no
index 905508f55f1c2015579b4964f87a5e636684ed86..0108039e6fa99c56bab70badafd90abb67f9348e 100644 (file)
@@ -4,7 +4,7 @@ Name=server
 
 [Network]
 Address=192.168.5.1/24
-IPForward=ipv4
+IPv4Forwarding=yes
 DHCPServer=yes
 IPv6AcceptRA=no
 
index 81302abf9d6a364466267d95e748b8e90f613eb4..d01a633952c904b49ff5f4a0b63f195a0ad72f79 100644 (file)
@@ -9,7 +9,6 @@ IPv6ProxyNDPAddress=2607:5300:203:5215:3::1
 IPv6ProxyNDPAddress=2607:5300:203:5215:2::1
 IPv6ProxyNDPAddress=2607:5300:203:5215:1::1
 IPv6AcceptRA=no
-IPForward=yes
 Address=66.70.129.136/32
 Address=66.70.129.142/32
 Address=66.70.129.143/32
index ff1ded4ef0f174d3e58a2f990a472e82f2f31267..759fe65fe88d994c5f3bc7ee89ea67e2975eb36c 100644 (file)
@@ -3,7 +3,8 @@
 Name=dummy98
 
 [Network]
-IPForward=yes
+IPv4Forwarding=yes
+IPv6Forwarding=yes
 IPv6DuplicateAddressDetection=3
 IPv6HopLimit=5
 IPv4ProxyARP=yes
index 7a697571e8200658f09ac9b92d203a7b7351f054..67011ac6c4e65bb7f557fb472b12f5bb714094cf 100644 (file)
@@ -4,7 +4,6 @@ Name=bridge99
 
 [Network]
 VLAN=vlan99
-IPForward=yes
 ConfigureWithoutCarrier=yes
 LLDP=yes
 IPv6AcceptRA=false
index 876219fca27b970d3a5fdf40c30656d338bbdf70..bc7c3b0501a564ce7d93431c415a68b101c5128a 100644 (file)
@@ -4,7 +4,6 @@ Name=test1
 
 [Network]
 IPv6AcceptRA=no
-IPForward=yes
 Bridge=bridge99
 LinkLocalAddressing=no
 EmitLLDP=nearest-bridge
index b1951ade204c4f55d3ecd926d0cf7e5cce037cfd..aa7bd1e87aa7cf576d0927cc42f7ccdd4077c477 100755 (executable)
@@ -5223,6 +5223,9 @@ class NetworkdRATests(unittest.TestCase, Utilities):
         start_networkd()
         self.wait_online('veth99:routable', 'veth-peer:degraded')
 
+        # IPv6SendRA=yes implies IPv6Forwarding.
+        self.check_ipv6_sysctl_attr('veth-peer', 'forwarding', '1')
+
         output = resolvectl('dns', 'veth99')
         print(output)
         self.assertRegex(output, 'fe80::')