networkd: Add support for ipv6 privacy extension
authorSusant Sahani <susant@redhat.com>
Sun, 5 Jul 2015 05:54:31 +0000 (11:24 +0530)
committerSusant Sahani <susant@redhat.com>
Sun, 5 Jul 2015 05:54:31 +0000 (11:24 +0530)
This patch add support for ipv6 privacy extensions.

The variable  /proc/sys/net/ipv6/conf/<if>/use_tempaddr

can be changed via the boolean

IPv6PrivacyExtensions=[yes/no/prefer-temporary]

When true enables privacy extensions, but prefer public addresses over
temporary addresses.
prefer-temporary  prefers temporary adresses over public addresses.
Defaults to false.

[Match]
Name=enp0s25

[Network]
IPv6PrivacyExtensions=prefer-temporary

src/network/networkd-link.c
src/network/networkd-network-gperf.gperf
src/network/networkd-network.c
src/network/networkd.h

index dff81a5..f67a19e 100644 (file)
@@ -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)
index b05bc94..787fc2f 100644 (file)
@@ -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)
index ec95c86..ddf03e6 100644 (file)
@@ -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;
+}
index ac6e2c8..0764609 100644 (file)
@@ -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);