summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBeniamino Galvani <bgalvani@redhat.com>2015-03-26 08:57:02 +0100
committerBeniamino Galvani <bgalvani@redhat.com>2015-03-30 13:46:14 +0200
commitfeb05fa1cbb18df2fbdb60723d1f72e0fb41d9c7 (patch)
tree0c7cfa98d06ee46e147c640cf7167465f9dc6cad
parentaf060e7c224cc7ce44a18fb23fdedb81f147319e (diff)
downloadNetworkManager-feb05fa1cbb18df2fbdb60723d1f72e0fb41d9c7.tar.gz
libnm-core: add dns-options property to NMSettingIPConfig
-rw-r--r--libnm-core/nm-setting-ip-config.c172
-rw-r--r--libnm-core/nm-setting-ip-config.h12
-rw-r--r--libnm-core/nm-utils-private.h4
-rw-r--r--libnm-core/nm-utils.c127
-rw-r--r--libnm/libnm.ver6
5 files changed, 321 insertions, 0 deletions
diff --git a/libnm-core/nm-setting-ip-config.c b/libnm-core/nm-setting-ip-config.c
index e6f0401a01..c1391690f9 100644
--- a/libnm-core/nm-setting-ip-config.c
+++ b/libnm-core/nm-setting-ip-config.c
@@ -1062,6 +1062,7 @@ typedef struct {
char *method;
GPtrArray *dns; /* array of IP address strings */
GPtrArray *dns_search; /* array of domain name strings */
+ GPtrArray *dns_options;/* array of DNS options */
GPtrArray *addresses; /* array of NMIPAddress */
GPtrArray *routes; /* array of NMIPRoute */
gint64 route_metric;
@@ -1079,6 +1080,7 @@ enum {
PROP_METHOD,
PROP_DNS,
PROP_DNS_SEARCH,
+ PROP_DNS_OPTIONS,
PROP_ADDRESSES,
PROP_GATEWAY,
PROP_ROUTES,
@@ -1394,6 +1396,155 @@ nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting)
}
/**
+ * nm_setting_ip_config_get_num_dns_options:
+ * @setting: the #NMSettingIPConfig
+ *
+ * Returns: the number of configured DNS options
+ **/
+guint
+nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting)
+{
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), 0);
+
+ return NM_SETTING_IP_CONFIG_GET_PRIVATE (setting)->dns_options->len;
+}
+
+/**
+ * nm_setting_ip_config_get_dns_options:
+ * @setting: the #NMSettingIPConfig
+ * @i: index number of the DNS options
+ *
+ * Returns: the DNS option at index @i
+ **/
+const char *
+nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting, int i)
+{
+ NMSettingIPConfigPrivate *priv;
+
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), NULL);
+
+ priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+ g_return_val_if_fail (i < priv->dns_options->len, NULL);
+
+ return priv->dns_options->pdata[i];
+}
+
+/**
+ * nm_setting_ip_config_add_dns_option:
+ * @setting: the #NMSettingIPConfig
+ * @dns_option: the DNS option to add
+ *
+ * Adds a new DNS option to the setting.
+ *
+ * Returns: %TRUE if the DNS option was added; %FALSE if the option was
+ * already known
+ **/
+gboolean
+nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting,
+ const char *dns_option)
+{
+ NMSettingIPConfigPrivate *priv;
+ gboolean numeric;
+ char *name;
+
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
+ g_return_val_if_fail (dns_option != NULL, FALSE);
+ g_return_val_if_fail (dns_option[0] != '\0', FALSE);
+
+ /* Check syntax and extract option name */
+ if (!_nm_utils_dns_option_parse (dns_option, &name, &numeric))
+ return FALSE;
+
+ /* Verify that the option is known */
+ if (!_nm_utils_dns_option_validate (name, numeric,
+ NM_IS_SETTING_IP6_CONFIG (setting))) {
+ g_free (name);
+ return FALSE;
+ }
+
+ priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+ if (!_nm_utils_dns_option_check_duplicate (priv->dns_options, name)) {
+ g_free (name);
+ return FALSE;
+ }
+
+ g_free (name);
+ g_ptr_array_add (priv->dns_options, g_strdup (dns_option));
+ g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
+ return TRUE;
+}
+
+/**
+ * nm_setting_ip_config_remove_dns_option:
+ * @setting: the #NMSettingIPConfig
+ * @i: index number of the DNS option
+ *
+ * Removes the DNS option at index @i.
+ **/
+void
+nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting, int i)
+{
+ NMSettingIPConfigPrivate *priv;
+
+ g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
+
+ priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+ g_return_if_fail (i < priv->dns_options->len);
+
+ g_ptr_array_remove_index (priv->dns_options, i);
+ g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
+}
+
+/**
+ * nm_setting_ip_config_remove_dns_option_by_value:
+ * @setting: the #NMSettingIPConfig
+ * @dns_option: the DNS option to remove
+ *
+ * Removes the DNS option @dns_option.
+ *
+ * Returns: %TRUE if the DNS option was found and removed; %FALSE if it was not.
+ **/
+gboolean
+nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting,
+ const char *dns_option)
+{
+ NMSettingIPConfigPrivate *priv;
+ int i;
+
+ g_return_val_if_fail (NM_IS_SETTING_IP_CONFIG (setting), FALSE);
+ g_return_val_if_fail (dns_option != NULL, FALSE);
+ g_return_val_if_fail (dns_option[0] != '\0', FALSE);
+
+ priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+ for (i = 0; i < priv->dns_options->len; i++) {
+ if (!strcmp (dns_option, priv->dns_options->pdata[i])) {
+ g_ptr_array_remove_index (priv->dns_options, i);
+ g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
+ return TRUE;
+ }
+ }
+ return FALSE;
+}
+
+/**
+ * nm_setting_ip_config_clear_dns_options:
+ * @setting: the #NMSettingIPConfig
+ *
+ * Removes all configured DNS options.
+ **/
+void
+nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting)
+{
+ NMSettingIPConfigPrivate *priv;
+
+ g_return_if_fail (NM_IS_SETTING_IP_CONFIG (setting));
+
+ priv = NM_SETTING_IP_CONFIG_GET_PRIVATE (setting);
+ g_ptr_array_set_size (priv->dns_options, 0);
+ g_object_notify (G_OBJECT (setting), NM_SETTING_IP_CONFIG_DNS_OPTIONS);
+}
+
+/**
* nm_setting_ip_config_get_num_addresses:
* @setting: the #NMSettingIPConfig
*
@@ -1959,6 +2110,7 @@ nm_setting_ip_config_init (NMSettingIPConfig *setting)
priv->dns = g_ptr_array_new_with_free_func (g_free);
priv->dns_search = g_ptr_array_new_with_free_func (g_free);
+ priv->dns_options = g_ptr_array_new_with_free_func (g_free);
priv->addresses = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_address_unref);
priv->routes = g_ptr_array_new_with_free_func ((GDestroyNotify) nm_ip_route_unref);
}
@@ -1975,6 +2127,7 @@ finalize (GObject *object)
g_ptr_array_unref (priv->dns);
g_ptr_array_unref (priv->dns_search);
+ g_ptr_array_unref (priv->dns_options);
g_ptr_array_unref (priv->addresses);
g_ptr_array_unref (priv->routes);
@@ -2002,6 +2155,10 @@ set_property (GObject *object, guint prop_id,
g_ptr_array_unref (priv->dns_search);
priv->dns_search = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
break;
+ case PROP_DNS_OPTIONS:
+ g_ptr_array_unref (priv->dns_options);
+ priv->dns_options = _nm_utils_strv_to_ptrarray (g_value_get_boxed (value));
+ break;
case PROP_ADDRESSES:
g_ptr_array_unref (priv->addresses);
priv->addresses = _nm_utils_copy_array (g_value_get_boxed (value),
@@ -2065,6 +2222,9 @@ get_property (GObject *object, guint prop_id,
case PROP_DNS_SEARCH:
g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_search));
break;
+ case PROP_DNS_OPTIONS:
+ g_value_take_boxed (value, _nm_utils_ptrarray_to_strv (priv->dns_options));
+ break;
case PROP_ADDRESSES:
g_value_take_boxed (value, _nm_utils_copy_array (priv->addresses,
(NMUtilsCopyFunc) nm_ip_address_dup,
@@ -2185,6 +2345,18 @@ nm_setting_ip_config_class_init (NMSettingIPConfigClass *setting_class)
G_PARAM_STATIC_STRINGS));
/**
+ * NMSettingIPConfig:dns-options:
+ *
+ * Array of DNS options.
+ **/
+ g_object_class_install_property
+ (object_class, PROP_DNS_OPTIONS,
+ g_param_spec_boxed (NM_SETTING_IP_CONFIG_DNS_OPTIONS, "", "",
+ G_TYPE_STRV,
+ G_PARAM_READWRITE |
+ G_PARAM_STATIC_STRINGS));
+
+ /**
* NMSettingIPConfig:addresses:
*
* Array of IP addresses.
diff --git a/libnm-core/nm-setting-ip-config.h b/libnm-core/nm-setting-ip-config.h
index 12763fa857..58d1a3baba 100644
--- a/libnm-core/nm-setting-ip-config.h
+++ b/libnm-core/nm-setting-ip-config.h
@@ -133,6 +133,7 @@ void nm_ip_route_set_attribute (NMIPRoute *route,
#define NM_SETTING_IP_CONFIG_METHOD "method"
#define NM_SETTING_IP_CONFIG_DNS "dns"
#define NM_SETTING_IP_CONFIG_DNS_SEARCH "dns-search"
+#define NM_SETTING_IP_CONFIG_DNS_OPTIONS "dns-options"
#define NM_SETTING_IP_CONFIG_ADDRESSES "addresses"
#define NM_SETTING_IP_CONFIG_GATEWAY "gateway"
#define NM_SETTING_IP_CONFIG_ROUTES "routes"
@@ -181,6 +182,17 @@ gboolean nm_setting_ip_config_remove_dns_search_by_value (NMSettingIPConfig
const char *dns_search);
void nm_setting_ip_config_clear_dns_searches (NMSettingIPConfig *setting);
+guint nm_setting_ip_config_get_num_dns_options (NMSettingIPConfig *setting);
+const char *nm_setting_ip_config_get_dns_option (NMSettingIPConfig *setting,
+ int i);
+gboolean nm_setting_ip_config_add_dns_option (NMSettingIPConfig *setting,
+ const char *dns_option);
+void nm_setting_ip_config_remove_dns_option (NMSettingIPConfig *setting,
+ int i);
+gboolean nm_setting_ip_config_remove_dns_option_by_value (NMSettingIPConfig *setting,
+ const char *dns_option);
+void nm_setting_ip_config_clear_dns_options (NMSettingIPConfig *setting);
+
guint nm_setting_ip_config_get_num_addresses (NMSettingIPConfig *setting);
NMIPAddress *nm_setting_ip_config_get_address (NMSettingIPConfig *setting,
int i);
diff --git a/libnm-core/nm-utils-private.h b/libnm-core/nm-utils-private.h
index 3854d67951..8b5ae05ffa 100644
--- a/libnm-core/nm-utils-private.h
+++ b/libnm-core/nm-utils-private.h
@@ -48,4 +48,8 @@ char ** _nm_utils_ptrarray_to_strv (GPtrArray *ptrarray);
char * _nm_utils_hwaddr_canonical_or_invalid (const char *mac, gssize length);
+gboolean _nm_utils_dns_option_parse (const char *str, char **name, gboolean *numeric);
+gboolean _nm_utils_dns_option_validate (const char *name, gboolean numeric, gboolean ipv6);
+gboolean _nm_utils_dns_option_check_duplicate (GPtrArray *array, const char *name);
+
#endif
diff --git a/libnm-core/nm-utils.c b/libnm-core/nm-utils.c
index d3557f578a..464177d3f4 100644
--- a/libnm-core/nm-utils.c
+++ b/libnm-core/nm-utils.c
@@ -144,6 +144,29 @@ static const struct IsoLangToEncodings isoLangEntries2[] =
static GHashTable * langToEncodings5 = NULL;
static GHashTable * langToEncodings2 = NULL;
+typedef struct {
+ const char *name;
+ gboolean numeric;
+ gboolean ipv6_only;
+} DNSOptionDesc;
+
+static const DNSOptionDesc dns_option_descs[] = {
+ { "debug", FALSE, FALSE },
+ { "ndots", TRUE, FALSE },
+ { "timeout", TRUE, FALSE },
+ { "attempts", TRUE, FALSE },
+ { "rotate", FALSE, FALSE },
+ { "no-check-names", FALSE, FALSE },
+ { "inet6", FALSE, TRUE },
+ { "ip6-bytestring", FALSE, TRUE },
+ { "ip6-dotint", FALSE, TRUE },
+ { "no-ip6-dotint", FALSE, TRUE },
+ { "edns0", FALSE, FALSE },
+ { "single-request", FALSE, FALSE },
+ { "single-request-reopen", FALSE, FALSE },
+ { NULL, FALSE, FALSE }
+};
+
static void
init_lang_to_encodings_hash (void)
{
@@ -3406,3 +3429,107 @@ _nm_utils_ascii_str_to_int64 (const char *str, guint base, gint64 min, gint64 ma
return v;
}
+/**
+ * _nm_utils_dns_option_parse
+ * @str: option string
+ * @name: (out): on return will contain the option name
+ * @numeric: (out) (allow-none): whether the option has a numeric argument
+ *
+ * Parses a DNS option in the form "name" or "name:number"
+ *
+ * Returns: %TRUE when the parsing was successfully done, %FALSE otherwise
+ */
+gboolean _nm_utils_dns_option_parse(const char *str, char **name,
+ gboolean *numeric)
+{
+ char **tokens, *ptr;
+ gboolean ret;
+
+ g_return_val_if_fail (str != NULL, FALSE);
+ g_return_val_if_fail (name != NULL, FALSE);
+
+ tokens = g_strsplit (str, ":", 2);
+ if (numeric)
+ *numeric = FALSE;
+
+ if (g_strv_length (tokens) == 1) {
+ *name = g_strdup (tokens[0]);
+ ret = TRUE;
+ goto out;
+ }
+
+ /* Numeric option */
+
+ if (!tokens[1][0]) {
+ ret = FALSE;
+ goto out;
+ }
+
+ for (ptr = tokens[1]; *ptr; ptr++) {
+ if (!g_ascii_isdigit (*ptr)) {
+ ret = FALSE;
+ goto out;
+ }
+ }
+
+ *name = g_strdup (tokens[0]);
+ if (numeric)
+ *numeric = TRUE;
+ ret = TRUE;
+out:
+ g_strfreev (tokens);
+ return ret;
+}
+
+/**
+ * _nm_utils_dns_option_validate
+ * @name: option name
+ * @numeric: whether the option has a numeric argument
+ * @ipv6: whether the option refers to a IPv6 connection
+ *
+ * Checks if a DNS option is valid
+ *
+ * Returns: %TRUE if the option is valid, %FALSE otherwise
+ */
+gboolean _nm_utils_dns_option_validate(const char *name, gboolean numeric,
+ gboolean ipv6)
+{
+ const DNSOptionDesc *desc;
+
+ for (desc = dns_option_descs; desc->name; desc++) {
+ if (!strcmp (name, desc->name) &&
+ numeric == desc->numeric &&
+ (!desc->ipv6_only || ipv6))
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+/**
+ * _nm_utils_dns_option_check_duplicate
+ * @array: an array of strings
+ * @name: name of a DNS option
+ *
+ * Checks if a DNS option with name @name is already present in the array
+ *
+ * Returns: %TRUE if the option is not present, %FALSE otherwise
+ */
+gboolean _nm_utils_dns_option_check_duplicate(GPtrArray *array, const char *name)
+{
+ gboolean ret;
+ char *tmp_name;
+ int i;
+
+ for (i = 0; i < array->len; i++) {
+ _nm_utils_dns_option_parse (array->pdata[i], &tmp_name, NULL);
+ ret = strcmp (tmp_name, name);
+ g_free (tmp_name);
+
+ if (!ret)
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
diff --git a/libnm/libnm.ver b/libnm/libnm.ver
index 44b83f6ecb..06640e6d84 100644
--- a/libnm/libnm.ver
+++ b/libnm/libnm.ver
@@ -553,16 +553,19 @@ global:
nm_setting_ip_config_add_address;
nm_setting_ip_config_add_dns;
nm_setting_ip_config_add_dns_search;
+ nm_setting_ip_config_add_dns_option;
nm_setting_ip_config_add_route;
nm_setting_ip_config_clear_addresses;
nm_setting_ip_config_clear_dns;
nm_setting_ip_config_clear_dns_searches;
+ nm_setting_ip_config_clear_dns_options;
nm_setting_ip_config_clear_routes;
nm_setting_ip_config_get_address;
nm_setting_ip_config_get_dhcp_hostname;
nm_setting_ip_config_get_dhcp_send_hostname;
nm_setting_ip_config_get_dns;
nm_setting_ip_config_get_dns_search;
+ nm_setting_ip_config_get_dns_option;
nm_setting_ip_config_get_gateway;
nm_setting_ip_config_get_ignore_auto_dns;
nm_setting_ip_config_get_ignore_auto_routes;
@@ -572,6 +575,7 @@ global:
nm_setting_ip_config_get_num_addresses;
nm_setting_ip_config_get_num_dns;
nm_setting_ip_config_get_num_dns_searches;
+ nm_setting_ip_config_get_num_dns_options;
nm_setting_ip_config_get_num_routes;
nm_setting_ip_config_get_route;
nm_setting_ip_config_get_route_metric;
@@ -582,6 +586,8 @@ global:
nm_setting_ip_config_remove_dns_by_value;
nm_setting_ip_config_remove_dns_search;
nm_setting_ip_config_remove_dns_search_by_value;
+ nm_setting_ip_config_remove_dns_option;
+ nm_setting_ip_config_remove_dns_option_by_value;
nm_setting_ip_config_remove_route;
nm_setting_ip_config_remove_route_by_value;
nm_setting_lookup_type;