From b02f59d4a459cb1f0a4d5cac014f595ff008fe0e Mon Sep 17 00:00:00 2001 From: Beniamino Galvani Date: Thu, 26 Mar 2015 09:23:12 +0100 Subject: [PATCH] core: add DNS options property to NMIP4Config and NMIP6Config --- introspection/nm-ip4-config.xml | 7 ++ introspection/nm-ip6-config.xml | 7 ++ src/nm-ip4-config.c | 142 +++++++++++++++++++++++++++++++- src/nm-ip4-config.h | 8 ++ src/nm-ip6-config.c | 140 ++++++++++++++++++++++++++++++- src/nm-ip6-config.h | 8 ++ 6 files changed, 310 insertions(+), 2 deletions(-) diff --git a/introspection/nm-ip4-config.xml b/introspection/nm-ip4-config.xml index 9807653495..5a9e8ea1c3 100644 --- a/introspection/nm-ip4-config.xml +++ b/introspection/nm-ip4-config.xml @@ -49,6 +49,13 @@ A list of dns searches. + + + A list of DNS options that modify the behavior of the DNS + resolver. See resolv.conf(5) manual page for the list of + supported options. + + The Windows Internet Name Service servers associated with the connection. Each address is in network byte order. diff --git a/introspection/nm-ip6-config.xml b/introspection/nm-ip6-config.xml index 985dd2e331..f2ef386ba1 100644 --- a/introspection/nm-ip6-config.xml +++ b/introspection/nm-ip6-config.xml @@ -43,6 +43,13 @@ A list of dns searches. + + + A list of DNS options that modify the behavior of the DNS + resolver. See resolv.conf(5) manual page for the list of + supported options. + + diff --git a/src/nm-ip4-config.c b/src/nm-ip4-config.c index abc8af836a..7092f75c3d 100644 --- a/src/nm-ip4-config.c +++ b/src/nm-ip4-config.c @@ -49,6 +49,7 @@ typedef struct { GArray *nameservers; GPtrArray *domains; GPtrArray *searches; + GPtrArray *dns_options; guint32 mss; GArray *nis; char *nis_domain; @@ -73,6 +74,7 @@ enum { PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, + PROP_DNS_OPTIONS, PROP_WINS_SERVERS, LAST_PROP @@ -388,6 +390,12 @@ nm_ip4_config_merge_setting (NMIP4Config *config, NMSettingIPConfig *setting, gu for (i = 0; i < nsearches; i++) nm_ip4_config_add_search (config, nm_setting_ip_config_get_dns_search (setting, i)); + i = 0; + while ((i = nm_setting_ip_config_next_valid_dns_option (setting, i)) >= 0) { + nm_ip4_config_add_dns_option (config, nm_setting_ip_config_get_dns_option (setting, i)); + i++; + } + g_object_thaw_notify (G_OBJECT (config)); } @@ -396,7 +404,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) { NMSettingIPConfig *s_ip4; guint32 gateway; - guint naddresses, nroutes, nnameservers, nsearches; + guint naddresses, nroutes, nnameservers, nsearches, noptions; const char *method = NULL; int i; @@ -414,6 +422,7 @@ nm_ip4_config_create_setting (const NMIP4Config *config) nroutes = nm_ip4_config_get_num_routes (config); nnameservers = nm_ip4_config_get_num_nameservers (config); nsearches = nm_ip4_config_get_num_searches (config); + noptions = nm_ip4_config_get_num_dns_options (config); /* Addresses */ for (i = 0; i < naddresses; i++) { @@ -484,6 +493,12 @@ nm_ip4_config_create_setting (const NMIP4Config *config) nm_setting_ip_config_add_dns_search (s_ip4, search); } + for (i = 0; i < noptions; i++) { + const char *option = nm_ip4_config_get_dns_option (config, i); + + nm_setting_ip_config_add_dns_option (s_ip4, option); + } + return NM_SETTING (s_ip4); } @@ -523,6 +538,10 @@ nm_ip4_config_merge (NMIP4Config *dst, const NMIP4Config *src) for (i = 0; i < nm_ip4_config_get_num_searches (src); i++) nm_ip4_config_add_search (dst, nm_ip4_config_get_search (src, i)); + /* dns options */ + for (i = 0; i < nm_ip4_config_get_num_dns_options (src); i++) + nm_ip4_config_add_dns_option (dst, nm_ip4_config_get_dns_option (src, i)); + /* MSS */ if (!nm_ip4_config_get_mss (dst)) nm_ip4_config_set_mss (dst, nm_ip4_config_get_mss (src)); @@ -625,6 +644,21 @@ _searches_get_index (const NMIP4Config *self, const char *search) return -1; } +static int +_dns_options_get_index (const NMIP4Config *self, const char *option) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->dns_options->len; i++) { + const char *s = g_ptr_array_index (priv->dns_options, i); + + if (g_strcmp0 (option, s) == 0) + return (int) i; + } + return -1; +} + static int _nis_servers_get_index (const NMIP4Config *self, guint32 nis_server) { @@ -717,6 +751,13 @@ nm_ip4_config_subtract (NMIP4Config *dst, const NMIP4Config *src) nm_ip4_config_del_search (dst, idx); } + /* dns options */ + for (i = 0; i < nm_ip4_config_get_num_dns_options (src); i++) { + idx = _dns_options_get_index (dst, nm_ip4_config_get_dns_option (src, i)); + if (idx >= 0) + nm_ip4_config_del_dns_option (dst, idx); + } + /* MSS */ if (nm_ip4_config_get_mss (src) == nm_ip4_config_get_mss (dst)) nm_ip4_config_set_mss (dst, 0); @@ -783,6 +824,7 @@ nm_ip4_config_intersect (NMIP4Config *dst, const NMIP4Config *src) /* ignore domains */ /* ignore dns searches */ + /* ignore dns options */ /* ignore NIS */ /* ignore WINS */ @@ -949,6 +991,25 @@ nm_ip4_config_replace (NMIP4Config *dst, const NMIP4Config *src, gboolean *relev has_relevant_changes = TRUE; } + /* dns options */ + num = nm_ip4_config_get_num_dns_options (src); + are_equal = num == nm_ip4_config_get_num_dns_options (dst); + if (are_equal) { + for (i = 0; i < num; i++ ) { + if (g_strcmp0 (nm_ip4_config_get_dns_option (src, i), + nm_ip4_config_get_dns_option (dst, i))) { + are_equal = FALSE; + break; + } + } + } + if (!are_equal) { + nm_ip4_config_reset_dns_options (dst); + for (i = 0; i < num; i++) + nm_ip4_config_add_dns_option (dst, nm_ip4_config_get_dns_option (src, i)); + has_relevant_changes = TRUE; + } + /* mss */ if (src_priv->mss != dst_priv->mss) { nm_ip4_config_set_mss (dst, src_priv->mss); @@ -1055,6 +1116,11 @@ nm_ip4_config_dump (const NMIP4Config *config, const char *detail) for (i = 0; i < nm_ip4_config_get_num_searches (config); i++) g_message (" search: %s", nm_ip4_config_get_search (config, i)); + /* dns options */ + for (i = 0; i < nm_ip4_config_get_num_dns_options (config); i++) + g_message (" dnsopt: %s", nm_ip4_config_get_dns_option (config, i)); + + g_message (" mss: %"G_GUINT32_FORMAT, nm_ip4_config_get_mss (config)); g_message (" mtu: %"G_GUINT32_FORMAT, nm_ip4_config_get_mtu (config)); @@ -1552,6 +1618,63 @@ nm_ip4_config_get_search (const NMIP4Config *config, guint i) /******************************************************************/ +void +nm_ip4_config_reset_dns_options (NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + + if (priv->dns_options->len != 0) { + g_ptr_array_set_size (priv->dns_options, 0); + _NOTIFY (config, PROP_DNS_OPTIONS); + } +} + +void +nm_ip4_config_add_dns_option (NMIP4Config *config, const char *new) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + int i; + + g_return_if_fail (new != NULL); + g_return_if_fail (new[0] != '\0'); + + for (i = 0; i < priv->dns_options->len; i++) + if (!g_strcmp0 (g_ptr_array_index (priv->dns_options, i), new)) + return; + + g_ptr_array_add (priv->dns_options, g_strdup (new)); + _NOTIFY (config, PROP_DNS_OPTIONS); +} + +void +nm_ip4_config_del_dns_option(NMIP4Config *config, guint i) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + + g_return_if_fail (i < priv->dns_options->len); + + g_ptr_array_remove_index (priv->dns_options, i); + _NOTIFY (config, PROP_DNS_OPTIONS); +} + +guint32 +nm_ip4_config_get_num_dns_options (const NMIP4Config *config) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + + return priv->dns_options->len; +} + +const char * +nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i) +{ + NMIP4ConfigPrivate *priv = NM_IP4_CONFIG_GET_PRIVATE (config); + + return g_ptr_array_index (priv->dns_options, i); +} + +/******************************************************************/ + void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss) { @@ -1778,6 +1901,12 @@ nm_ip4_config_hash (const NMIP4Config *config, GChecksum *sum, gboolean dns_only s = nm_ip4_config_get_search (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } + + for (i = 0; i < nm_ip4_config_get_num_dns_options (config); i++) { + s = nm_ip4_config_get_dns_option (config, i); + g_checksum_update (sum, (const guint8 *) s, strlen (s)); + } + } /** @@ -1832,6 +1961,7 @@ nm_ip4_config_init (NMIP4Config *config) priv->nameservers = g_array_new (FALSE, FALSE, sizeof (guint32)); priv->domains = g_ptr_array_new_with_free_func (g_free); priv->searches = g_ptr_array_new_with_free_func (g_free); + priv->dns_options = g_ptr_array_new_with_free_func (g_free); priv->nis = g_array_new (FALSE, TRUE, sizeof (guint32)); priv->wins = g_array_new (FALSE, TRUE, sizeof (guint32)); } @@ -1848,6 +1978,7 @@ finalize (GObject *object) g_array_unref (priv->nameservers); g_ptr_array_unref (priv->domains); g_ptr_array_unref (priv->searches); + g_ptr_array_unref (priv->dns_options); g_array_unref (priv->nis); g_free (priv->nis_domain); g_array_unref (priv->wins); @@ -2015,6 +2146,9 @@ get_property (GObject *object, guint prop_id, case PROP_SEARCHES: g_value_set_boxed (value, priv->searches); break; + case PROP_DNS_OPTIONS: + g_value_set_boxed (value, priv->dns_options); + break; case PROP_WINS_SERVERS: g_value_set_boxed (value, priv->wins); break; @@ -2099,6 +2233,12 @@ nm_ip4_config_class_init (NMIP4ConfigClass *config_class) DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DNS_OPTIONS] = + g_param_spec_boxed (NM_IP4_CONFIG_DNS_OPTIONS, "", "", + DBUS_TYPE_G_ARRAY_OF_STRING, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); + obj_properties[PROP_WINS_SERVERS] = g_param_spec_boxed (NM_IP4_CONFIG_WINS_SERVERS, "", "", DBUS_TYPE_G_UINT_ARRAY, diff --git a/src/nm-ip4-config.h b/src/nm-ip4-config.h index 3e551950d3..9b74e8102b 100644 --- a/src/nm-ip4-config.h +++ b/src/nm-ip4-config.h @@ -48,6 +48,7 @@ typedef struct { #define NM_IP4_CONFIG_NAMESERVERS "nameservers" #define NM_IP4_CONFIG_DOMAINS "domains" #define NM_IP4_CONFIG_SEARCHES "searches" +#define NM_IP4_CONFIG_DNS_OPTIONS "dns-options" #define NM_IP4_CONFIG_WINS_SERVERS "wins-servers" /* deprecated */ @@ -124,6 +125,13 @@ void nm_ip4_config_del_search (NMIP4Config *config, guint i); guint32 nm_ip4_config_get_num_searches (const NMIP4Config *config); const char * nm_ip4_config_get_search (const NMIP4Config *config, guint i); +/* DNS options */ +void nm_ip4_config_reset_dns_options (NMIP4Config *config); +void nm_ip4_config_add_dns_option (NMIP4Config *config, const char *option); +void nm_ip4_config_del_dns_option (NMIP4Config *config, guint i); +guint32 nm_ip4_config_get_num_dns_options (const NMIP4Config *config); +const char * nm_ip4_config_get_dns_option (const NMIP4Config *config, guint i); + /* MSS */ void nm_ip4_config_set_mss (NMIP4Config *config, guint32 mss); guint32 nm_ip4_config_get_mss (const NMIP4Config *config); diff --git a/src/nm-ip6-config.c b/src/nm-ip6-config.c index 9d4bf47b20..5716af20c9 100644 --- a/src/nm-ip6-config.c +++ b/src/nm-ip6-config.c @@ -49,6 +49,7 @@ typedef struct { GArray *nameservers; GPtrArray *domains; GPtrArray *searches; + GPtrArray *dns_options; guint32 mss; int ifindex; } NMIP6ConfigPrivate; @@ -65,6 +66,7 @@ enum { PROP_NAMESERVERS, PROP_DOMAINS, PROP_SEARCHES, + PROP_DNS_OPTIONS, LAST_PROP }; @@ -499,6 +501,12 @@ nm_ip6_config_merge_setting (NMIP6Config *config, NMSettingIPConfig *setting, gu for (i = 0; i < nsearches; i++) nm_ip6_config_add_search (config, nm_setting_ip_config_get_dns_search (setting, i)); + i = 0; + while ((i = nm_setting_ip_config_next_valid_dns_option (setting, i)) >= 0) { + nm_ip6_config_add_dns_option (config, nm_setting_ip_config_get_dns_option (setting, i)); + i++; + } + g_object_thaw_notify (G_OBJECT (config)); } @@ -507,7 +515,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) { NMSettingIPConfig *s_ip6; const struct in6_addr *gateway; - guint naddresses, nroutes, nnameservers, nsearches; + guint naddresses, nroutes, nnameservers, nsearches, noptions; const char *method = NULL; int i; @@ -525,6 +533,7 @@ nm_ip6_config_create_setting (const NMIP6Config *config) nroutes = nm_ip6_config_get_num_routes (config); nnameservers = nm_ip6_config_get_num_nameservers (config); nsearches = nm_ip6_config_get_num_searches (config); + noptions = nm_ip6_config_get_num_dns_options (config); /* Addresses */ for (i = 0; i < naddresses; i++) { @@ -602,6 +611,12 @@ nm_ip6_config_create_setting (const NMIP6Config *config) nm_setting_ip_config_add_dns_search (s_ip6, search); } + for (i = 0; i < noptions; i++) { + const char *option = nm_ip6_config_get_dns_option (config, i); + + nm_setting_ip_config_add_dns_option (s_ip6, option); + } + return NM_SETTING (s_ip6); } @@ -642,6 +657,10 @@ nm_ip6_config_merge (NMIP6Config *dst, const NMIP6Config *src) for (i = 0; i < nm_ip6_config_get_num_searches (src); i++) nm_ip6_config_add_search (dst, nm_ip6_config_get_search (src, i)); + /* dns options */ + for (i = 0; i < nm_ip6_config_get_num_dns_options (src); i++) + nm_ip6_config_add_dns_option (dst, nm_ip6_config_get_dns_option (src, i)); + if (!nm_ip6_config_get_mss (dst)) nm_ip6_config_set_mss (dst, nm_ip6_config_get_mss (src)); @@ -742,6 +761,21 @@ _searches_get_index (const NMIP6Config *self, const char *search) return -1; } +static int +_dns_options_get_index (const NMIP6Config *self, const char *option) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (self); + guint i; + + for (i = 0; i < priv->dns_options->len; i++) { + const char *s = g_ptr_array_index (priv->dns_options, i); + + if (g_strcmp0 (option, s) == 0) + return (int) i; + } + return -1; +} + /*******************************************************************************/ /** @@ -807,6 +841,13 @@ nm_ip6_config_subtract (NMIP6Config *dst, const NMIP6Config *src) nm_ip6_config_del_search (dst, idx); } + /* dns options */ + for (i = 0; i < nm_ip6_config_get_num_dns_options (src); i++) { + idx = _dns_options_get_index (dst, nm_ip6_config_get_dns_option (src, i)); + if (idx >= 0) + nm_ip6_config_del_dns_option (dst, idx); + } + if (nm_ip6_config_get_mss (src) == nm_ip6_config_get_mss (dst)) nm_ip6_config_set_mss (dst, 0); @@ -857,6 +898,7 @@ nm_ip6_config_intersect (NMIP6Config *dst, const NMIP6Config *src) /* ignore domains */ /* ignore dns searches */ + /* ignome dns options */ g_object_thaw_notify (G_OBJECT (dst)); } @@ -1021,6 +1063,25 @@ nm_ip6_config_replace (NMIP6Config *dst, const NMIP6Config *src, gboolean *relev has_relevant_changes = TRUE; } + /* dns options */ + num = nm_ip6_config_get_num_dns_options (src); + are_equal = num == nm_ip6_config_get_num_dns_options (dst); + if (are_equal) { + for (i = 0; i < num; i++ ) { + if (g_strcmp0 (nm_ip6_config_get_dns_option (src, i), + nm_ip6_config_get_dns_option (dst, i))) { + are_equal = FALSE; + break; + } + } + } + if (!are_equal) { + nm_ip6_config_reset_dns_options (dst); + for (i = 0; i < num; i++) + nm_ip6_config_add_dns_option (dst, nm_ip6_config_get_dns_option (src, i)); + has_relevant_changes = TRUE; + } + /* mss */ if (src_priv->mss != dst_priv->mss) { nm_ip6_config_set_mss (dst, src_priv->mss); @@ -1081,6 +1142,10 @@ nm_ip6_config_dump (const NMIP6Config *config, const char *detail) for (i = 0; i < nm_ip6_config_get_num_searches (config); i++) g_message (" search: %s", nm_ip6_config_get_search (config, i)); + /* dns options */ + for (i = 0; i < nm_ip6_config_get_num_dns_options (config); i++) + g_message (" dnsopt: %s", nm_ip6_config_get_dns_option (config, i)); + g_message (" mss: %"G_GUINT32_FORMAT, nm_ip6_config_get_mss (config)); g_message (" n-dflt: %d", nm_ip6_config_get_never_default (config)); } @@ -1563,6 +1628,63 @@ nm_ip6_config_get_search (const NMIP6Config *config, guint i) /******************************************************************/ +void +nm_ip6_config_reset_dns_options (NMIP6Config *config) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + if (priv->dns_options->len != 0) { + g_ptr_array_set_size (priv->dns_options, 0); + _NOTIFY (config, PROP_DNS_OPTIONS); + } +} + +void +nm_ip6_config_add_dns_option (NMIP6Config *config, const char *new) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + int i; + + g_return_if_fail (new != NULL); + g_return_if_fail (new[0] != '\0'); + + for (i = 0; i < priv->dns_options->len; i++) + if (!g_strcmp0 (g_ptr_array_index (priv->dns_options, i), new)) + return; + + g_ptr_array_add (priv->dns_options, g_strdup (new)); + _NOTIFY (config, PROP_DNS_OPTIONS); +} + +void +nm_ip6_config_del_dns_option (NMIP6Config *config, guint i) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + g_return_if_fail (i < priv->dns_options->len); + + g_ptr_array_remove_index (priv->dns_options, i); + _NOTIFY (config, PROP_DNS_OPTIONS); +} + +guint32 +nm_ip6_config_get_num_dns_options (const NMIP6Config *config) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + return priv->dns_options->len; +} + +const char * +nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i) +{ + NMIP6ConfigPrivate *priv = NM_IP6_CONFIG_GET_PRIVATE (config); + + return g_ptr_array_index (priv->dns_options, i); +} + +/******************************************************************/ + void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss) { @@ -1637,6 +1759,12 @@ nm_ip6_config_hash (const NMIP6Config *config, GChecksum *sum, gboolean dns_only s = nm_ip6_config_get_search (config, i); g_checksum_update (sum, (const guint8 *) s, strlen (s)); } + + for (i = 0; i < nm_ip6_config_get_num_dns_options (config); i++) { + s = nm_ip6_config_get_dns_option (config, i); + g_checksum_update (sum, (const guint8 *) s, strlen (s)); + } + } /** @@ -1691,6 +1819,7 @@ nm_ip6_config_init (NMIP6Config *config) priv->nameservers = g_array_new (FALSE, TRUE, sizeof (struct in6_addr)); priv->domains = g_ptr_array_new_with_free_func (g_free); priv->searches = g_ptr_array_new_with_free_func (g_free); + priv->dns_options = g_ptr_array_new_with_free_func (g_free); } static void @@ -1705,6 +1834,7 @@ finalize (GObject *object) g_array_unref (priv->nameservers); g_ptr_array_unref (priv->domains); g_ptr_array_unref (priv->searches); + g_ptr_array_unref (priv->dns_options); G_OBJECT_CLASS (nm_ip6_config_parent_class)->finalize (object); } @@ -1926,6 +2056,9 @@ get_property (GObject *object, guint prop_id, case PROP_SEARCHES: g_value_set_boxed (value, priv->searches); break; + case PROP_DNS_OPTIONS: + g_value_set_boxed (value, priv->dns_options); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2009,6 +2142,11 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class) DBUS_TYPE_G_ARRAY_OF_STRING, G_PARAM_READABLE | G_PARAM_STATIC_STRINGS); + obj_properties[PROP_DNS_OPTIONS] = + g_param_spec_boxed (NM_IP6_CONFIG_DNS_OPTIONS, "", "", + DBUS_TYPE_G_ARRAY_OF_STRING, + G_PARAM_READABLE | + G_PARAM_STATIC_STRINGS); g_object_class_install_properties (object_class, LAST_PROP, obj_properties); diff --git a/src/nm-ip6-config.h b/src/nm-ip6-config.h index e0527e5e55..28513c2174 100644 --- a/src/nm-ip6-config.h +++ b/src/nm-ip6-config.h @@ -49,6 +49,7 @@ typedef struct { #define NM_IP6_CONFIG_NAMESERVERS "nameservers" #define NM_IP6_CONFIG_DOMAINS "domains" #define NM_IP6_CONFIG_SEARCHES "searches" +#define NM_IP6_CONFIG_DNS_OPTIONS "dns-options" /* deprecated */ #define NM_IP6_CONFIG_ADDRESSES "addresses" @@ -126,6 +127,13 @@ void nm_ip6_config_del_search (NMIP6Config *config, guint i); guint32 nm_ip6_config_get_num_searches (const NMIP6Config *config); const char * nm_ip6_config_get_search (const NMIP6Config *config, guint i); +/* DNS options */ +void nm_ip6_config_reset_dns_options (NMIP6Config *config); +void nm_ip6_config_add_dns_option (NMIP6Config *config, const char *option); +void nm_ip6_config_del_dns_option (NMIP6Config *config, guint i); +guint32 nm_ip6_config_get_num_dns_options (const NMIP6Config *config); +const char * nm_ip6_config_get_dns_option (const NMIP6Config *config, guint i); + /* MSS */ void nm_ip6_config_set_mss (NMIP6Config *config, guint32 mss); guint32 nm_ip6_config_get_mss (const NMIP6Config *config);