diff options
-rw-r--r-- | man/systemd.network.xml | 11 | ||||
-rw-r--r-- | src/network/networkd-address.c | 20 | ||||
-rw-r--r-- | src/network/networkd-address.h | 1 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 2 | ||||
-rw-r--r-- | src/network/networkd-network.c | 5 | ||||
-rw-r--r-- | src/network/networkd-network.h | 2 | ||||
-rw-r--r-- | src/network/networkd-util.c | 10 | ||||
-rw-r--r-- | src/network/networkd-util.h | 1 |
8 files changed, 39 insertions, 13 deletions
diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 8b7c9ff32a..5b622877e1 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -729,9 +729,14 @@ IPv6Token=prefixstable:2002:da8:1::</programlisting></para> <listitem><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 a boolean argument. Implies - <varname>IPForward=ipv4</varname>. Defaults to - <literal>no</literal>.</para></listitem> + Takes one of <literal>ipv4</literal>, <literal>ipv6</literal>, + <literal>both</literal>, <literal>no</literal>. + The setting <literal>yes</literal> is the same as <literal>ipv4</literal> and not as + <literal>both</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>both</literal>. + </para></listitem> </varlistentry> <varlistentry> <term><varname>IPv6PrivacyExtensions=</varname></term> diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c index 549f5f1f82..9c0e0220bb 100644 --- a/src/network/networkd-address.c +++ b/src/network/networkd-address.c @@ -261,16 +261,23 @@ static int address_set_masquerade(Address *address, bool add) { if (!address->link->network) return 0; - if (!address->link->network->ip_masquerade) + if (address->family == AF_INET && + !FLAGS_SET(address->link->network->ip_masquerade, ADDRESS_FAMILY_IPV4)) return 0; - if (address->family != AF_INET) + if (address->family == AF_INET6 && + !FLAGS_SET(address->link->network->ip_masquerade, ADDRESS_FAMILY_IPV6)) return 0; if (address->scope >= RT_SCOPE_LINK) return 0; - if (address->ip_masquerade_done == add) + if (address->family == AF_INET && + address->ip_masquerade_done == add) + return 0; + + if (address->family == AF_INET6 && + address->ipv6_masquerade_done == add) return 0; masked = address->in_addr; @@ -278,11 +285,14 @@ static int address_set_masquerade(Address *address, bool add) { if (r < 0) return r; - r = fw_add_masquerade(&address->link->manager->fw_ctx, add, AF_INET, &masked, address->prefixlen); + r = fw_add_masquerade(&address->link->manager->fw_ctx, add, address->family, &masked, address->prefixlen); if (r < 0) return r; - address->ip_masquerade_done = add; + if (address->family == AF_INET) + address->ip_masquerade_done = add; + else if (address->family == AF_INET6) + address->ipv6_masquerade_done = add; return 0; } diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h index 4764766996..1a7f6c8ed2 100644 --- a/src/network/networkd-address.h +++ b/src/network/networkd-address.h @@ -38,6 +38,7 @@ typedef struct Address { bool scope_set:1; bool ip_masquerade_done:1; + bool ipv6_masquerade_done:1; AddressFamily duplicate_address_detection; /* Called when address become ready */ diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 896a884063..516df61874 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -111,7 +111,7 @@ Network.DNSSEC, config_parse_dnssec_mode, Network.DNSSECNegativeTrustAnchors, config_parse_dnssec_negative_trust_anchors, 0, 0 Network.NTP, config_parse_ntp, 0, offsetof(Network, ntp) Network.IPForward, config_parse_address_family_with_kernel, 0, offsetof(Network, ip_forward) -Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) +Network.IPMasquerade, config_parse_address_family_compat, 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) Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 97a5f1b0d1..5d7f3b9b05 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -208,9 +208,8 @@ int network_verify(Network *network) { if (network->link_local < 0) network->link_local = network->bridge ? ADDRESS_FAMILY_NO : ADDRESS_FAMILY_IPV6; - /* IPMasquerade=yes implies IPForward=yes */ - if (network->ip_masquerade) - network->ip_forward |= ADDRESS_FAMILY_IPV4; + /* IPMasquerade implies IPForward */ + network->ip_forward |= network->ip_masquerade; network_adjust_ipv6_accept_ra(network); network_adjust_dhcp(network); diff --git a/src/network/networkd-network.h b/src/network/networkd-network.h index bd419f6ef4..e6353c6dc7 100644 --- a/src/network/networkd-network.h +++ b/src/network/networkd-network.h @@ -100,7 +100,7 @@ struct Network { KeepConfiguration keep_configuration; char **bind_carrier; bool default_route_on_device; - bool ip_masquerade; + AddressFamily ip_masquerade; /* DHCP Client Support */ AddressFamily dhcp; diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c index 83b38b2b05..02a6800a41 100644 --- a/src/network/networkd-util.c +++ b/src/network/networkd-util.c @@ -53,6 +53,16 @@ DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_addr AddressFamily, "Failed to parse option"); DEFINE_STRING_TABLE_LOOKUP(dhcp_lease_server_type, sd_dhcp_lease_server_type); +static AddressFamily address_family_compat_from_string(const char *s) { + if (streq_ptr(s, "yes")) /* compat name */ + return ADDRESS_FAMILY_IPV4; + if (streq_ptr(s, "both")) + return ADDRESS_FAMILY_YES; + return address_family_from_string(s); +} +DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_compat, address_family_compat, + AddressFamily, "Failed to parse option"); + int config_parse_address_family_with_kernel( const char* unit, const char *filename, diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h index 7b48046c35..76b4d0cfba 100644 --- a/src/network/networkd-util.h +++ b/src/network/networkd-util.h @@ -28,6 +28,7 @@ typedef struct NetworkConfigSection { CONFIG_PARSER_PROTOTYPE(config_parse_link_local_address_family); CONFIG_PARSER_PROTOTYPE(config_parse_address_family_with_kernel); +CONFIG_PARSER_PROTOTYPE(config_parse_address_family_compat); const char *address_family_to_string(AddressFamily b) _const_; AddressFamily address_family_from_string(const char *s) _pure_; |