diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2016-04-30 16:48:02 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2016-05-30 16:32:06 +0200 |
commit | 954d937b2f6bfe5a513497c6ea13d0651a0c0b16 (patch) | |
tree | a91234624df78826e88b3fe3f1dbed32546ef483 | |
parent | 24f428f76888564f89dc0c6837efa6a3ababd4a5 (diff) | |
download | NetworkManager-954d937b2f6bfe5a513497c6ea13d0651a0c0b16.tar.gz |
setting-ip6-config: add token property
-rw-r--r-- | libnm-core/nm-connection.c | 27 | ||||
-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-- | src/settings/plugins/ifcfg-rh/reader.c | 7 | ||||
-rw-r--r-- | src/settings/plugins/ifcfg-rh/writer.c | 4 |
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); |