mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-04-19 02:00:45 +02:00
merge: branch 'lr/connection-token'
https://bugzilla.gnome.org/show_bug.cgi?id=765851
This commit is contained in:
commit
2edaf35f12
19 changed files with 438 additions and 100 deletions
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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,12 +472,26 @@ 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;
|
||||
}
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
|
|
@ -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---
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -3565,6 +3565,40 @@ nm_utils_ipaddr_valid (int family, const char *ip)
|
|||
return inet_pton (family, ip, buf) == 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
|
|
|
|||
|
|
@ -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),
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
hwaddr = nm_platform_link_get_address (NM_PLATFORM_GET, ifindex, &hwaddr_len);
|
||||
if (!hwaddr_len)
|
||||
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;
|
||||
|
||||
success = nm_utils_get_ipv6_interface_identifier (link_type,
|
||||
hwaddr,
|
||||
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 (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);
|
||||
|
|
|
|||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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())
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue