diff --git a/man/systemd.network.xml b/man/systemd.network.xml
index d0bd0c57d45..610799724b6 100644
--- a/man/systemd.network.xml
+++ b/man/systemd.network.xml
@@ -735,17 +735,15 @@ IPv6Token=prefixstable:2002:da8:1::
IPMasquerade=
- 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 ipv4, ipv6,
- both, no.
- The setting yes is the same as ipv4 and not as
- both!
- Defaults to no.
- If enabled, this automatically sets IPForward to one of
- ipv4, ipv6 or both.
-
+ 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 ipv4, ipv6, both, or
+ no. Defaults to no. If enabled, this automatically sets
+ IPForward= to one of ipv4, ipv6 or
+ yes.
+ Note. Any positive boolean values such as yes or
+ true are now deprecated. Please use one of the values in the above.
+
IPv6PrivacyExtensions=
diff --git a/src/network/networkd-address.c b/src/network/networkd-address.c
index f55f9fafbe7..566709b3715 100644
--- a/src/network/networkd-address.c
+++ b/src/network/networkd-address.c
@@ -276,12 +276,7 @@ static int address_set_masquerade(Address *address, bool add) {
if (address->scope >= RT_SCOPE_LINK)
return 0;
- if (address->family == AF_INET &&
- address->ip_masquerade_done == add)
- return 0;
-
- if (address->family == AF_INET6 &&
- address->ipv6_masquerade_done == add)
+ if (address->ip_masquerade_done == add)
return 0;
masked = address->in_addr;
@@ -293,10 +288,7 @@ static int address_set_masquerade(Address *address, bool add) {
if (r < 0)
return r;
- if (address->family == AF_INET)
- address->ip_masquerade_done = add;
- else if (address->family == AF_INET6)
- address->ipv6_masquerade_done = add;
+ address->ip_masquerade_done = add;
return 0;
}
diff --git a/src/network/networkd-address.h b/src/network/networkd-address.h
index d50c5a77f52..7c2d0db3d07 100644
--- a/src/network/networkd-address.h
+++ b/src/network/networkd-address.h
@@ -38,7 +38,6 @@ 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 60ac30fbce6..e7e51e2f19c 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_address_family_compat, 0, offsetof(Network, ip_masquerade)
+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)
Network.IPv6AcceptRouterAdvertisements, config_parse_tristate, 0, offsetof(Network, ipv6_accept_ra)
diff --git a/src/network/networkd-util.c b/src/network/networkd-util.c
index 52f4e9dbb56..a9dd6d45eb6 100644
--- a/src/network/networkd-util.c
+++ b/src/network/networkd-util.c
@@ -40,6 +40,13 @@ static const char* const dhcp_deprecated_address_family_table[_ADDRESS_FAMILY_MA
[ADDRESS_FAMILY_IPV6] = "v6",
};
+static const char* const ip_masquerade_address_family_table[_ADDRESS_FAMILY_MAX] = {
+ [ADDRESS_FAMILY_NO] = "no",
+ [ADDRESS_FAMILY_YES] = "both",
+ [ADDRESS_FAMILY_IPV4] = "ipv4",
+ [ADDRESS_FAMILY_IPV6] = "ipv6",
+};
+
static const char* const dhcp_lease_server_type_table[_SD_DHCP_LEASE_SERVER_TYPE_MAX] = {
[SD_DHCP_LEASE_DNS] = "DNS servers",
[SD_DHCP_LEASE_NTP] = "NTP servers",
@@ -65,18 +72,9 @@ DEFINE_STRING_TABLE_LOOKUP(duplicate_address_detection_address_family, AddressFa
DEFINE_CONFIG_PARSE_ENUM(config_parse_link_local_address_family, link_local_address_family,
AddressFamily, "Failed to parse option");
DEFINE_STRING_TABLE_LOOKUP_FROM_STRING(dhcp_deprecated_address_family, AddressFamily);
+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);
-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,
@@ -119,6 +117,49 @@ int config_parse_address_family_with_kernel(
return 0;
}
+int config_parse_ip_masquerade(
+ 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 a, *ret = data;
+ int r;
+
+ if (isempty(rvalue)) {
+ *ret = ADDRESS_FAMILY_NO;
+ return 0;
+ }
+
+ r = parse_boolean(rvalue);
+ if (r >= 0) {
+ if (r)
+ log_syntax(unit, LOG_WARNING, filename, line, 0,
+ "IPMasquerade=%s is deprecated, and it is handled as \"ipv4\" instead of \"both\". "
+ "Please use \"ipv4\" or \"both\".",
+ rvalue);
+
+ *ret = r ? ADDRESS_FAMILY_IPV4 : ADDRESS_FAMILY_NO;
+ return 0;
+ }
+
+ a = ip_masquerade_address_family_from_string(rvalue);
+ if (a < 0) {
+ log_syntax(unit, LOG_WARNING, filename, line, a,
+ "Failed to parse IPMasquerade= setting, ignoring assignment: %s", rvalue);
+ return 0;
+ }
+
+ *ret = a;
+ return 0;
+}
+
/* Router lifetime can be set with netlink interface since kernel >= 4.5
* so for the supported kernel we don't need to expire routes in userspace */
int kernel_route_expiration_supported(void) {
diff --git a/src/network/networkd-util.h b/src/network/networkd-util.h
index e70df0528e3..01675e8b5c5 100644
--- a/src/network/networkd-util.h
+++ b/src/network/networkd-util.h
@@ -28,7 +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);
+CONFIG_PARSER_PROTOTYPE(config_parse_ip_masquerade);
const char *address_family_to_string(AddressFamily b) _const_;
AddressFamily address_family_from_string(const char *s) _pure_;