diff options
author | Daniel Mack <github@zonque.org> | 2015-07-05 13:08:13 -0400 |
---|---|---|
committer | Daniel Mack <github@zonque.org> | 2015-07-05 13:08:13 -0400 |
commit | b5070ab9d0956ac3482262b17b20696b0f24622f (patch) | |
tree | 7dd0f682ab653b3442902019264235af452421b4 | |
parent | 604f02add68c10232876a868c2f04b77cdcefee0 (diff) | |
parent | a521dbf43be0a0ae4f3ec0db3b65b559834e9232 (diff) |
Merge pull request #417 from ssahani/ipv6-private
Ipv6 private extensions
-rw-r--r-- | TODO | 2 | ||||
-rw-r--r-- | man/systemd.network.xml | 10 | ||||
-rw-r--r-- | src/network/networkd-link.c | 39 | ||||
-rw-r--r-- | src/network/networkd-network-gperf.gperf | 131 | ||||
-rw-r--r-- | src/network/networkd-network.c | 53 | ||||
-rw-r--r-- | src/network/networkd.h | 17 |
6 files changed, 185 insertions, 67 deletions
@@ -49,8 +49,6 @@ Features: * install: include generator dirs in unit file search paths -* networkd: add support for configuring ipv6 privacy extensions - * introduce an NSS module that uses machined info to give container UIDs pretty names when user namespacing is used. * stop using off_t, it's a crazy type. Use uint64_t instead. diff --git a/man/systemd.network.xml b/man/systemd.network.xml index 71ced09696..85867e7f66 100644 --- a/man/systemd.network.xml +++ b/man/systemd.network.xml @@ -392,6 +392,16 @@ <literal>no</literal>.</para></listitem> </varlistentry> <varlistentry> + <term><varname>IPv6PrivacyExtensions=</varname></term> + <listitem><para>Configures use of stateless temporary addresses that change over time + (see <ulink url="https://tools.ietf.org/html/rfc4941">RFC 4941</ulink>, Privacy Extensions for Stateless Address + Autoconfiguration in IPv6). A boolean or <literal>prefer-temporary</literal>. When true or <literal>prefer-public</literal> + enables privacy extensions, but prefer public addresses over temporary addresses. + <literal>prefer-temporary</literal> prefers temporary addresses over public addresses. + Defaults to + <literal>no</literal>.</para></listitem> + </varlistentry> + <varlistentry> <term><varname>Bridge=</varname></term> <listitem> <para>The name of the bridge to add the link to.</para> diff --git a/src/network/networkd-link.c b/src/network/networkd-link.c index dff81a5cf0..f67a19e50b 100644 --- a/src/network/networkd-link.c +++ b/src/network/networkd-link.c @@ -116,6 +116,19 @@ static bool link_ipv6_forward_enabled(Link *link) { return link->network->ip_forward & ADDRESS_FAMILY_IPV6; } +static bool link_ipv6_privacy_extensions_enabled(Link *link) { + if (link->flags & IFF_LOOPBACK) + return false; + + if (!link->network) + return false; + + if (link->network->ipv6_privacy_extensions == _IPV6_PRIVACY_EXTENSIONS_INVALID) + return false; + + return link->network->ipv6_privacy_extensions; +} + #define FLAG_STRING(string, flag, old, new) \ (((old ^ new) & flag) \ ? ((old & flag) ? (" -" string) : (" +" string)) \ @@ -1506,6 +1519,28 @@ static int link_set_ipv6_forward(Link *link) { return 0; } +static int link_set_ipv6_privacy_extensions(Link *link) { + char buf[2 * DECIMAL_STR_MAX(unsigned) + 1]; + const char *p = NULL; + int r; + + /* Make this a NOP if IPv6 is not available */ + if (!socket_ipv6_is_supported()) + return 0; + + if (!link_ipv6_privacy_extensions_enabled(link)) + return 0; + + p = strjoina("/proc/sys/net/ipv6/conf/", link->ifname, "/use_tempaddr"); + xsprintf(buf, "%u", link->network->ipv6_privacy_extensions); + + r = write_string_file_no_create(p, buf); + if (r < 0) + log_link_warning_errno(link, r, "Cannot configure IPv6 privacy extension for interface: %m"); + + return 0; +} + static int link_configure(Link *link) { int r; @@ -1525,6 +1560,10 @@ static int link_configure(Link *link) { if (r < 0) return r; + r = link_set_ipv6_privacy_extensions(link); + if (r < 0) + return r; + if (link_ipv4ll_enabled(link)) { r = ipv4ll_configure(link); if (r < 0) diff --git a/src/network/networkd-network-gperf.gperf b/src/network/networkd-network-gperf.gperf index b05bc949f2..787fc2ff5b 100644 --- a/src/network/networkd-network-gperf.gperf +++ b/src/network/networkd-network-gperf.gperf @@ -15,69 +15,70 @@ struct ConfigPerfItem; %struct-type %includes %% -Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) -Match.Path, config_parse_strv, 0, offsetof(Network, match_path) -Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) -Match.Type, config_parse_strv, 0, offsetof(Network, match_type) -Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) -Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) -Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) -Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) -Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) -Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) -Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) -Network.Description, config_parse_string, 0, offsetof(Network, description) -Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) -Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) -Network.VLAN, config_parse_netdev, 0, 0 -Network.MACVLAN, config_parse_netdev, 0, 0 -Network.IPVLAN, config_parse_netdev, 0, 0 -Network.VXLAN, config_parse_netdev, 0, 0 -Network.Tunnel, config_parse_tunnel, 0, 0 -Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) -Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) -Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local) -Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) -Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) -Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp) -Network.Address, config_parse_address, 0, 0 -Network.Gateway, config_parse_gateway, 0, 0 -Network.Domains, config_parse_domains, 0, offsetof(Network, domains) -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_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward) -Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) -Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) -Address.Address, config_parse_address, 0, 0 -Address.Peer, config_parse_address, 0, 0 -Address.Broadcast, config_parse_broadcast, 0, 0 -Address.Label, config_parse_label, 0, 0 -Route.Gateway, config_parse_gateway, 0, 0 -Route.Destination, config_parse_destination, 0, 0 -Route.Source, config_parse_destination, 0, 0 -Route.Metric, config_parse_route_priority, 0, 0 -Route.Scope, config_parse_route_scope, 0, 0 -DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) -DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) -DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) -DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) -DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) -DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) -DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) -DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) -Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) -BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 -BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 +Match.MACAddress, config_parse_hwaddr, 0, offsetof(Network, match_mac) +Match.Path, config_parse_strv, 0, offsetof(Network, match_path) +Match.Driver, config_parse_strv, 0, offsetof(Network, match_driver) +Match.Type, config_parse_strv, 0, offsetof(Network, match_type) +Match.Name, config_parse_ifnames, 0, offsetof(Network, match_name) +Match.Host, config_parse_net_condition, CONDITION_HOST, offsetof(Network, match_host) +Match.Virtualization, config_parse_net_condition, CONDITION_VIRTUALIZATION, offsetof(Network, match_virt) +Match.KernelCommandLine, config_parse_net_condition, CONDITION_KERNEL_COMMAND_LINE, offsetof(Network, match_kernel) +Match.Architecture, config_parse_net_condition, CONDITION_ARCHITECTURE, offsetof(Network, match_arch) +Link.MACAddress, config_parse_hwaddr, 0, offsetof(Network, mac) +Link.MTUBytes, config_parse_iec_size, 0, offsetof(Network, mtu) +Network.Description, config_parse_string, 0, offsetof(Network, description) +Network.Bridge, config_parse_netdev, 0, offsetof(Network, bridge) +Network.Bond, config_parse_netdev, 0, offsetof(Network, bond) +Network.VLAN, config_parse_netdev, 0, 0 +Network.MACVLAN, config_parse_netdev, 0, 0 +Network.IPVLAN, config_parse_netdev, 0, 0 +Network.VXLAN, config_parse_netdev, 0, 0 +Network.Tunnel, config_parse_tunnel, 0, 0 +Network.DHCP, config_parse_dhcp, 0, offsetof(Network, dhcp) +Network.DHCPServer, config_parse_bool, 0, offsetof(Network, dhcp_server) +Network.LinkLocalAddressing, config_parse_address_family_boolean, 0, offsetof(Network, link_local) +Network.IPv4LLRoute, config_parse_bool, 0, offsetof(Network, ipv4ll_route) +Network.IPv6Token, config_parse_ipv6token, 0, offsetof(Network, ipv6_token) +Network.LLDP, config_parse_bool, 0, offsetof(Network, lldp) +Network.Address, config_parse_address, 0, 0 +Network.Gateway, config_parse_gateway, 0, 0 +Network.Domains, config_parse_domains, 0, offsetof(Network, domains) +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_address_family_boolean_with_kernel,0, offsetof(Network, ip_forward) +Network.IPMasquerade, config_parse_bool, 0, offsetof(Network, ip_masquerade) +Network.IPv6PrivacyExtensions, config_parse_ipv6_privacy_extensions, 0, offsetof(Network, ipv6_privacy_extensions) +Network.BindCarrier, config_parse_strv, 0, offsetof(Network, bind_carrier) +Address.Address, config_parse_address, 0, 0 +Address.Peer, config_parse_address, 0, 0 +Address.Broadcast, config_parse_broadcast, 0, 0 +Address.Label, config_parse_label, 0, 0 +Route.Gateway, config_parse_gateway, 0, 0 +Route.Destination, config_parse_destination, 0, 0 +Route.Source, config_parse_destination, 0, 0 +Route.Metric, config_parse_route_priority, 0, 0 +Route.Scope, config_parse_route_scope, 0, 0 +DHCP.ClientIdentifier, config_parse_dhcp_client_identifier, 0, offsetof(Network, dhcp_client_identifier) +DHCP.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) +DHCP.UseNTP, config_parse_bool, 0, offsetof(Network, dhcp_ntp) +DHCP.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) +DHCP.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) +DHCP.UseDomains, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCP.UseRoutes, config_parse_bool, 0, offsetof(Network, dhcp_routes) +DHCP.SendHostname, config_parse_bool, 0, offsetof(Network, dhcp_sendhost) +DHCP.RequestBroadcast, config_parse_bool, 0, offsetof(Network, dhcp_broadcast) +DHCP.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) +DHCP.VendorClassIdentifier, config_parse_string, 0, offsetof(Network, dhcp_vendor_class_identifier) +DHCP.RouteMetric, config_parse_unsigned, 0, offsetof(Network, dhcp_route_metric) +Bridge.Cost, config_parse_unsigned, 0, offsetof(Network, cost) +BridgeFDB.MACAddress, config_parse_fdb_hwaddr, 0, 0 +BridgeFDB.VLANId, config_parse_fdb_vlan_id, 0, 0 /* backwards compatibility: do not add new entries to this section */ -Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) -DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) -DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) -DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) -DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) -DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) +Network.IPv4LL, config_parse_ipv4ll, 0, offsetof(Network, link_local) +DHCPv4.UseDNS, config_parse_bool, 0, offsetof(Network, dhcp_dns) +DHCPv4.UseMTU, config_parse_bool, 0, offsetof(Network, dhcp_mtu) +DHCPv4.UseHostname, config_parse_bool, 0, offsetof(Network, dhcp_hostname) +DHCP.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCPv4.UseDomainName, config_parse_bool, 0, offsetof(Network, dhcp_domains) +DHCPv4.CriticalConnection, config_parse_bool, 0, offsetof(Network, dhcp_critical) diff --git a/src/network/networkd-network.c b/src/network/networkd-network.c index ec95c8661e..ddf03e67f9 100644 --- a/src/network/networkd-network.c +++ b/src/network/networkd-network.c @@ -111,6 +111,8 @@ static int network_load_one(Manager *manager, const char *filename) { network->link_local = ADDRESS_FAMILY_IPV6; + network->ipv6_privacy_extensions = _IPV6_PRIVACY_EXTENSIONS_INVALID; + r = config_parse(NULL, filename, file, "Match\0" "Link\0" @@ -751,3 +753,54 @@ int config_parse_address_family_boolean_with_kernel( return 0; } + +static const char* const ipv6_privacy_extensions_table[_IPV6_PRIVACY_EXTENSIONS_MAX] = { + [IPV6_PRIVACY_EXTENSIONS_DISABLE] = "no", + [IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC] = "yes", + [IPV6_PRIVACY_EXTENSIONS_PREFER_TEMPORARY] = "prefer-temporary", +}; + +DEFINE_STRING_TABLE_LOOKUP(ipv6_privacy_extensions, IPv6PrivacyExtensions); + +int config_parse_ipv6_privacy_extensions( + 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) { + + IPv6PrivacyExtensions *ipv6_privacy_extensions = data; + int k; + + assert(filename); + assert(lvalue); + assert(rvalue); + assert(ipv6_privacy_extensions); + + /* Our enum shall be a superset of booleans, hence first try + * to parse as boolean, and then as enum */ + + k = parse_boolean(rvalue); + if (k > 0) + *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC; + else if (k == 0) + *ipv6_privacy_extensions = IPV6_PRIVACY_EXTENSIONS_DISABLE; + else { + IPv6PrivacyExtensions s; + + s = ipv6_privacy_extensions_from_string(rvalue); + if (s < 0){ + log_syntax(unit, LOG_ERR, filename, line, -s, "Failed to parse IPv6 privacy extensions option, ignoring: %s", rvalue); + return 0; + } + + *ipv6_privacy_extensions = s; + } + + return 0; +} diff --git a/src/network/networkd.h b/src/network/networkd.h index ac6e2c8a8e..0764609daa 100644 --- a/src/network/networkd.h +++ b/src/network/networkd.h @@ -90,6 +90,14 @@ typedef enum DCHPClientIdentifier { _DHCP_CLIENT_ID_INVALID = -1, } DCHPClientIdentifier; +typedef enum IPv6PrivacyExtensions { + IPV6_PRIVACY_EXTENSIONS_DISABLE, + IPV6_PRIVACY_EXTENSIONS_PREFER_PUBLIC, + IPV6_PRIVACY_EXTENSIONS_PREFER_TEMPORARY, + _IPV6_PRIVACY_EXTENSIONS_MAX, + _IPV6_PRIVACY_EXTENSIONS_INVALID = -1, +} IPv6PrivacyExtensions; + struct FdbEntry { Network *network; unsigned section; @@ -145,6 +153,8 @@ struct Network { AddressFamilyBoolean ip_forward; bool ip_masquerade; + IPv6PrivacyExtensions ipv6_privacy_extensions; + struct ether_addr *mac; unsigned mtu; @@ -455,3 +465,10 @@ int config_parse_address_family_boolean_with_kernel(const char *unit, const char const char* link_operstate_to_string(LinkOperationalState s) _const_; LinkOperationalState link_operstate_from_string(const char *s) _pure_; + +/* Ipv6 privacy extensions support */ + +const char* ipv6_privacy_extensions_to_string(IPv6PrivacyExtensions i) _const_; +IPv6PrivacyExtensions ipv6_privacy_extensions_from_string(const char *s) _pure_; + +int config_parse_ipv6_privacy_extensions(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); |