diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-05-30 16:40:41 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-05-30 16:40:41 +0200 |
commit | 2edaf35f1296b4b8f140365b4b40d5d89e57128a (patch) | |
tree | 33baf5059104b891cb9895ed1abbe303f6690d87 | |
parent | 28938155e0133ae31c2f8b498d9b985160ca3ab4 (diff) | |
parent | 6fd1bf07499cea02de050f3d3906547090f4589d (diff) | |
download | NetworkManager-2edaf35f1296b4b8f140365b4b40d5d89e57128a.tar.gz |
merge: branch 'lr/connection-token'
https://bugzilla.gnome.org/show_bug.cgi?id=765851
-rw-r--r-- | clients/cli/settings.c | 13 | ||||
-rw-r--r-- | libnm-core/nm-connection.c | 27 | ||||
-rw-r--r-- | libnm-core/nm-core-internal.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip6-config.c | 104 | ||||
-rw-r--r-- | libnm-core/nm-setting-ip6-config.h | 4 | ||||
-rw-r--r-- | libnm-core/nm-utils.c | 34 | ||||
-rw-r--r-- | libnm-glib/nm-vpn-plugin.c | 2 | ||||
-rw-r--r-- | libnm-util/nm-setting.c | 2 | ||||
-rw-r--r-- | src/devices/nm-device.c | 108 | ||||
-rw-r--r-- | src/dhcp-manager/nm-dhcp-client.c | 2 | ||||
-rw-r--r-- | src/nm-core-utils.c | 76 | ||||
-rw-r--r-- | src/nm-core-utils.h | 18 | ||||
-rw-r--r-- | src/platform/nm-linux-platform.c | 83 | ||||
-rw-r--r-- | src/platform/nm-platform.c | 32 | ||||
-rw-r--r-- | src/platform/nm-platform.h | 10 | ||||
-rw-r--r-- | src/ppp-manager/nm-ppp-manager.c | 2 | ||||
-rw-r--r-- | src/rdisc/nm-rdisc.c | 2 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/reader.c | 7 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 6 |
19 files changed, 437 insertions, 99 deletions
diff --git a/clients/cli/settings.c b/clients/cli/settings.c index f2a504cc5c..0f75d2a791 100644 --- a/clients/cli/settings.c +++ b/clients/cli/settings.c @@ -330,6 +330,7 @@ NmcOutputField nmc_fields_setting_ip6_config[] = { SETTING_FIELD (NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE), /* 15 */ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME), /* 16 */ SETTING_FIELD (NM_SETTING_IP_CONFIG_DHCP_HOSTNAME), /* 17 */ + SETTING_FIELD (NM_SETTING_IP6_CONFIG_TOKEN), /* 18 */ {NULL, NULL, 0, NULL, FALSE, FALSE, 0} }; #define NMC_FIELDS_SETTING_IP6_CONFIG_ALL "name"","\ @@ -349,7 +350,8 @@ NmcOutputField nmc_fields_setting_ip6_config[] = { NM_SETTING_IP6_CONFIG_IP6_PRIVACY","\ NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE","\ NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME","\ - NM_SETTING_IP_CONFIG_DHCP_HOSTNAME + NM_SETTING_IP_CONFIG_DHCP_HOSTNAME","\ + NM_SETTING_IP6_CONFIG_TOKEN /* Available fields for NM_SETTING_SERIAL_SETTING_NAME */ NmcOutputField nmc_fields_setting_serial[] = { @@ -1629,6 +1631,7 @@ DEFINE_GETTER (nmc_property_ipv6_get_never_default, NM_SETTING_IP_CONFIG_NEVER_D DEFINE_GETTER (nmc_property_ipv6_get_may_fail, NM_SETTING_IP_CONFIG_MAY_FAIL) DEFINE_GETTER (nmc_property_ipv6_get_dhcp_send_hostname, NM_SETTING_IP_CONFIG_DHCP_SEND_HOSTNAME) DEFINE_GETTER (nmc_property_ipv6_get_dhcp_hostname, NM_SETTING_IP_CONFIG_DHCP_HOSTNAME) +DEFINE_GETTER (nmc_property_ipv6_get_token, NM_SETTING_IP6_CONFIG_TOKEN) static char * nmc_property_ipv6_get_ip6_privacy (NMSetting *setting, NmcPropertyGetType get_type) @@ -6728,6 +6731,13 @@ nmc_properties_init (void) NULL, NULL, NULL); + nmc_add_prop_funcs (GLUE (IP6_CONFIG, TOKEN), + nmc_property_ipv6_get_token, + nmc_property_set_string, + NULL, + NULL, + NULL, + NULL); /* Add editable properties for NM_SETTING_OLPC_MESH_SETTING_NAME */ nmc_add_prop_funcs (GLUE (OLPC_MESH, SSID), @@ -8256,6 +8266,7 @@ setting_ip6_config_details (NMSetting *setting, NmCli *nmc, const char *one_pro set_val_str (arr, 15, nmc_property_ipv6_get_addr_gen_mode (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 16, nmc_property_ipv6_get_dhcp_send_hostname (setting, NMC_PROPERTY_GET_PRETTY)); set_val_str (arr, 17, nmc_property_ipv6_get_dhcp_hostname (setting, NMC_PROPERTY_GET_PRETTY)); + set_val_str (arr, 18, nmc_property_ipv6_get_token (setting, NMC_PROPERTY_GET_PRETTY)); g_ptr_array_add (nmc->output_data, arr); print_data (nmc); /* Print all data */ diff --git a/libnm-core/nm-connection.c b/libnm-core/nm-connection.c index b2c4d4eea0..a823af9bea 100644 --- a/libnm-core/nm-connection.c +++ b/libnm-core/nm-connection.c @@ -23,6 +23,7 @@ #include "nm-default.h" #include <string.h> +#include <arpa/inet.h> #include "nm-connection.h" #include "nm-connection-private.h" @@ -724,7 +725,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) const char *default_ip6_method = NULL; NMSettingIPConfig *s_ip4, *s_ip6; NMSetting *setting; - gboolean gateway_removed = FALSE; + gboolean changed = FALSE; if (parameters) default_ip6_method = g_hash_table_lookup (parameters, NM_CONNECTION_NORMALIZE_PARAM_IP6_CONFIG_METHOD); @@ -761,7 +762,7 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) if ( nm_setting_ip_config_get_gateway (s_ip4) && nm_setting_ip_config_get_never_default (s_ip4)) { g_object_set (s_ip4, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); - gateway_removed = TRUE; + changed = TRUE; } } if (!s_ip6) { @@ -773,13 +774,31 @@ _normalize_ip_config (NMConnection *self, GHashTable *parameters) NULL); nm_connection_add_setting (self, setting); } else { + const char *token; + + token = nm_setting_ip6_config_get_token ((NMSettingIP6Config *) s_ip6); + if ( token + && nm_setting_ip6_config_get_addr_gen_mode ((NMSettingIP6Config *) s_ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { + struct in6_addr i6_token; + char normalized[NM_UTILS_INET_ADDRSTRLEN]; + + if ( inet_pton (AF_INET6, token, &i6_token) == 1 + && _nm_utils_inet6_is_token (&i6_token)) { + nm_utils_inet6_ntop (&i6_token, normalized); + if (g_strcmp0 (token, normalized)) { + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, normalized, NULL); + changed = TRUE; + } + } + } + if ( nm_setting_ip_config_get_gateway (s_ip6) && nm_setting_ip_config_get_never_default (s_ip6)) { g_object_set (s_ip6, NM_SETTING_IP_CONFIG_GATEWAY, NULL, NULL); - gateway_removed = TRUE; + changed = TRUE; } } - return !s_ip4 || !s_ip6 || gateway_removed; + return !s_ip4 || !s_ip6 || changed; } } diff --git a/libnm-core/nm-core-internal.h b/libnm-core/nm-core-internal.h index 2041a1d3a1..a09ee26c48 100644 --- a/libnm-core/nm-core-internal.h +++ b/libnm-core/nm-core-internal.h @@ -296,4 +296,8 @@ typedef enum { NMBondOptionType _nm_setting_bond_get_option_type (NMSettingBond *setting, const char *name); +/***********************************************************/ + +gboolean _nm_utils_inet6_is_token (const struct in6_addr *in6addr); + #endif diff --git a/libnm-core/nm-setting-ip6-config.c b/libnm-core/nm-setting-ip6-config.c index f583255382..a5826eb3b1 100644 --- a/libnm-core/nm-setting-ip6-config.c +++ b/libnm-core/nm-setting-ip6-config.c @@ -24,6 +24,7 @@ #include "nm-setting-ip6-config.h" #include <string.h> +#include <arpa/inet.h> #include "nm-setting-private.h" #include "nm-core-enum-types.h" @@ -59,6 +60,7 @@ NM_SETTING_REGISTER_TYPE (NM_TYPE_SETTING_IP6_CONFIG) typedef struct { NMSettingIP6ConfigPrivacy ip6_privacy; NMSettingIP6ConfigAddrGenMode addr_gen_mode; + char *token; } NMSettingIP6ConfigPrivate; @@ -66,6 +68,7 @@ enum { PROP_0, PROP_IP6_PRIVACY, PROP_ADDR_GEN_MODE, + PROP_TOKEN, LAST_PROP }; @@ -120,6 +123,25 @@ nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting) return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->addr_gen_mode; } +/** + * nm_setting_ip6_config_get_token: + * @setting: the #NMSettingIP6Config + * + * Returns the value contained in the #NMSettingIP6Config:token + * property. + * + * Returns: A string. + * + * Since: 1.4 + **/ +const char * +nm_setting_ip6_config_get_token (NMSettingIP6Config *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_IP6_CONFIG (setting), NULL); + + return NM_SETTING_IP6_CONFIG_GET_PRIVATE (setting)->token; +} + static gboolean verify (NMSetting *setting, NMConnection *connection, GError **error) { @@ -127,6 +149,7 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) NMSettingIPConfig *s_ip = NM_SETTING_IP_CONFIG (setting); NMSettingVerifyResult ret; const char *method; + gboolean token_needs_normalization = FALSE; ret = NM_SETTING_CLASS (nm_setting_ip6_config_parent_class)->verify (setting, connection, error); if (ret != NM_SETTING_VERIFY_SUCCESS) @@ -201,6 +224,44 @@ verify (NMSetting *setting, NMConnection *connection, GError **error) return FALSE; } + if (priv->token) { + if (priv->addr_gen_mode == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) { + struct in6_addr i6_token; + char s_token[NM_UTILS_INET_ADDRSTRLEN]; + + if ( inet_pton (AF_INET6, priv->token, &i6_token) != 1 + || !_nm_utils_inet6_is_token (&i6_token)) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("value is not a valid token")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN); + return FALSE; + } + + if (g_strcmp0 (priv->token, nm_utils_inet6_ntop (&i6_token, s_token))) + token_needs_normalization = TRUE; + } else { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("only makes sense with EUI64 address generation mode")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN); + return FALSE; + } + } + + /* Failures from here on, are NORMALIZABLE_ERROR... */ + + if (token_needs_normalization) { + g_set_error_literal (error, + NM_CONNECTION_ERROR, + NM_CONNECTION_ERROR_INVALID_PROPERTY, + _("token is not in canonical form")); + g_prefix_error (error, "%s.%s: ", NM_SETTING_IP6_CONFIG_SETTING_NAME, NM_SETTING_IP6_CONFIG_TOKEN); + return NM_SETTING_VERIFY_NORMALIZABLE_ERROR; + } + return TRUE; } @@ -388,6 +449,10 @@ set_property (GObject *object, guint prop_id, case PROP_ADDR_GEN_MODE: priv->addr_gen_mode = g_value_get_int (value); break; + case PROP_TOKEN: + g_free (priv->token); + priv->token = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -407,6 +472,9 @@ get_property (GObject *object, guint prop_id, case PROP_ADDR_GEN_MODE: g_value_set_int (value, priv->addr_gen_mode); break; + case PROP_TOKEN: + g_value_set_string (value, priv->token); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -414,6 +482,17 @@ get_property (GObject *object, guint prop_id, } static void +finalize (GObject *object) +{ + NMSettingIP6Config *self = NM_SETTING_IP6_CONFIG (object); + NMSettingIP6ConfigPrivate *priv = NM_SETTING_IP6_CONFIG_GET_PRIVATE (self); + + g_free (priv->token); + + G_OBJECT_CLASS (nm_setting_ip6_config_parent_class)->finalize (object); +} + +static void nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) { GObjectClass *object_class = G_OBJECT_CLASS (ip6_class); @@ -424,6 +503,7 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) /* virtual methods */ object_class->set_property = set_property; object_class->get_property = get_property; + object_class->finalize = finalize; setting_class->verify = verify; /* Properties */ @@ -656,6 +736,30 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *ip6_class) G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS)); + /** + * NMSettingIP6Config:token: + * + * Configure the token for draft-chown-6man-tokenised-ipv6-identifiers-02 + * IPv6 tokenized interface identifiers. Useful with eui64 addr-gen-mode. + * + * Since: 1.4 + **/ + /* ---ifcfg-rh--- + * property: token + * variable: IPV6_TOKEN + * description: The IPv6 tokenized interface identifier token + * example: IPV6_TOKEN=::53 + * ---end--- + */ + g_object_class_install_property + (object_class, PROP_TOKEN, + g_param_spec_string (NM_SETTING_IP6_CONFIG_TOKEN, "", "", + NULL, + G_PARAM_READWRITE | + NM_SETTING_PARAM_INFERRABLE | + G_PARAM_STATIC_STRINGS)); + + /* IP6-specific property overrides */ /* ---dbus--- diff --git a/libnm-core/nm-setting-ip6-config.h b/libnm-core/nm-setting-ip6-config.h index 2966e558cb..3b29aaa226 100644 --- a/libnm-core/nm-setting-ip6-config.h +++ b/libnm-core/nm-setting-ip6-config.h @@ -43,6 +43,8 @@ G_BEGIN_DECLS #define NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE "addr-gen-mode" +#define NM_SETTING_IP6_CONFIG_TOKEN "token" + /** * NM_SETTING_IP6_CONFIG_METHOD_IGNORE: * @@ -156,6 +158,8 @@ NMSetting *nm_setting_ip6_config_new (void); NMSettingIP6ConfigPrivacy nm_setting_ip6_config_get_ip6_privacy (NMSettingIP6Config *setting); NM_AVAILABLE_IN_1_2 NMSettingIP6ConfigAddrGenMode nm_setting_ip6_config_get_addr_gen_mode (NMSettingIP6Config *setting); +NM_AVAILABLE_IN_1_4 +const char *nm_setting_ip6_config_get_token (NMSettingIP6Config *setting); G_END_DECLS diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c index 81676e9f1f..7a87dc18c4 100644 --- a/libnm-core/nm-utils.c +++ b/libnm-core/nm-utils.c @@ -3566,6 +3566,40 @@ nm_utils_ipaddr_valid (int family, const char *ip) } /** + * nm_utils_iinet6_is_token: + * @in6addr: the AF_INET6 address structure + * + * Checks if only the bottom 64bits of the address are set. + * + * Return value: %TRUE or %FALSE + */ +gboolean +_nm_utils_inet6_is_token (const struct in6_addr *in6addr) +{ + if ( in6addr->s6_addr[0] + || in6addr->s6_addr[1] + || in6addr->s6_addr[2] + || in6addr->s6_addr[3] + || in6addr->s6_addr[4] + || in6addr->s6_addr[5] + || in6addr->s6_addr[6] + || in6addr->s6_addr[7]) + return FALSE; + + if ( in6addr->s6_addr[8] + || in6addr->s6_addr[9] + || in6addr->s6_addr[10] + || in6addr->s6_addr[11] + || in6addr->s6_addr[12] + || in6addr->s6_addr[13] + || in6addr->s6_addr[14] + || in6addr->s6_addr[15]) + return TRUE; + + return FALSE; +} + +/** * nm_utils_check_virtual_device_compatibility: * @virtual_type: a virtual connection type * @other_type: a connection type to test against @virtual_type diff --git a/libnm-glib/nm-vpn-plugin.c b/libnm-glib/nm-vpn-plugin.c index 2af9deb4bd..0534b766e8 100644 --- a/libnm-glib/nm-vpn-plugin.c +++ b/libnm-glib/nm-vpn-plugin.c @@ -800,7 +800,7 @@ set_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_DBUS_SERVICE_NAME: /* Construct-only */ - priv->dbus_service_name = g_strdup (g_value_get_string (value)); + priv->dbus_service_name = g_value_dup_string (value); break; case PROP_STATE: nm_vpn_plugin_set_state (NM_VPN_PLUGIN (object), diff --git a/libnm-util/nm-setting.c b/libnm-util/nm-setting.c index 990d6fe73b..c0d82b4263 100644 --- a/libnm-util/nm-setting.c +++ b/libnm-util/nm-setting.c @@ -1403,7 +1403,7 @@ _nm_setting_verify_deprecated_virtual_iface_name (const char *interface_name, e_invalid_property, _("property is invalid")); g_prefix_error (error, "%s.%s: ", setting_name, setting_property); - /* we would like to make this a NORMALIZEABLE_ERROR, but that might + /* we would like to make this a NORMALIZABLE_ERROR, but that might * break older connections. */ return NM_SETTING_VERIFY_NORMALIZABLE; } diff --git a/src/devices/nm-device.c b/src/devices/nm-device.c index dfbf3ebbc8..5234d24cdd 100644 --- a/src/devices/nm-device.c +++ b/src/devices/nm-device.c @@ -735,39 +735,72 @@ static gboolean get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *out_iid) { NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMLinkType link_type; - const guint8 *hwaddr = NULL; - size_t hwaddr_len = 0; + const NMPlatformLink *pllink; int ifindex; gboolean success; /* If we get here, we *must* have a kernel netdev, which implies an ifindex */ ifindex = nm_device_get_ip_ifindex (self); - g_assert (ifindex); + g_return_val_if_fail (ifindex > 0, FALSE); - link_type = nm_platform_link_get_type (NM_PLATFORM_GET, ifindex); - g_return_val_if_fail (link_type > NM_LINK_TYPE_UNKNOWN, 0); + pllink = nm_platform_link_get (NM_PLATFORM_GET, ifindex); + if ( !pllink + || NM_IN_SET (pllink->type, NM_LINK_TYPE_NONE, NM_LINK_TYPE_UNKNOWN)) + return FALSE; - hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len); - if (!hwaddr_len) + if (pllink->addr.len <= 0) return FALSE; + if (pllink->addr.len > NM_UTILS_HWADDR_LEN_MAX) + g_return_val_if_reached (FALSE); - success = nm_utils_get_ipv6_interface_identifier (link_type, - hwaddr, - hwaddr_len, + success = nm_utils_get_ipv6_interface_identifier (pllink->type, + pllink->addr.data, + pllink->addr.len, priv->dev_id, out_iid); if (!success) { _LOGW (LOGD_HW, "failed to generate interface identifier " - "for link type %u hwaddr_len %zu", link_type, hwaddr_len); + "for link type %u hwaddr_len %u", pllink->type, (unsigned) pllink->addr.len); } return success; } +/** + * nm_device_get_ip_iface_identifier: + * @self: an #NMDevice + * @iid: where to place the interface identifier + * @ignore_token: force creation of a non-tokenized address + * + * Return the interface's identifier for the EUI64 address generation mode. + * It's either a manually set token or and identifier generated in a + * hardware-specific way. + * + * Unless @ignore_token is set the token is preferred. That is the case + * for link-local addresses (to mimic kernel behavior). + * + * Returns: #TRUE if the @iid could be set + */ static gboolean -nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid) +nm_device_get_ip_iface_identifier (NMDevice *self, NMUtilsIPv6IfaceId *iid, gboolean ignore_token) { - return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); + NMSettingIP6Config *s_ip6; + const char *token = NULL; + NMConnection *connection; + + g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); + + connection = nm_device_get_applied_connection (self); + nm_assert (connection); + + s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting_ip6_config (connection)); + nm_assert (s_ip6); + + if (!ignore_token) + token = nm_setting_ip6_config_get_token (s_ip6); + if (token) + return nm_utils_ipv6_interface_identifier_get_from_token (iid, token); + else + return NM_DEVICE_GET_CLASS (self)->get_ip_iface_identifier (self, iid); } const char * @@ -1606,7 +1639,6 @@ device_link_changed (NMDevice *self) { NMDeviceClass *klass = NM_DEVICE_GET_CLASS (self); NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); - NMUtilsIPv6IfaceId token_iid; gboolean ip_ifname_changed = FALSE; const char *udi; NMPlatformLink info; @@ -1678,10 +1710,11 @@ device_link_changed (NMDevice *self) nm_device_emit_recheck_auto_activate (self); } - if (priv->rdisc && nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &token_iid)) { - _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); - if (nm_rdisc_set_iid (priv->rdisc, token_iid)) + if (priv->rdisc && info.inet6_token.id) { + if (nm_rdisc_set_iid (priv->rdisc, info.inet6_token)) { + _LOGD (LOGD_DEVICE, "IPv6 tokenized identifier present on device %s", priv->iface); nm_rdisc_start (priv->rdisc); + } } if (klass->link_changed) @@ -3061,6 +3094,7 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) gs_free char *uuid = NULL; const char *ip4_method, *ip6_method; GError *error = NULL; + const NMPlatformLink *pllink; /* If update_connection() is not implemented, just fail. */ if (!klass->update_connection) @@ -3107,6 +3141,15 @@ nm_device_generate_connection (NMDevice *self, NMDevice *master) s_ip6 = nm_ip6_config_create_setting (priv->ip6_config); nm_connection_add_setting (connection, s_ip6); + + pllink = nm_platform_link_get (NM_PLATFORM_GET, priv->ifindex); + if (pllink && pllink->inet6_token.id) { + _LOGD (LOGD_IP6, "IPv6 tokenized identifier present"); + g_object_set (s_ip6, + NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE, NM_IN6_ADDR_GEN_MODE_EUI64, + NM_SETTING_IP6_CONFIG_TOKEN, nm_utils_inet6_interface_identifier_to_token (pllink->inet6_token, NULL), + NULL); + } } klass->update_connection (self, connection); @@ -5194,6 +5237,7 @@ ip6_config_merge_and_apply (NMDevice *self, gboolean ignore_auto_routes = FALSE; gboolean ignore_auto_dns = FALSE; gboolean auto_method = FALSE; + const char *token = NULL; /* Apply ignore-auto-routes and ignore-auto-dns settings */ connection = nm_device_get_applied_connection (self); @@ -5201,9 +5245,14 @@ ip6_config_merge_and_apply (NMDevice *self, NMSettingIPConfig *s_ip6 = nm_connection_get_setting_ip6_config (connection); if (s_ip6) { + NMSettingIP6Config *ip6 = NM_SETTING_IP6_CONFIG (s_ip6); + ignore_auto_routes = nm_setting_ip_config_get_ignore_auto_routes (s_ip6); ignore_auto_dns = nm_setting_ip_config_get_ignore_auto_dns (s_ip6); + if (nm_setting_ip6_config_get_addr_gen_mode (ip6) == NM_SETTING_IP6_CONFIG_ADDR_GEN_MODE_EUI64) + token = nm_setting_ip6_config_get_token (ip6); + if (NM_IN_STRSET (nm_setting_ip_config_get_method (s_ip6), NM_SETTING_IP6_CONFIG_METHOD_AUTO, NM_SETTING_IP6_CONFIG_METHOD_DHCP)) @@ -5351,6 +5400,14 @@ END_ADD_DEFAULT_ROUTE: /* Allow setting MTU etc */ if (commit) { + NMUtilsIPv6IfaceId iid; + + if (token && nm_utils_ipv6_interface_identifier_get_from_token (&iid, token)) { + nm_platform_link_set_ipv6_token (NM_PLATFORM_GET, + nm_device_get_ip_ifindex (self), + iid); + } + if (NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit) NM_DEVICE_GET_CLASS (self)->ip6_config_pre_commit (self, composite); } @@ -5823,13 +5880,13 @@ check_and_add_ipv6ll_addr (NMDevice *self) return; } - if (!nm_device_get_ip_iface_identifier (self, &iid)) { + if (!nm_device_get_ip_iface_identifier (self, &iid, TRUE)) { _LOGW (LOGD_IP6, "linklocal6: failed to get interface identifier; IPv6 cannot continue"); return; } _LOGD (LOGD_IP6, "linklocal6: using EUI-64 identifier to generate IPv6LL address"); - nm_utils_ipv6_addr_set_interface_identfier (&lladdr, iid); + nm_utils_ipv6_addr_set_interface_identifier (&lladdr, iid); } _LOGD (LOGD_IP6, "linklocal6: adding IPv6LL address %s", nm_utils_inet6_ntop (&lladdr, NULL)); @@ -6108,10 +6165,7 @@ addrconf6_start_with_link_ready (NMDevice *self) g_assert (priv->rdisc); - if (nm_platform_link_get_ipv6_token (NM_PLATFORM_GET, priv->ifindex, &iid)) { - _LOGD (LOGD_IP6, "addrconf6: IPv6 tokenized identifier present"); - nm_rdisc_set_iid (priv->rdisc, iid); - } else if (nm_device_get_ip_iface_identifier (self, &iid)) { + if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { _LOGD (LOGD_IP6, "addrconf6: using the device EUI-64 identifier"); nm_rdisc_set_iid (priv->rdisc, iid); } else { @@ -10658,7 +10712,7 @@ nm_device_spawn_iface_helper (NMDevice *self) g_ptr_array_add (argv, g_strdup ("--slaac-tempaddr")); g_ptr_array_add (argv, g_strdup_printf ("%d", priv->rdisc_use_tempaddr)); - if (nm_device_get_ip_iface_identifier (self, &iid)) { + if (nm_device_get_ip_iface_identifier (self, &iid, FALSE)) { g_ptr_array_add (argv, g_strdup ("--iid")); hex_iid = bin2hexstr ((const char *) iid.id_u8, sizeof (NMUtilsIPv6IfaceId)); g_ptr_array_add (argv, hex_iid); @@ -11693,11 +11747,11 @@ set_property (GObject *object, guint prop_id, break; case PROP_DRIVER_VERSION: g_free (priv->driver_version); - priv->driver_version = g_strdup (g_value_get_string (value)); + priv->driver_version = g_value_dup_string (value); break; case PROP_FIRMWARE_VERSION: g_free (priv->firmware_version); - priv->firmware_version = g_strdup (g_value_get_string (value)); + priv->firmware_version = g_value_dup_string (value); break; case PROP_MTU: priv->mtu = g_value_get_uint (value); diff --git a/src/dhcp-manager/nm-dhcp-client.c b/src/dhcp-manager/nm-dhcp-client.c index 3490c0d235..9f66c93144 100644 --- a/src/dhcp-manager/nm-dhcp-client.c +++ b/src/dhcp-manager/nm-dhcp-client.c @@ -834,7 +834,7 @@ set_property (GObject *object, guint prop_id, switch (prop_id) { case PROP_IFACE: /* construct-only */ - priv->iface = g_strdup (g_value_get_string (value)); + priv->iface = g_value_dup_string (value); break; case PROP_IFINDEX: /* construct-only */ diff --git a/src/nm-core-utils.c b/src/nm-core-utils.c index 40081677df..276dc1c406 100644 --- a/src/nm-core-utils.c +++ b/src/nm-core-utils.c @@ -2866,20 +2866,92 @@ nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, } return FALSE; } + +/*****************************************************************************/ + +/** + * nm_utils_ipv6_addr_set_interface_identifier: + * @addr: output token encoded as %in6_addr + * @iid: %NMUtilsIPv6IfaceId interface identifier + * + * Converts the %NMUtilsIPv6IfaceId to an %in6_addr (suitable for use + * with Linux platform). This only copies the lower 8 bytes, ignoring + * the /64 network prefix which is expected to be all-zero for a valid + * token. + */ void -nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, +nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr, const NMUtilsIPv6IfaceId iid) { memcpy (addr->s6_addr + 8, &iid.id_u8, 8); } +/** + * nm_utils_ipv6_interface_identifier_get_from_addr: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @addr: token encoded as %in6_addr + * + * Converts the %in6_addr encoded token (as used by Linux platform) to + * the interface identifier. + */ void -nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, +nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid, const struct in6_addr *addr) { memcpy (iid, addr->s6_addr + 8, 8); } +/** + * nm_utils_ipv6_interface_identifier_get_from_token: + * @iid: output %NMUtilsIPv6IfaceId interface identifier set from the token + * @token: token encoded as string + * + * Converts the %in6_addr encoded token (as used in ip6 settings) to + * the interface identifier. + * + * Returns: %TRUE if the @token is a valid token, %FALSE otherwise + */ +gboolean +nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid, + const char *token) +{ + struct in6_addr i6_token; + + g_return_val_if_fail (token, FALSE); + + if (!inet_pton (AF_INET6, token, &i6_token)) + return FALSE; + + if (!_nm_utils_inet6_is_token (&i6_token)) + return FALSE; + + nm_utils_ipv6_interface_identifier_get_from_addr (iid, &i6_token); + return TRUE; +} + +/** + * nm_utils_inet6_interface_identifier_to_token: + * @iid: %NMUtilsIPv6IfaceId interface identifier + * @buf: the destination buffer or %NULL + * + * Converts the interface identifier to a string token. + * If the destination buffer it set, set it is used to store the + * resulting token, otherwise an internal static buffer is used. + * The buffer needs to be %NM_UTILS_INET_ADDRSTRLEN characters long. + * + * Returns: a statically allocated array. Do not g_free(). + */ +const char * +nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, char *buf) +{ + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, iid); + return nm_utils_inet6_ntop (&i6_token, buf); +} + +/*****************************************************************************/ + static gboolean _set_stable_privacy (struct in6_addr *addr, const char *ifname, diff --git a/src/nm-core-utils.h b/src/nm-core-utils.h index 7a0f909bc4..a203a8ef71 100644 --- a/src/nm-core-utils.h +++ b/src/nm-core-utils.h @@ -335,24 +335,30 @@ struct _NMUtilsIPv6IfaceId { #define NM_UTILS_IPV6_IFACE_ID_INIT { { .id = 0 } } +void nm_utils_ipv6_addr_set_interface_identifier (struct in6_addr *addr, + const NMUtilsIPv6IfaceId iid); + +void nm_utils_ipv6_interface_identifier_get_from_addr (NMUtilsIPv6IfaceId *iid, + const struct in6_addr *addr); + +gboolean nm_utils_ipv6_interface_identifier_get_from_token (NMUtilsIPv6IfaceId *iid, + const char *token); + +const char *nm_utils_inet6_interface_identifier_to_token (NMUtilsIPv6IfaceId iid, + char *buf); + gboolean nm_utils_get_ipv6_interface_identifier (NMLinkType link_type, const guint8 *hwaddr, guint len, guint dev_id, NMUtilsIPv6IfaceId *out_iid); -void nm_utils_ipv6_addr_set_interface_identfier (struct in6_addr *addr, - const NMUtilsIPv6IfaceId iid); - gboolean nm_utils_ipv6_addr_set_stable_privacy (struct in6_addr *addr, const char *ifname, const char *uuid, guint dad_counter, GError **error); -void nm_utils_ipv6_interface_identfier_get_from_addr (NMUtilsIPv6IfaceId *iid, - const struct in6_addr *addr); - void nm_utils_array_remove_at_indexes (GArray *array, const guint *indexes_to_delete, gsize len); void nm_utils_setpgid (gpointer unused); diff --git a/src/platform/nm-linux-platform.c b/src/platform/nm-linux-platform.c index 2c20d77c57..4e41bc9b27 100644 --- a/src/platform/nm-linux-platform.c +++ b/src/platform/nm-linux-platform.c @@ -798,9 +798,10 @@ _nl_nlmsg_type_to_str (guint16 type, char *buf, gsize len) static gboolean _parse_af_inet6 (NMPlatform *platform, struct nlattr *attr, - NMUtilsIPv6IfaceId *out_iid, - guint8 *out_iid_is_valid, - guint8 *out_addr_gen_mode_inv) + NMUtilsIPv6IfaceId *out_token, + gboolean *out_token_valid, + guint8 *out_addr_gen_mode_inv, + gboolean *out_addr_gen_mode_valid) { static struct nla_policy policy[IFLA_INET6_MAX+1] = { [IFLA_INET6_FLAGS] = { .type = NLA_U32 }, @@ -814,7 +815,8 @@ _parse_af_inet6 (NMPlatform *platform, struct nlattr *tb[IFLA_INET6_MAX+1]; int err; struct in6_addr i6_token; - gboolean iid_is_valid = FALSE; + gboolean token_valid = FALSE; + gboolean addr_gen_mode_valid = FALSE; guint8 i6_addr_gen_mode_inv = 0; gboolean success = FALSE; @@ -831,8 +833,7 @@ _parse_af_inet6 (NMPlatform *platform, if (_check_addr_or_errout (tb, IFLA_INET6_TOKEN, sizeof (struct in6_addr))) { nla_memcpy (&i6_token, tb[IFLA_INET6_TOKEN], sizeof (struct in6_addr)); - if (!IN6_IS_ADDR_UNSPECIFIED (&i6_token)) - iid_is_valid = TRUE; + token_valid = TRUE; } /* Hack to detect support addrgenmode of the kernel. We only parse @@ -847,21 +848,18 @@ _parse_af_inet6 (NMPlatform *platform, * to signal "unset". */ goto errout; } + addr_gen_mode_valid = TRUE; } success = TRUE; - if (iid_is_valid) { - out_iid->id_u8[7] = i6_token.s6_addr[15]; - out_iid->id_u8[6] = i6_token.s6_addr[14]; - out_iid->id_u8[5] = i6_token.s6_addr[13]; - out_iid->id_u8[4] = i6_token.s6_addr[12]; - out_iid->id_u8[3] = i6_token.s6_addr[11]; - out_iid->id_u8[2] = i6_token.s6_addr[10]; - out_iid->id_u8[1] = i6_token.s6_addr[9]; - out_iid->id_u8[0] = i6_token.s6_addr[8]; - *out_iid_is_valid = TRUE; + if (token_valid) { + *out_token_valid = token_valid; + nm_utils_ipv6_interface_identifier_get_from_addr (out_token, &i6_token); + } + if (addr_gen_mode_valid) { + *out_addr_gen_mode_valid = addr_gen_mode_valid; + *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; } - *out_addr_gen_mode_inv = i6_addr_gen_mode_inv; errout: return success; } @@ -1436,6 +1434,8 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr NMPObject *lnk_data = NULL; gboolean address_complete_from_cache = TRUE; gboolean lnk_data_complete_from_cache = TRUE; + gboolean af_inet6_token_valid = FALSE; + gboolean af_inet6_addr_gen_mode_valid = FALSE; if (!nlmsg_valid_hdr (nlh, sizeof (*ifi))) return NULL; @@ -1512,9 +1512,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr case AF_INET6: _parse_af_inet6 (platform, af_attr, - &obj->link.inet6_token.iid, - &obj->link.inet6_token.is_valid, - &obj->link.inet6_addr_gen_mode_inv); + &obj->link.inet6_token, + &af_inet6_token_valid, + &obj->link.inet6_addr_gen_mode_inv, + &af_inet6_addr_gen_mode_valid); break; } } @@ -1556,7 +1557,9 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr if ( completed_from_cache && ( lnk_data_complete_from_cache - || address_complete_from_cache)) { + || address_complete_from_cache + || !af_inet6_token_valid + || !af_inet6_addr_gen_mode_valid)) { _lookup_cached_link (cache, obj->link.ifindex, completed_from_cache, &link_cached); if (link_cached) { if ( lnk_data_complete_from_cache @@ -1575,6 +1578,10 @@ _new_from_nl_link (NMPlatform *platform, const NMPCache *cache, struct nlmsghdr } if (address_complete_from_cache) obj->link.addr = link_cached->link.addr; + if (!af_inet6_token_valid) + obj->link.inet6_token = link_cached->link.inet6_token; + if (!af_inet6_addr_gen_mode_valid) + obj->link.inet6_addr_gen_mode_inv = link_cached->link.inet6_addr_gen_mode_inv; } } @@ -1947,7 +1954,8 @@ nmp_object_new_from_nl (NMPlatform *platform, const NMPCache *cache, struct nl_m static gboolean _nl_msg_new_link_set_afspec (struct nl_msg *msg, - int addr_gen_mode) + int addr_gen_mode, + NMUtilsIPv6IfaceId *iid) { struct nlattr *af_spec; struct nlattr *af_attr; @@ -1957,11 +1965,19 @@ _nl_msg_new_link_set_afspec (struct nl_msg *msg, if (!(af_spec = nla_nest_start (msg, IFLA_AF_SPEC))) goto nla_put_failure; - if (addr_gen_mode >= 0) { + if (addr_gen_mode >= 0 || iid) { if (!(af_attr = nla_nest_start (msg, AF_INET6))) goto nla_put_failure; - NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + if (addr_gen_mode >= 0) + NLA_PUT_U8 (msg, IFLA_INET6_ADDR_GEN_MODE, addr_gen_mode); + + if (iid) { + struct in6_addr i6_token = { .s6_addr = { 0, } }; + + nm_utils_ipv6_addr_set_interface_identifier (&i6_token, *iid); + NLA_PUT (msg, IFLA_INET6_TOKEN, sizeof (struct in6_addr), &i6_token); + } nla_nest_end (msg, af_attr); } @@ -4322,8 +4338,22 @@ link_set_user_ipv6ll_enabled (NMPlatform *platform, int ifindex, gboolean enable 0, 0); if ( !nlmsg - || !_nl_msg_new_link_set_afspec (nlmsg, - mode)) + || !_nl_msg_new_link_set_afspec (nlmsg, mode, NULL)) + g_return_val_if_reached (FALSE); + + return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; +} + +static gboolean +link_set_token (NMPlatform *platform, int ifindex, NMUtilsIPv6IfaceId iid) +{ + nm_auto_nlmsg struct nl_msg *nlmsg = NULL; + + _LOGD ("link: change %d: token: set IPv6 address generation token to %s", + ifindex, nm_utils_inet6_interface_identifier_to_token (iid, NULL)); + + nlmsg = _nl_msg_new_link (RTM_NEWLINK, 0, ifindex, NULL, 0, 0); + if (!nlmsg || !_nl_msg_new_link_set_afspec (nlmsg, -1, &iid)) g_return_val_if_reached (FALSE); return do_change_link (platform, ifindex, nlmsg) == NM_PLATFORM_ERROR_SUCCESS; @@ -6435,6 +6465,7 @@ nm_linux_platform_class_init (NMLinuxPlatformClass *klass) platform_class->link_get_udev_device = link_get_udev_device; platform_class->link_set_user_ipv6ll_enabled = link_set_user_ipv6ll_enabled; + platform_class->link_set_token = link_set_token; platform_class->link_set_address = link_set_address; platform_class->link_get_permanent_address = link_get_permanent_address; diff --git a/src/platform/nm-platform.c b/src/platform/nm-platform.c index 500db9b621..a6afcf33a9 100644 --- a/src/platform/nm-platform.c +++ b/src/platform/nm-platform.c @@ -900,33 +900,25 @@ nm_platform_link_uses_arp (NMPlatform *self, int ifindex) } /** - * nm_platform_link_get_ipv6_token: + * nm_platform_link_set_ipv6_token: * @self: platform instance * @ifindex: Interface index * @iid: Tokenized interface identifier * - * Returns IPv6 tokenized interface identifier. If the platform or OS doesn't - * support IPv6 tokenized interface identifiers, or the token is not set - * this call will fail and return %FALSE. + * Sets then IPv6 tokenized interface identifier. * * Returns: %TRUE a tokenized identifier was available */ gboolean -nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid) +nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid) { - const NMPlatformLink *pllink; - _CHECK_SELF (self, klass, FALSE); g_return_val_if_fail (ifindex >= 0, FALSE); - g_return_val_if_fail (iid, FALSE); - + g_return_val_if_fail (iid.id, FALSE); - pllink = nm_platform_link_get (self, ifindex); - if (pllink && pllink->inet6_token.is_valid) { - *iid = pllink->inet6_token.iid; - return TRUE; - } + if (klass->link_set_token) + return klass->link_set_token (self, ifindex, iid); return FALSE; } @@ -3067,7 +3059,7 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) GString *str_flags; char str_addrmode[30]; gs_free char *str_addr = NULL; - gs_free char *str_inet6_token = NULL; + char str_inet6_token[NM_UTILS_INET_ADDRSTRLEN]; const char *str_link_type; if (!nm_utils_to_string_buffer_init_null (link, &buf, &len)) @@ -3104,8 +3096,6 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) if (link->addr.len) str_addr = nm_utils_hwaddr_ntoa (link->addr.data, MIN (link->addr.len, sizeof (link->addr.data))); - if (link->inet6_token.is_valid) - str_inet6_token = nm_utils_hwaddr_ntoa (&link->inet6_token.iid, sizeof (link->inet6_token.iid)); str_link_type = nm_link_type_to_string (link->type); @@ -3139,8 +3129,8 @@ nm_platform_link_to_string (const NMPlatformLink *link, char *buf, gsize len) link->inet6_addr_gen_mode_inv ? nm_platform_link_inet6_addrgenmode2str (_nm_platform_uint8_inv (link->inet6_addr_gen_mode_inv), str_addrmode, sizeof (str_addrmode)) : "", str_addr ? " addr " : "", str_addr ? str_addr : "", - str_inet6_token ? " inet6token " : "", - str_inet6_token ? str_inet6_token : "", + link->inet6_token.id ? " inet6token " : "", + link->inet6_token.id ? nm_utils_inet6_interface_identifier_to_token (link->inet6_token, str_inet6_token) : "", link->driver ? " driver " : "", link->driver ? link->driver : ""); g_string_free (str_flags, TRUE); @@ -3798,13 +3788,11 @@ nm_platform_link_cmp (const NMPlatformLink *a, const NMPlatformLink *b) _CMP_FIELD (a, b, arptype); _CMP_FIELD (a, b, addr.len); _CMP_FIELD (a, b, inet6_addr_gen_mode_inv); - _CMP_FIELD (a, b, inet6_token.is_valid); _CMP_FIELD_STR_INTERNED (a, b, kind); _CMP_FIELD_STR_INTERNED (a, b, driver); if (a->addr.len) _CMP_FIELD_MEMCMP_LEN (a, b, addr.data, a->addr.len); - if (a->inet6_token.is_valid) - _CMP_FIELD_MEMCMP (a, b, inet6_token.iid); + _CMP_FIELD_MEMCMP (a, b, inet6_token); return 0; } diff --git a/src/platform/nm-platform.h b/src/platform/nm-platform.h index ed21632836..72f4f6720a 100644 --- a/src/platform/nm-platform.h +++ b/src/platform/nm-platform.h @@ -147,11 +147,8 @@ struct _NMPlatformLink { guint8 len; } addr; - /* rtnl_link_inet6_get_token() */ - struct { - NMUtilsIPv6IfaceId iid; - guint8 is_valid; - } inet6_token; + /* rtnl_link_inet6_get_token(), IFLA_INET6_TOKEN */ + NMUtilsIPv6IfaceId inet6_token; /* The bitwise inverse of rtnl_link_inet6_get_addr_gen_mode(). It is inverse * to have a default of 0 -- meaning: unspecified. That way, a struct @@ -523,6 +520,7 @@ typedef struct { GObject *(*link_get_udev_device) (NMPlatform *self, int ifindex); gboolean (*link_set_user_ipv6ll_enabled) (NMPlatform *, int ifindex, gboolean enabled); + gboolean (*link_set_token) (NMPlatform *, int ifindex, NMUtilsIPv6IfaceId iid); gboolean (*link_get_permanent_address) (NMPlatform *, int ifindex, @@ -733,7 +731,6 @@ gboolean nm_platform_link_is_up (NMPlatform *self, int ifindex); gboolean nm_platform_link_is_connected (NMPlatform *self, int ifindex); gboolean nm_platform_link_uses_arp (NMPlatform *self, int ifindex); guint32 nm_platform_link_get_mtu (NMPlatform *self, int ifindex); -gboolean nm_platform_link_get_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId *iid); gboolean nm_platform_link_get_user_ipv6ll_enabled (NMPlatform *self, int ifindex); gconstpointer nm_platform_link_get_address (NMPlatform *self, int ifindex, size_t *length); int nm_platform_link_get_master (NMPlatform *self, int slave); @@ -757,6 +754,7 @@ const char *nm_platform_link_get_udi (NMPlatform *self, int ifindex); GObject *nm_platform_link_get_udev_device (NMPlatform *self, int ifindex); gboolean nm_platform_link_set_user_ipv6ll_enabled (NMPlatform *self, int ifindex, gboolean enabled); +gboolean nm_platform_link_set_ipv6_token (NMPlatform *self, int ifindex, NMUtilsIPv6IfaceId iid); gboolean nm_platform_link_get_permanent_address (NMPlatform *self, int ifindex, guint8 *buf, size_t *length); gboolean nm_platform_link_set_address (NMPlatform *self, int ifindex, const void *address, size_t length); diff --git a/src/ppp-manager/nm-ppp-manager.c b/src/ppp-manager/nm-ppp-manager.c index b8860b9eb0..a51f7cfa6c 100644 --- a/src/ppp-manager/nm-ppp-manager.c +++ b/src/ppp-manager/nm-ppp-manager.c @@ -540,7 +540,7 @@ iid_value_to_ll6_addr (GVariant *dict, out_addr->s6_addr16[0] = htons (0xfe80); memcpy (out_addr->s6_addr + 8, &iid, sizeof (iid)); if (out_iid) - nm_utils_ipv6_interface_identfier_get_from_addr (out_iid, out_addr); + nm_utils_ipv6_interface_identifier_get_from_addr (out_iid, out_addr); return TRUE; } diff --git a/src/rdisc/nm-rdisc.c b/src/rdisc/nm-rdisc.c index 12e3962b0d..85c803dc79 100644 --- a/src/rdisc/nm-rdisc.c +++ b/src/rdisc/nm-rdisc.c @@ -161,7 +161,7 @@ complete_address (NMRDisc *rdisc, NMRDiscAddress *addr) if (addr->address.s6_addr32[2] == 0x0 && addr->address.s6_addr32[3] == 0x0) { _LOGD ("complete-address: adding an EUI-64 address"); - nm_utils_ipv6_addr_set_interface_identfier (&addr->address, rdisc->iid); + nm_utils_ipv6_addr_set_interface_identifier (&addr->address, rdisc->iid); return TRUE; } diff --git a/src/settings/plugins/ifcfg-rh/reader.c b/src/settings/plugins/ifcfg-rh/reader.c index 240149b3e3..b933e1a5fa 100644 --- a/src/settings/plugins/ifcfg-rh/reader.c +++ b/src/settings/plugins/ifcfg-rh/reader.c @@ -1527,6 +1527,13 @@ make_ip6_setting (shvarFile *ifcfg, NULL); } + /* IPv6 tokenized interface identifier */ + tmp = svGetValue (ifcfg, "IPV6_TOKEN", FALSE); + if (tmp) { + g_object_set (s_ip6, NM_SETTING_IP6_CONFIG_TOKEN, tmp, NULL); + g_free (tmp); + } + /* DNS servers * Pick up just IPv6 addresses (IPv4 addresses are taken by make_ip4_setting()) */ diff --git a/src/settings/plugins/ifcfg-rh/writer.c b/src/settings/plugins/ifcfg-rh/writer.c index 55ef2cc766..2864078a48 100644 --- a/src/settings/plugins/ifcfg-rh/writer.c +++ b/src/settings/plugins/ifcfg-rh/writer.c @@ -2623,8 +2623,14 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error) addr_gen_mode); svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", tmp, FALSE); g_free (tmp); + } else { + svSetValue (ifcfg, "IPV6_ADDR_GEN_MODE", NULL, FALSE); } + /* IPv6 tokenized interface identifier */ + value = nm_setting_ip6_config_get_token (NM_SETTING_IP6_CONFIG (s_ip6)); + svSetValue (ifcfg, "IPV6_TOKEN", value, FALSE); + priority = nm_setting_ip_config_get_dns_priority (s_ip6); if (priority) svSetValueInt64 (ifcfg, "IPV6_DNS_PRIORITY", priority); |