summaryrefslogtreecommitdiff
path: root/src/network
diff options
context:
space:
mode:
authorSusant Sahani <susant@redhat.com>2015-07-05 11:24:31 +0530
committerSusant Sahani <susant@redhat.com>2015-07-05 11:24:31 +0530
commit49092e22c2893118304bac1b3b706cd88f90590d (patch)
treec623efdb72fa1bcd1867a24ecf39a02a255bda70 /src/network
parent138879ccad87148cc5d805471183789a6ad688c6 (diff)
networkd: Add support for ipv6 privacy extension
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
Diffstat (limited to 'src/network')
-rw-r--r--src/network/networkd-link.c39
-rw-r--r--src/network/networkd-network-gperf.gperf131
-rw-r--r--src/network/networkd-network.c53
-rw-r--r--src/network/networkd.h17
4 files changed, 175 insertions, 65 deletions
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);