2008-03-07 Dan Williams <dcbw@redhat.com>

First pass of multiple active device support.  Expect bugs.

	* src/nm-ip4-config.c
	  src/nm-ip4-config.h
		- (nm_ip4_config_get_secondary, nm_ip4_config_set_secondary): remove;
			there are better ways to do this in the named manager

	* src/nm-device.c
	  src/nm-device.h
		- (nm_device_can_activate): return whether the device can activate a
			connection right now; taking into account things like carrier state
			and rfkill state
		- (nm_device_get_best_auto_connection): renamed from
			nm_device_get_best_connection
		- (real_act_stage4_get_ip4_config): MTU stuff is now handled in the
			device subclasses themselves, so that each device can override the
			MTU from it's NMSetting subclass if needed
		- (nm_device_set_ip4_config): set MTU when setting up routes and stuff
			in NetworkManagerSystem.c, not here

	* src/named-manager/nm-named-manager.c
	  src/named-manager/nm-named-manager.h
		- (nm_named_manager_name_owner_changed,
		   nm_named_manager_dbus_connection_changed): fix for changes to
			rewrite_resolv_conf()
		- (compute_nameservers): don't need the NMNamedManager at all, remove
			from parameter list
		- (merge_one_ip4_config): new function; merge ip4 configs together
		- (rewrite_resolv_conf): write out resolv.conf from all the stored
			ip4 configs; the VPN config takes precedence, then the best
			device config, then the rest of the configs
		- (get_domain_for_config): take the NMNamedManager as an argument
			to check whether the config is the VPN config
		- (add_ip4_config_to_named): fixups for removal of the 'secondary'
			attribute from ip4 configs
		- (add_all_ip4_configs_to_named): add all the configs in priority order
		- (remove_ip4_config_from_named): fix for changes to
			get_domain_for_config()
		- (nm_named_manager_add_ip4_config): assign the config to the right slot
			based on its type; callers must pass in the type now
		- (get_last_default_domain): remove, unused
		- (nm_named_manager_remove_ip4_config): handle config slots correctly

	* src/nm-device-802-11-wireless.c
		- (real_can_activate): new function
		- (real_get_best_auto_connection): renamed from real_get_best_connection
		- (real_act_stage4_get_ip4_config): handle MTU override

	* src/nm-device-802-3-ethernet.c
		- (real_can_activate): new function
		- (real_get_best_auto_connection): renamed from real_get_best_connection
		- (real_act_stage4_get_ip4_config): new function; handle MTU override

	* src/vpn-manager/nm-vpn-connection.c
		- (nm_vpn_connection_ip4_config_get): don't need to set the 'secondary'
			attribute on the ip4 config

	* src/NetworkManagerPolicy.c
		- (nm_policy_auto_get_best_device): remove
		- (nm_policy_device_change_check): remove
		- (update_default_route): new function; set the default route via
			the specified device
		- (get_device_priority): new function; return the priority number of
			a device type WRT which one should have the default route.  Order is
			(highest to lowest)  wired, wireless, GSM, CDMA.
		- (update_routing_and_dns): new function; determine which device should
			have the default route, then update the routing table and DNS
		- (maybe_auto_activate_device): new function; if a device is now
			available for activation, find out what connection it would like to
			activate and do it
		- (schedule_activate_check): new function; if a device can be activated
			now, schedule the activation.  Each device may have only one
			pending activation at a given time.
		- (device_state_changed): if activation was canceled, try again,
			possibly with another connection; if the device was activated,
			update routing and DNS; if the device was deactivated, try again
			with another connection
		- (device_carrier_changed): if there is no carrier, deactivate the
			device; otherwise schedule an activation check for the device
		- (wireless_networks_changed): schedule an activation check for the
			device
		- (device_added): keep track of the signal handler IDs so they can
			be removed when the device goes away
		- (device_removed): remove any signal handlers that might be attached
			to the device; update routing and DNS
		- (schedule_activate_all): new function
		- (connections_added, connection_added, connection_updated): when
			connections change, schedule all devices for an activation check
		- (connection_removed): when a device is deactivated because its
			connection was removed, schedule another activation check for it
		- (nm_policy_destroy): destroy pending activations and disconnect
			all device signal handlers

	* src/nm-manager.c
		- (nm_manager_activate_device): if the device was already actived,
			deactivate it
		- (deactivate_old_device): remove
		- (connection_added_default_handler, impl_manager_activate_device):
			don't deactivate other devices when activating this one

	* src/backends/NetworkManagerGentoo.c
	  src/backends/NetworkManagerFrugalware.c
	  src/backends/NetworkManagerPaldo.c
	  src/backends/NetworkManagerRedHat.c
	  src/backends/NetworkManagerSlackware.c
	  src/backends/NetworkManagerArch.c
	  src/backends/NetworkManagerSuSE.c
	  src/backends/NetworkManagerDebian.c
		- (nm_system_get_mtu): remove; MTU should be provided through the
			distro's system settings service plugin instead
		- (nm_system_device_add_default_route_via_device): remove
		- (nm_system_device_add_default_route_via_device_with_iface): remove
		- (nm_system_device_replace_default_route): new function; call
			generic implementation

	* src/backends/NetworkManagerGeneric.c
	  src/backends/NetworkManagerGeneric.h
		- (nm_generic_device_add_default_route_via_device,
		   nm_generic_device_add_default_route_via_device_with_iface): remove
		- (nm_generic_device_replace_default_route): replace the default route
			with the given route via some gateway

	* src/NetworkManagerSystem.c
	  src/NetworkManagerSystem.h
		- (nm_system_device_set_from_ip4_config): let the policy handle updates
			to routing and DNS; but set the MTU here
		- (nm_system_vpn_device_set_from_ip4_config): set the route with the
			ip_iface of the active device; use the standard MTU setting function
		- (nm_system_set_mtu): remove
		- (nm_system_device_set_mtu): consolidate MTU setting code in one place



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@3391 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2008-03-07 19:41:32 +00:00
parent d84a51a145
commit 3fec481414
25 changed files with 819 additions and 968 deletions

View File

@@ -36,6 +36,8 @@
#include <glib.h>
#include <dbus/dbus.h>
#include <glib/gi18n.h>
#include "nm-ip4-config.h"
#include "nm-utils.h"
#include "NetworkManagerSystem.h"
@@ -61,19 +63,20 @@ G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
NM_TYPE_NAMED_MANAGER, \
NMNamedManagerPrivate))
static NMIP4Config *get_last_default_domain (NMNamedManager *mgr);
static gboolean add_all_ip4_configs_to_named (NMNamedManager *mgr);
static gboolean rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error);
static gboolean rewrite_resolv_conf (NMNamedManager *mgr, GError **error);
static gboolean remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config);
struct NMNamedManagerPrivate {
gboolean use_named;
NMDBusManager * dbus_mgr;
GSList * configs;
gboolean use_named;
NMDBusManager * dbus_mgr;
NMIP4Config * vpn_config;
NMIP4Config * device_config;
GSList * configs;
gboolean disposed;
};
@@ -145,7 +148,7 @@ nm_named_manager_name_owner_changed (NMDBusManager *dbus_mgr,
if (handled) {
GError *error = NULL;
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
if (!rewrite_resolv_conf (mgr, &error)) {
nm_warning ("Could not write resolv.conf. Error: '%s'",
error ? error->message : "(none)");
g_error_free (error);
@@ -177,7 +180,7 @@ nm_named_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
if (handled) {
GError *error = NULL;
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error)) {
if (!rewrite_resolv_conf (mgr, &error)) {
nm_warning ("Could not write resolv.conf. Error: '%s'",
error ? error->message : "(none)");
g_error_free (error);
@@ -186,87 +189,79 @@ nm_named_manager_dbus_connection_changed (NMDBusManager *dbus_mgr,
}
static char *
compute_nameservers (NMNamedManager *mgr, NMIP4Config *config)
compute_nameservers (NMIP4Config *config)
{
int i, num_nameservers;
int i, num;
GString *str = NULL;
g_return_val_if_fail (mgr != NULL, g_strdup (""));
g_return_val_if_fail (config != NULL, g_strdup (""));
g_return_val_if_fail (config != NULL, NULL);
num_nameservers = nm_ip4_config_get_num_nameservers (config);
if (num_nameservers > 3)
num_nameservers = 3; /* 'man resolv.conf' says we can't have > 3 */
for (i = 0; i < num_nameservers; i++)
{
num = nm_ip4_config_get_num_nameservers (config);
if (num == 0)
return NULL;
str = g_string_new ("");
for (i = 0; i < num; i++) {
#define ADDR_BUF_LEN 50
struct in_addr addr;
char *buf;
if (!str)
str = g_string_new ("");
addr.s_addr = nm_ip4_config_get_nameserver (config, i);
buf = g_malloc0 (ADDR_BUF_LEN);
if (!buf)
continue;
inet_ntop (AF_INET, &addr, buf, ADDR_BUF_LEN);
if (i == 3) {
g_string_append (str, "# ");
g_string_append (str, _("NOTE: the glibc resolver does not support more than 3 nameservers."));
g_string_append (str, "\n# ");
g_string_append (str, _("The nameservers listed below may not be recognized."));
g_string_append_c (str, '\n');
}
g_string_append (str, "nameserver ");
g_string_append (str, buf);
g_string_append_c (str, '\n');
g_free (buf);
}
if (!str)
return g_strdup ("");
return g_string_free (str, FALSE);
}
static char *
compute_searches (NMNamedManager *mgr, NMIP4Config *config)
static void
merge_one_ip4_config (NMIP4Config *dst, NMIP4Config *src)
{
int i, num_searches;
GString *str = NULL;
guint32 num, i;
g_return_val_if_fail (mgr != NULL, g_strdup (""));
num = nm_ip4_config_get_num_nameservers (src);
for (i = 0; i < num; i++)
nm_ip4_config_add_nameserver (dst, nm_ip4_config_get_nameserver (src, i));
/* config can be NULL */
if (!config)
return g_strdup ("");
num_searches = nm_ip4_config_get_num_domains (config);
for (i = 0; i < num_searches; i++)
{
if (!str)
str = g_string_new ("search");
g_string_append_c (str, ' ');
g_string_append (str, nm_ip4_config_get_domain (config, i));
}
if (!str)
return g_strdup ("");
else
g_string_append_c (str, '\n');
return g_string_free (str, FALSE);
num = nm_ip4_config_get_num_domains (src);
for (i = 0; i < num; i++)
nm_ip4_config_add_domain (dst, nm_ip4_config_get_domain (src, i));
}
static gboolean
rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error)
rewrite_resolv_conf (NMNamedManager *mgr, GError **error)
{
const char * tmp_resolv_conf = RESOLV_CONF ".tmp";
char * searches = NULL;
FILE * f;
NMIP4Config *ns_config = config;
NMNamedManagerPrivate *priv;
const char *tmp_resolv_conf = RESOLV_CONF ".tmp";
char *searches = NULL;
guint32 num_domains, i;
NMIP4Config *composite;
GSList *iter;
FILE *f;
/* If no config, we don't have anything to update, so exit silently */
if (!config)
return TRUE;
g_return_val_if_fail (error != NULL, FALSE);
g_return_val_if_fail (*error == NULL, FALSE);
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
/* If the sysadmin disabled modifying resolv.conf, exit silently */
if (!nm_system_should_modify_resolv_conf ())
{
if (!nm_system_should_modify_resolv_conf ()) {
nm_info ("DHCP returned name servers but system has disabled dynamic modification!");
return TRUE;
}
@@ -290,85 +285,107 @@ rewrite_resolv_conf (NMNamedManager *mgr, NMIP4Config *config, GError **error)
return FALSE;
}
/* If the ip4 config is a secondary config and has no nameservers, use the
* nameservers from the primary config.
*/
if ( nm_ip4_config_get_secondary (config)
&& !nm_ip4_config_get_num_nameservers (config)) {
ns_config = mgr->priv->configs->data;
}
g_return_val_if_fail (ns_config != NULL, FALSE);
/* Construct the composite config from all the currently active IP4Configs */
composite = nm_ip4_config_new ();
searches = compute_searches (mgr, ns_config);
if (priv->vpn_config)
merge_one_ip4_config (composite, priv->vpn_config);
if (priv->device_config)
merge_one_ip4_config (composite, priv->device_config);
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
if ((config == priv->vpn_config) || (config == priv->device_config))
continue;
merge_one_ip4_config (composite, config);
}
/* Compute resolv.conf search domains */
num_domains = nm_ip4_config_get_num_domains (composite);
if (num_domains > 0) {
GString *str;
str = g_string_new ("search");
for (i = 0; i < num_domains; i++) {
g_string_append_c (str, ' ');
g_string_append (str, nm_ip4_config_get_domain (composite, i));
}
g_string_append_c (str, '\n');
searches = g_string_free (str, FALSE);
}
if (mgr->priv->use_named == TRUE) {
/* Using caching-nameserver & local DNS */
if (fprintf (f,
"%s%s%s",
"; Use a local caching nameserver controlled by NetworkManager\n\n",
searches,
searches ? searches : "",
"\nnameserver 127.0.0.1\n") < 0) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not write " RESOLV_CONF ": %s\n",
g_strerror (errno));
fclose (f);
g_free (searches);
return FALSE;
}
} else {
/* Using glibc resolver */
char *nameservers = compute_nameservers (mgr, ns_config);
char *nameservers = compute_nameservers (composite);
if ((fprintf (f, "%s\n\n", searches) < 0) ||
(fprintf (f, "%s\n\n", nameservers) < 0)) {
if ((fprintf (f, "%s\n\n", searches ? searches : "") < 0) ||
(fprintf (f, "%s\n\n", nameservers ? nameservers : "") < 0)) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not write to " RESOLV_CONF ": %s\n",
g_strerror (errno));
g_free (nameservers);
g_free (searches);
fclose (f);
return FALSE;
}
g_free (nameservers);
}
g_free (searches);
if (fclose (f) < 0) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not close " RESOLV_CONF ": %s\n",
g_strerror (errno));
return FALSE;
if (*error == NULL) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not close " RESOLV_CONF ": %s\n",
g_strerror (errno));
}
}
if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not replace " RESOLV_CONF ": %s\n",
g_strerror (errno));
return FALSE;
g_free (searches);
if (*error == NULL) {
if (rename (tmp_resolv_conf, RESOLV_CONF) < 0) {
g_set_error (error,
NM_NAMED_MANAGER_ERROR,
NM_NAMED_MANAGER_ERROR_SYSTEM,
"Could not replace " RESOLV_CONF ": %s\n",
g_strerror (errno));
} else {
nm_system_update_dns ();
}
}
nm_system_update_dns ();
return TRUE;
return *error ? FALSE : TRUE;
}
static const char *
get_domain_for_config (NMIP4Config *config, gboolean *dflt)
get_domain_for_config (NMNamedManager *mgr, NMIP4Config *config, gboolean *dflt)
{
NMNamedManagerPrivate *priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
gboolean is_dflt = FALSE;
const char *domain;
g_return_val_if_fail (config != NULL, NULL);
/* Primary configs always use default domain */
if (!nm_ip4_config_get_secondary (config))
if (config == priv->vpn_config)
is_dflt = TRUE;
/* Any config without a domain becomes default */
if (nm_ip4_config_get_num_domains (config) == 0)
is_dflt = TRUE;
@@ -387,6 +404,7 @@ get_domain_for_config (NMIP4Config *config, gboolean *dflt)
static gboolean
add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
{
NMNamedManagerPrivate *priv;
const char *domain;
NMIP4Config *ns_config = config;
int i, num_nameservers;
@@ -400,15 +418,17 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
dbus_error_init (&error);
dbus_connection = nm_dbus_manager_get_dbus_connection (mgr->priv->dbus_mgr);
dbus_connection = nm_dbus_manager_get_dbus_connection (priv->dbus_mgr);
if (!dbus_connection) {
nm_warning ("could not get dbus connection.");
goto out;
}
if (!(domain = get_domain_for_config (config, &dflt)))
if (!(domain = get_domain_for_config (mgr, config, &dflt)))
goto out;
message = dbus_message_new_method_call (NAMED_DBUS_SERVICE,
@@ -427,9 +447,9 @@ add_ip4_config_to_named (NMNamedManager *mgr, NMIP4Config *config)
/* If the ip4 config is a secondary config and has no nameservers, use the
* nameservers from the primary config.
*/
if ( nm_ip4_config_get_secondary (config)
if ( (config == priv->vpn_config)
&& !nm_ip4_config_get_num_nameservers (config)) {
ns_config = mgr->priv->configs->data;
ns_config = priv->device_config;
}
g_return_val_if_fail (ns_config != NULL, FALSE);
@@ -486,12 +506,27 @@ out:
static gboolean
add_all_ip4_configs_to_named (NMNamedManager *mgr)
{
GSList *elt = NULL;
NMNamedManagerPrivate *priv;
GSList *iter = NULL;
g_return_val_if_fail (mgr != NULL, FALSE);
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
add_ip4_config_to_named (mgr, (NMIP4Config *)(elt->data));
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
if (priv->vpn_config)
add_ip4_config_to_named (mgr, priv->vpn_config);
if (priv->device_config)
add_ip4_config_to_named (mgr, priv->device_config);
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
if ((config == priv->vpn_config) || (config == priv->device_config))
continue;
add_ip4_config_to_named (mgr, config);
}
return TRUE;
}
@@ -581,7 +616,7 @@ remove_ip4_config_from_named (NMNamedManager *mgr, NMIP4Config *config)
g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
if (!(domain = get_domain_for_config (config, NULL)))
if (!(domain = get_domain_for_config (mgr, config, NULL)))
return FALSE;
return remove_one_zone_from_named (mgr, domain);
@@ -675,32 +710,40 @@ out:
}
gboolean
nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
nm_named_manager_add_ip4_config (NMNamedManager *mgr,
NMIP4Config *config,
NMNamedIPConfigType cfg_type)
{
GError * error = NULL;
NMNamedManagerPrivate *priv;
GError *error = NULL;
g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
switch (cfg_type) {
case NM_NAMED_IP_CONFIG_TYPE_VPN:
priv->vpn_config = config;
break;
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
priv->device_config = config;
break;
default:
break;
}
/* Don't allow the same zone added twice */
if (g_slist_find (mgr->priv->configs, config))
return FALSE;
if (!g_slist_find (priv->configs, config))
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
/* First clear out and reload configs in named */
if (mgr->priv->use_named)
{
if (priv->use_named) {
remove_all_zones_from_named (mgr);
add_all_ip4_configs_to_named (mgr);
}
mgr->priv->configs = g_slist_append (mgr->priv->configs, g_object_ref (config));
/* Activate the zone config */
if (mgr->priv->use_named)
add_ip4_config_to_named (mgr, config);
if (!rewrite_resolv_conf (mgr, config, &error))
{
if (!rewrite_resolv_conf (mgr, &error)) {
nm_warning ("Could not commit DNS changes. Error: '%s'", error ? error->message : "(none)");
g_error_free (error);
}
@@ -708,60 +751,45 @@ nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
return TRUE;
}
static NMIP4Config *
get_last_default_domain (NMNamedManager *mgr)
{
GSList *elt = NULL;
NMIP4Config *last_default = NULL;
NMIP4Config *last = NULL;
for (elt = mgr->priv->configs; elt; elt = g_slist_next (elt))
{
gboolean dflt = FALSE;
const char *domain = NULL;
NMIP4Config *config = (NMIP4Config *)(elt->data);
last = config;
domain = get_domain_for_config (config, &dflt);
if (dflt)
last_default = config;
}
/* Fall back the last config added to the list if none are the default */
return (last_default ? last_default : last);
}
gboolean
nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config)
{
GError * error = NULL;
NMNamedManagerPrivate *priv;
GError *error = NULL;
g_return_val_if_fail (mgr != NULL, FALSE);
g_return_val_if_fail (config != NULL, FALSE);
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
/* Can't remove it if it wasn't in the list to begin with */
if (!g_slist_find (mgr->priv->configs, config))
if (!g_slist_find (priv->configs, config))
return FALSE;
/* Deactivate the config */
if (mgr->priv->use_named)
if (priv->use_named)
remove_ip4_config_from_named (mgr, config);
mgr->priv->configs = g_slist_remove (mgr->priv->configs, config);
priv->configs = g_slist_remove (priv->configs, config);
if (config == priv->vpn_config)
priv->vpn_config = NULL;
if (config == priv->device_config)
priv->device_config = NULL;
g_object_unref (config);
/* Clear out and reload configs since we may need a new
* default zone if the one we are removing was the old
* default zone.
*/
if (mgr->priv->use_named)
{
if (mgr->priv->use_named) {
remove_all_zones_from_named (mgr);
add_all_ip4_configs_to_named (mgr);
}
if (!rewrite_resolv_conf (mgr, get_last_default_domain (mgr), &error))
{
if (!rewrite_resolv_conf (mgr, &error)) {
nm_warning ("Could not commit DNS changes. Error: '%s'", error ? error->message : "(none)");
if (error)
g_error_free (error);

View File

@@ -28,14 +28,19 @@
#include <dbus/dbus.h>
#include "nm-ip4-config.h"
typedef enum
{
typedef enum {
NM_NAMED_MANAGER_ERROR_SYSTEM,
NM_NAMED_MANAGER_ERROR_INVALID_NAMESERVER,
NM_NAMED_MANAGER_ERROR_INVALID_HOST,
NM_NAMED_MANAGER_ERROR_INVALID_ID
} NMNamedManagerError;
typedef enum {
NM_NAMED_IP_CONFIG_TYPE_DEFAULT = 0,
NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE,
NM_NAMED_IP_CONFIG_TYPE_VPN
} NMNamedIPConfigType;
#define NM_NAMED_MANAGER_ERROR nm_named_manager_error_quark ()
GQuark nm_named_manager_error_quark (void);
@@ -64,7 +69,9 @@ GType nm_named_manager_get_type (void);
NMNamedManager * nm_named_manager_get (void);
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr, NMIP4Config *config);
gboolean nm_named_manager_add_ip4_config (NMNamedManager *mgr,
NMIP4Config *config,
NMNamedIPConfigType cfg_type);
gboolean nm_named_manager_remove_ip4_config (NMNamedManager *mgr, NMIP4Config *config);