diff options
author | Lennart Poettering <lennart@poettering.net> | 2015-01-13 20:07:13 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2015-01-13 20:17:07 +0100 |
commit | 769d324c99aab129148bd25f5f663ef441287d86 (patch) | |
tree | e6d3335e4b7e59f47a248e64e17c507536ce223c /src/network | |
parent | db9fd84944807ebea04363dada761613360fa6f9 (diff) |
networkd: make IP forwarding for IPv4 and IPv6 individually configurable
Diffstat (limited to 'src/network')
-rw-r--r-- | src/network/networkd-link.c | 38 | ||||
-rw-r--r-- | src/network/networkd-manager.c | 2 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 2 | ||||
-rw-r--r-- | src/network/networkd-network.c | 6 | ||||
-rw-r--r-- | src/network/networkd.h | 13 |
5 files changed, 48 insertions, 13 deletions
diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index 1e2596749f..e4800a10de 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -88,14 +88,24 @@ static bool link_lldp_enabled(Link *link) { return link->network->lldp; } -static bool link_ip_forward_enabled(Link *link) { +static bool link_ipv4_forward_enabled(Link *link) { if (link->flags & IFF_LOOPBACK) return false; if (!link->network) return false; - return link->network->ip_forward; + return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV4, ADDRESS_FAMILY_YES); +} + +static bool link_ipv6_forward_enabled(Link *link) { + if (link->flags & IFF_LOOPBACK) + return false; + + if (!link->network) + return false; + + return IN_SET(link->network->ip_forward, ADDRESS_FAMILY_IPV6, ADDRESS_FAMILY_YES); } #define FLAG_STRING(string, flag, old, new) \ @@ -1225,14 +1235,26 @@ static int link_enter_join_netdev(Link *link) { return 0; } -static int link_set_ip_forward(Link *link) { +static int link_set_ipv4_forward(Link *link) { const char *p = NULL; int r; p = strappenda("/proc/sys/net/ipv4/conf/", link->ifname, "/forwarding"); - r = write_string_file_no_create(p, link_ip_forward_enabled(link) ? "1" : "0"); + r = write_string_file_no_create(p, one_zero(link_ipv4_forward_enabled(link))); if (r < 0) - log_link_warning_errno(link, r, "Cannot configure IP forwarding for interface: %m"); + log_link_warning_errno(link, r, "Cannot configure IPv4 forwarding for interface: %m"); + + return 0; +} + +static int link_set_ipv6_forward(Link *link) { + const char *p = NULL; + int r; + + p = strappenda("/proc/sys/net/ipv6/conf/", link->ifname, "/forwarding"); + r = write_string_file_no_create(p, one_zero(link_ipv6_forward_enabled(link))); + if (r < 0) + log_link_warning_errno(link, r, "Cannot configure IPv6 forwarding for interface: %m"); return 0; } @@ -1248,7 +1270,11 @@ static int link_configure(Link *link) { if (r < 0) return r; - r = link_set_ip_forward(link); + r = link_set_ipv4_forward(link); + if (r < 0) + return r; + + r = link_set_ipv6_forward(link); if (r < 0) return r; diff --git a/src/network/networkd-manager.c b/src/network/networkd-manager.c index 42b51137ef..4c9043486a 100644 --- a/src/network/networkd-manager.c +++ b/src/network/networkd-manager.c @@ -686,3 +686,5 @@ AddressFamilyBoolean address_family_boolean_from_string(const char *s) { return _ADDRESS_FAMILY_BOOLEAN_INVALID; } + +DEFINE_CONFIG_PARSE_ENUM(config_parse_address_family_boolean, address_family_boolean, AddressFamilyBoolean, "Failed to parse option"); diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index 3eb37b4d24..5f2f741966 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -44,7 +44,7 @@ Network.Domains, config_parse_domains, 0, Network.DNS, config_parse_strv, 0, offsetof(Network, dns) Network.LLMNR, config_parse_llmnr, 0, offsetof(Network, llmnr) Network.NTP, config_parse_strv, 0, offsetof(Network, ntp) -Network.IPForward, config_parse_bool, 0, offsetof(Network, ip_forward) +Network.IPForward, config_parse_address_family_boolean,0, offsetof(Network, ip_forward) Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) Address.Address, config_parse_address, 0, 0 Address.Peer, config_parse_address, 0, 0 diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index 98f199ad72..34a06d3f34 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -111,7 +111,7 @@ static int network_load_one(Manager *manager, const char *filename) { /* IPMasquerade=yes implies IPForward=yes */ if (network->ip_masquerade) - network->ip_forward = true; + network->ip_forward |= ADDRESS_FAMILY_IPV4; LIST_PREPEND(networks, manager->networks, network); @@ -489,6 +489,10 @@ int config_parse_dhcp( assert(rvalue); assert(data); + /* Note that this is mostly like + * config_parse_address_family_boolean(), except that it + * understands some old names for the enum values */ + s = address_family_boolean_from_string(rvalue); if (s < 0) { diff --git a/src/network/networkd.h b/src/network/networkd.h index ea4547b940..719a75b8b7 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -55,10 +55,11 @@ typedef struct AddressPool AddressPool; typedef struct FdbEntry FdbEntry; typedef enum AddressFamilyBoolean { - ADDRESS_FAMILY_NO, - ADDRESS_FAMILY_YES, - ADDRESS_FAMILY_IPV4, - ADDRESS_FAMILY_IPV6, + /* This is a bitmask, though it usually doesn't feel that way! */ + ADDRESS_FAMILY_NO = 0, + ADDRESS_FAMILY_IPV4 = 1, + ADDRESS_FAMILY_IPV6 = 2, + ADDRESS_FAMILY_YES = 3, _ADDRESS_FAMILY_BOOLEAN_MAX, _ADDRESS_FAMILY_BOOLEAN_INVALID = -1, } AddressFamilyBoolean; @@ -120,8 +121,8 @@ struct Network { unsigned cost; + AddressFamilyBoolean ip_forward; bool ip_masquerade; - bool ip_forward; struct ether_addr *mac; unsigned mtu; @@ -391,3 +392,5 @@ int address_pool_acquire(AddressPool *p, unsigned prefixlen, union in_addr_union const char *address_family_boolean_to_string(AddressFamilyBoolean b) _const_; AddressFamilyBoolean address_family_boolean_from_string(const char *s) _const_; + +int config_parse_address_family_boolean(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); |