1
0
mirror of https://github.com/systemd/systemd.git synced 2024-12-26 03:22:00 +03:00

networkd: extend IPMasquerade to cover ipv6

Extend IPMasquerade to also cover ipv6.
For compatibility reasons with earlier releases IPMasquerade=yes
is identical to IPMasquerade=ipv4.

Use IPMasquerade=both to cover ipv6 as well as ipv4.

IPForward will now also enable ipv6 forwarding if IPMasquerade for ipv6 is enabled.
This commit is contained in:
Florian Westphal 2020-12-17 05:32:42 +01:00
parent deff68e718
commit 48ed276647
8 changed files with 39 additions and 13 deletions

View File

@ -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>

View File

@ -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;
}

View File

@ -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 */

View File

@ -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)

View File

@ -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);

View File

@ -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;

View File

@ -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,

View File

@ -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_;