setting-ip6-config: add token property

This commit is contained in:
Lubomir Rintel 2016-04-30 16:48:02 +02:00
parent 24f428f768
commit 954d937b2f
5 changed files with 142 additions and 4 deletions

View file

@ -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;
}
}

View file

@ -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---

View file

@ -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

View file

@ -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())
*/

View file

@ -2627,6 +2627,10 @@ write_ip6_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
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);