summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2016-04-30 16:48:02 +0200
committerLubomir Rintel <lkundrak@v3.sk>2016-05-30 16:32:06 +0200
commit954d937b2f6bfe5a513497c6ea13d0651a0c0b16 (patch)
treea91234624df78826e88b3fe3f1dbed32546ef483
parent24f428f76888564f89dc0c6837efa6a3ababd4a5 (diff)
downloadNetworkManager-954d937b2f6bfe5a513497c6ea13d0651a0c0b16.tar.gz
setting-ip6-config: add token property
-rw-r--r--libnm-core/nm-connection.c27
-rw-r--r--libnm-core/nm-setting-ip6-config.c104
-rw-r--r--libnm-core/nm-setting-ip6-config.h4
-rw-r--r--src/settings/plugins/ifcfg-rh/reader.c7
-rw-r--r--src/settings/plugins/ifcfg-rh/writer.c4
5 files changed, 142 insertions, 4 deletions
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-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/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 b44d8fd233..2864078a48 100644
--- a/src/settings/plugins/ifcfg-rh/writer.c
+++ b/src/settings/plugins/ifcfg-rh/writer.c
@@ -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);