mirror of
https://gitlab.freedesktop.org/NetworkManager/NetworkManager.git
synced 2026-02-07 20:20:34 +01:00
Merge remote branch 'origin/ip6only'
This commit is contained in:
commit
c3ebe98ae3
64 changed files with 2526 additions and 1895 deletions
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2009 Red Hat, Inc.
|
||||
* (C) Copyright 2009 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
|
@ -86,7 +86,7 @@ static TypeNameElement name_map[] = {
|
|||
{ "GPtrArray_GArray_guint__", "array of array of uint32" },
|
||||
{ "GPtrArray_GArray_guchar__", "array of byte array" },
|
||||
{ "GHashTable_gchararray+gchararray_", "dict of (string::string)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint__", "array of (byte array, uint32)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint+GArray_guchar___", "array of (byte array, uint32, byte array)" },
|
||||
{ "GPtrArray_GValueArray_GArray_guchar_+guint+GArray_guchar_+guint__", "array of (byte array, uint32, byte array, uint32)" },
|
||||
{ NULL, NULL }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@
|
|||
#define DBUS_TYPE_G_MAP_OF_STRING (dbus_g_type_get_map ("GHashTable", G_TYPE_STRING, G_TYPE_STRING))
|
||||
#define DBUS_TYPE_G_LIST_OF_STRING (dbus_g_type_get_collection ("GSList", G_TYPE_STRING))
|
||||
|
||||
#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ADDRESS))
|
||||
#define DBUS_TYPE_G_IP6_ROUTE (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE (dbus_g_type_get_collection ("GPtrArray", DBUS_TYPE_G_IP6_ROUTE))
|
||||
|
|
|
|||
|
|
@ -18,7 +18,10 @@
|
|||
<tp:docstring>The state of this active connection.</tp:docstring>
|
||||
</property>
|
||||
<property name="Default" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is the default connection, i.e. whether it currently owns the default route.</tp:docstring>
|
||||
<tp:docstring>Whether this active connection is the default IPv4 connection, i.e. whether it currently owns the default IPv4 route.</tp:docstring>
|
||||
</property>
|
||||
<property name="Default6" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is the default IPv6 connection, i.e. whether it currently owns the default IPv6 route.</tp:docstring>
|
||||
</property>
|
||||
<property name="Vpn" type="b" access="read">
|
||||
<tp:docstring>Whether this active connection is also a VPN connection.</tp:docstring>
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
<node name="/" xmlns:tp="http://telepathy.freedesktop.org/wiki/DbusSpec#extensions-v0">
|
||||
<interface name="org.freedesktop.NetworkManager.IP6Config">
|
||||
<property name="Addresses" type="a(ayu)" access="read">
|
||||
<tp:docstring>Tuples of IPv6 address/prefix.</tp:docstring>
|
||||
<property name="Addresses" type="a(ayuay)" access="read">
|
||||
<tp:docstring>Tuples of IPv6 address/prefix/gateway.</tp:docstring>
|
||||
</property>
|
||||
<property name="Nameservers" type="aay" access="read">
|
||||
<tp:docstring>The nameservers in use.</tp:docstring>
|
||||
|
|
|
|||
|
|
@ -132,7 +132,7 @@ libnm_glib_la_LIBADD = \
|
|||
$(GUDEV_LIBS)
|
||||
|
||||
libnm_glib_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-glib.ver \
|
||||
-version-info "4:1:2"
|
||||
-version-info "4:2:2"
|
||||
|
||||
noinst_PROGRAMS = libnm-glib-test
|
||||
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@ global:
|
|||
nm_access_point_new;
|
||||
nm_active_connection_get_connection;
|
||||
nm_active_connection_get_default;
|
||||
nm_active_connection_get_default6;
|
||||
nm_active_connection_get_devices;
|
||||
nm_active_connection_get_scope;
|
||||
nm_active_connection_get_service_name;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -50,6 +50,7 @@ typedef struct {
|
|||
GPtrArray *devices;
|
||||
NMActiveConnectionState state;
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
} NMActiveConnectionPrivate;
|
||||
|
||||
enum {
|
||||
|
|
@ -60,6 +61,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -70,6 +72,7 @@ enum {
|
|||
#define DBUS_PROP_DEVICES "Devices"
|
||||
#define DBUS_PROP_STATE "State"
|
||||
#define DBUS_PROP_DEFAULT "Default"
|
||||
#define DBUS_PROP_DEFAULT6 "Default6"
|
||||
|
||||
/**
|
||||
* nm_active_connection_new:
|
||||
|
|
@ -263,10 +266,10 @@ nm_active_connection_get_state (NMActiveConnection *connection)
|
|||
* nm_active_connection_get_default:
|
||||
* @connection: a #NMActiveConnection
|
||||
*
|
||||
* Whether the active connection is the default one (that is, is used for the default route
|
||||
* and DNS information).
|
||||
* Whether the active connection is the default IPv4 one (that is, is used for
|
||||
* the default IPv4 route and DNS information).
|
||||
*
|
||||
* Returns: %TRUE if the active connection is the default one
|
||||
* Returns: %TRUE if the active connection is the default IPv4 connection
|
||||
**/
|
||||
gboolean
|
||||
nm_active_connection_get_default (NMActiveConnection *connection)
|
||||
|
|
@ -278,13 +281,39 @@ nm_active_connection_get_default (NMActiveConnection *connection)
|
|||
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
|
||||
if (!priv->is_default) {
|
||||
priv->is_default = _nm_object_get_boolean_property (NM_OBJECT (connection),
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT);
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT);
|
||||
}
|
||||
|
||||
return priv->is_default;
|
||||
}
|
||||
|
||||
/**
|
||||
* nm_active_connection_get_default6:
|
||||
* @connection: a #NMActiveConnection
|
||||
*
|
||||
* Whether the active connection is the default IPv6 one (that is, is used for
|
||||
* the default IPv6 route and DNS information).
|
||||
*
|
||||
* Returns: %TRUE if the active connection is the default IPv6 connection
|
||||
**/
|
||||
gboolean
|
||||
nm_active_connection_get_default6 (NMActiveConnection *connection)
|
||||
{
|
||||
NMActiveConnectionPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_ACTIVE_CONNECTION (connection), FALSE);
|
||||
|
||||
priv = NM_ACTIVE_CONNECTION_GET_PRIVATE (connection);
|
||||
if (!priv->is_default6) {
|
||||
priv->is_default6 = _nm_object_get_boolean_property (NM_OBJECT (connection),
|
||||
NM_DBUS_INTERFACE_ACTIVE_CONNECTION,
|
||||
DBUS_PROP_DEFAULT6);
|
||||
}
|
||||
|
||||
return priv->is_default6;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_active_connection_init (NMActiveConnection *ap)
|
||||
{
|
||||
|
|
@ -350,6 +379,9 @@ get_property (GObject *object,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, nm_active_connection_get_default (self));
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, nm_active_connection_get_default6 (self));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -392,6 +424,7 @@ register_for_property_changed (NMActiveConnection *connection)
|
|||
{ NM_ACTIVE_CONNECTION_DEVICES, demarshal_devices, &priv->devices },
|
||||
{ NM_ACTIVE_CONNECTION_STATE, _nm_object_demarshal_generic, &priv->state },
|
||||
{ NM_ACTIVE_CONNECTION_DEFAULT, _nm_object_demarshal_generic, &priv->is_default },
|
||||
{ NM_ACTIVE_CONNECTION_DEFAULT6, _nm_object_demarshal_generic, &priv->is_default6 },
|
||||
{ NULL },
|
||||
};
|
||||
|
||||
|
|
@ -512,13 +545,26 @@ nm_active_connection_class_init (NMActiveConnectionClass *ap_class)
|
|||
/**
|
||||
* NMActiveConnection:default:
|
||||
*
|
||||
* Whether the active connection is the default one.
|
||||
* Whether the active connection is the default IPv4 one.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
/**
|
||||
* NMActiveConnection:default6:
|
||||
*
|
||||
* Whether the active connection is the default IPv6 one.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -45,6 +45,7 @@ G_BEGIN_DECLS
|
|||
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
|
||||
#define NM_ACTIVE_CONNECTION_STATE "state"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6"
|
||||
|
||||
typedef struct {
|
||||
NMObject parent;
|
||||
|
|
@ -73,6 +74,7 @@ const char * nm_active_connection_get_specific_object (NMActiveConnection *c
|
|||
const GPtrArray *nm_active_connection_get_devices (NMActiveConnection *connection);
|
||||
NMActiveConnectionState nm_active_connection_get_state (NMActiveConnection *connection);
|
||||
gboolean nm_active_connection_get_default (NMActiveConnection *connection);
|
||||
gboolean nm_active_connection_get_default6 (NMActiveConnection *connection);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -59,7 +59,7 @@ libnm_util_la_SOURCES= \
|
|||
libnm_util_la_LIBADD = $(GLIB_LIBS) $(DBUS_LIBS) $(UUID_LIBS)
|
||||
|
||||
libnm_util_la_LDFLAGS = -Wl,--version-script=$(srcdir)/libnm-util.ver \
|
||||
-version-info "4:2:3"
|
||||
-version-info "4:3:3"
|
||||
|
||||
if WITH_GNUTLS
|
||||
libnm_util_la_SOURCES += crypto_gnutls.c
|
||||
|
|
|
|||
|
|
@ -177,6 +177,8 @@ global:
|
|||
nm_ip6_address_compare;
|
||||
nm_ip6_address_get_address;
|
||||
nm_ip6_address_set_address;
|
||||
nm_ip6_address_get_gateway;
|
||||
nm_ip6_address_set_gateway;
|
||||
nm_ip6_address_get_prefix;
|
||||
nm_ip6_address_set_prefix;
|
||||
nm_ip6_route_new;
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -377,6 +377,7 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
GValue *tmp_val;
|
||||
GByteArray *addr1, *addr2;
|
||||
guint32 prefix1, prefix2;
|
||||
GByteArray *gw1, *gw2;
|
||||
gint ret = 0;
|
||||
int i;
|
||||
|
||||
|
|
@ -387,8 +388,8 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* Since they are NM IPv6 address structures, we expect both
|
||||
* to contain two elements as specified in nm-dbus-glib-types.h.
|
||||
*/
|
||||
g_return_val_if_fail (values1->n_values == 2, 0);
|
||||
g_return_val_if_fail (values2->n_values == 2, 0);
|
||||
g_return_val_if_fail (values1->n_values == 3, 0);
|
||||
g_return_val_if_fail (values2->n_values == 3, 0);
|
||||
|
||||
/* First struct IPv6 address */
|
||||
tmp_val = g_value_array_get_nth (values1, 0);
|
||||
|
|
@ -396,6 +397,9 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* First struct IPv6 prefix */
|
||||
tmp_val = g_value_array_get_nth (values1, 1);
|
||||
prefix1 = g_value_get_uint (tmp_val);
|
||||
/* First struct IPv6 gateway */
|
||||
tmp_val = g_value_array_get_nth (values1, 2);
|
||||
gw1 = g_value_get_boxed (tmp_val);
|
||||
|
||||
/* Second struct IPv6 address */
|
||||
tmp_val = g_value_array_get_nth (values2, 0);
|
||||
|
|
@ -403,6 +407,9 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
/* Second struct IPv6 prefix */
|
||||
tmp_val = g_value_array_get_nth (values2, 1);
|
||||
prefix2 = g_value_get_uint (tmp_val);
|
||||
/* Second struct IPv6 gateway */
|
||||
tmp_val = g_value_array_get_nth (values2, 2);
|
||||
gw2 = g_value_get_boxed (tmp_val);
|
||||
|
||||
/* Compare IPv6 addresses */
|
||||
if (prefix1 != prefix2)
|
||||
|
|
@ -413,6 +420,11 @@ nm_gvalue_ip6_address_compare (const GValue *value1, const GValue *value2)
|
|||
ret = addr1->data[i] < addr2->data[i] ? -1 : addr1->data[i] > addr2->data[i];
|
||||
}
|
||||
|
||||
if (!IN6_ARE_ADDR_EQUAL ((struct in6_addr *) gw1->data, (struct in6_addr *) gw2->data)) {
|
||||
for (i = 0; ret == 0 && i < gw1->len; i++)
|
||||
ret = gw1->data[i] < gw2->data[i] ? -1 : gw1->data[i] > gw2->data[i];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -462,7 +462,8 @@ verify (NMSetting *setting, GSList *all_settings, GError **error)
|
|||
return FALSE;
|
||||
}
|
||||
} else if ( !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL)
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)
|
||||
|| !strcmp (priv->method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
if (priv->dns && priv->dns->len) {
|
||||
g_set_error (error,
|
||||
NM_SETTING_IP4_CONFIG_ERROR,
|
||||
|
|
@ -721,7 +722,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* network access to other computers) then the interface is assigned an
|
||||
* address in the 10.42.x.1/24 range and a DHCP and forwarding DNS server
|
||||
* are started, and the interface is NAT-ed to the current default network
|
||||
* connection. This property must be set.
|
||||
* connection. 'disabled' means IPv4 will not be used on this connection.
|
||||
* This property must be set.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_METHOD,
|
||||
|
|
@ -742,7 +744,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"address in the 10.42.x.1/24 range and a DHCP and "
|
||||
"forwarding DNS server are started, and the "
|
||||
"interface is NAT-ed to the current default network "
|
||||
"connection. This property must be set.",
|
||||
"connection. 'disabled' means IPv4 will not be "
|
||||
"used on this connection. This property must be set.",
|
||||
NULL,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -751,8 +754,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
*
|
||||
* List of DNS servers (network byte order). For the 'auto' method, these
|
||||
* DNS servers are appended to those (if any) returned by automatic
|
||||
* configuration. DNS servers cannot be used with the 'shared' or
|
||||
* 'link-local' methods as there is no usptream network. In all other
|
||||
* configuration. DNS servers cannot be used with the 'shared', 'link-local',
|
||||
* or 'disabled' methods as there is no usptream network. In all other
|
||||
* methods, these DNS servers are used as the only DNS servers for this
|
||||
* connection.
|
||||
**/
|
||||
|
|
@ -764,10 +767,10 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"the 'auto' method, these DNS servers are "
|
||||
"appended to those (if any) returned by automatic "
|
||||
"configuration. DNS servers cannot be used with "
|
||||
"the 'shared' or 'link-local' methods as there is "
|
||||
"no usptream network. In all other methods, "
|
||||
"these DNS servers are used as the only DNS "
|
||||
"servers for this connection.",
|
||||
"the 'shared', 'link-local', or 'disabled' "
|
||||
"methods as there is no usptream network. In all "
|
||||
"other methods, these DNS servers are used as the "
|
||||
"only DNS servers for this connection.",
|
||||
DBUS_TYPE_G_UINT_ARRAY,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -776,9 +779,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
*
|
||||
* List of DNS search domains. For the 'auto' method, these search domains
|
||||
* are appended to those returned by automatic configuration. Search domains
|
||||
* cannot be used with the 'shared' or 'link-local' methods as there is no
|
||||
* upstream network. In all other methods, these search domains are used
|
||||
* as the only search domains for this connection.
|
||||
* cannot be used with the 'shared', 'link-local', or 'disabled' methods as
|
||||
* there is no upstream network. In all other methods, these search domains
|
||||
* are used as the only search domains for this connection.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DNS_SEARCH,
|
||||
|
|
@ -787,11 +790,11 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"List of DNS search domains. For the 'auto' "
|
||||
"method, these search domains are appended to "
|
||||
"those returned by automatic configuration. "
|
||||
"Search domains cannot be used with the 'shared' "
|
||||
"or 'link-local' methods as there is no upstream "
|
||||
"network. In all other methods, these search "
|
||||
"domains are used as the only search domains for "
|
||||
"this connection.",
|
||||
"Search domains cannot be used with the 'shared', "
|
||||
"'link-local', or 'disabled' methods as there is "
|
||||
"no upstream network. In all other methods, these "
|
||||
"search domains are used as the only search domains "
|
||||
"for this connection.",
|
||||
DBUS_TYPE_G_LIST_OF_STRING,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -804,8 +807,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* (network byte order). The gateway may be left as 0 if no gateway exists
|
||||
* for that subnet. For the 'auto' method, given IP addresses are appended
|
||||
* to those returned by automatic configuration. Addresses cannot be used
|
||||
* with the 'shared' or 'link-local' methods as the interface is
|
||||
* automatically assigned an address with these methods.
|
||||
* with the 'shared', 'link-local', or 'disabled' methods as addressing is
|
||||
* either automatic or disabled with these methods.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
|
|
@ -820,9 +823,9 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"for that subnet. For the 'auto' method, given "
|
||||
"IP addresses are appended to those returned by "
|
||||
"automatic configuration. Addresses cannot be "
|
||||
"used with the 'shared' or 'link-local' methods "
|
||||
"as the interface is automatically assigned an "
|
||||
"address with these methods.",
|
||||
"used with the 'shared', 'link-local', or "
|
||||
"'disabled' methods as addressing is either "
|
||||
"automatic or disabled with these methods.",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
@ -835,8 +838,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
* address prefix (1 - 32), the third being the next-hop (network byte
|
||||
* order) if any, and the fourth being the route metric. For the 'auto'
|
||||
* method, given IP routes are appended to those returned by automatic
|
||||
* configuration. Routes cannot be used with the 'shared' or 'link-local'
|
||||
* methods because there is no upstream network.
|
||||
* configuration. Routes cannot be used with the 'shared', 'link-local',
|
||||
* or 'disabled' methods because there is no upstream network.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ROUTES,
|
||||
|
|
@ -852,8 +855,8 @@ nm_setting_ip4_config_class_init (NMSettingIP4ConfigClass *setting_class)
|
|||
"For the 'auto' method, given IP routes are "
|
||||
"appended to those returned by automatic "
|
||||
"configuration. Routes cannot be used with the "
|
||||
"'shared' or 'link-local' methods as there is no "
|
||||
"upstream network.",
|
||||
"'shared', 'link-local', or 'disabled', methods "
|
||||
"as there is no upstream network.",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE));
|
||||
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@
|
|||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||
* Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2007 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -69,6 +69,7 @@ GQuark nm_setting_ip4_config_error_quark (void);
|
|||
#define NM_SETTING_IP4_CONFIG_METHOD_LINK_LOCAL "link-local"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_MANUAL "manual"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_SHARED "shared"
|
||||
#define NM_SETTING_IP4_CONFIG_METHOD_DISABLED "disabled"
|
||||
|
||||
typedef struct NMIP4Address NMIP4Address;
|
||||
|
||||
|
|
|
|||
|
|
@ -684,25 +684,32 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
|
|||
* NMSettingIP6Config:addresses:
|
||||
*
|
||||
* Array of IPv6 address structures. Each IPv6 address structure is
|
||||
* composed of 2 members, the first being a byte array containing the IPv6
|
||||
* address (network byte order) and the second a 32-bit integer containing
|
||||
* the IPv6 address prefix. For the 'auto' method, given IP addresses are
|
||||
* appended to those returned by automatic configuration. Addresses cannot
|
||||
* be used with the 'shared' or 'link-local' methods as the interface is
|
||||
* automatically assigned an address with these methods.
|
||||
* composed of 3 members, the first being a byte array containing the IPv6
|
||||
* address (network byte order), the second a 32-bit integer containing the
|
||||
* IPv6 address prefix, and the third a byte array containing the IPv6
|
||||
* address (network byte order) of the gateway associated with this address,
|
||||
* if any. If no gateway is given, the third element should be given as
|
||||
* all zeros. For the 'auto' method, given IP addresses are appended to
|
||||
* those returned by automatic configuration. Addresses cannot be used with
|
||||
* the 'shared' or 'link-local' methods as the interface is automatically
|
||||
* assigned an address with these methods.
|
||||
**/
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
_nm_param_spec_specialized (NM_SETTING_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"Array of IPv6 address structures. Each IPv6 "
|
||||
"address structure is composed of 2 members, the "
|
||||
"address structure is composed of 3 members, the "
|
||||
"first being a byte array containing the IPv6 "
|
||||
"address (network byte order) and the second a "
|
||||
"address (network byte order), the second a "
|
||||
"32-bit integer containing the IPv6 address "
|
||||
"prefix. For the 'auto' method, given IP "
|
||||
"addresses are appended to those returned by "
|
||||
"automatic configuration. Addresses cannot be "
|
||||
"prefix, and the third a byte array containing "
|
||||
"the IPv6 address (network byte order) of the "
|
||||
"gateway associated with this address, if any. "
|
||||
"If no gateway is given, the third element should "
|
||||
"be given as all zeros. For the 'auto' method, "
|
||||
"given IP addresses are appended to those returned "
|
||||
"by automatic configuration. Addresses cannot be "
|
||||
"used with the 'shared' or 'link-local' methods "
|
||||
"as the interface is automatically assigned an "
|
||||
"address with these methods.",
|
||||
|
|
@ -797,10 +804,13 @@ nm_setting_ip6_config_class_init (NMSettingIP6ConfigClass *setting_class)
|
|||
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
struct NMIP6Address {
|
||||
guint32 refcount;
|
||||
struct in6_addr address;
|
||||
guint32 prefix;
|
||||
struct in6_addr gateway;
|
||||
};
|
||||
|
||||
NMIP6Address *
|
||||
|
|
@ -902,6 +912,27 @@ nm_ip6_address_set_prefix (NMIP6Address *address, guint32 prefix)
|
|||
address->prefix = prefix;
|
||||
}
|
||||
|
||||
const struct in6_addr *
|
||||
nm_ip6_address_get_gateway (NMIP6Address *address)
|
||||
{
|
||||
g_return_val_if_fail (address != NULL, 0);
|
||||
g_return_val_if_fail (address->refcount > 0, 0);
|
||||
|
||||
return &address->gateway;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_address_set_gateway (NMIP6Address *address, const struct in6_addr *gw)
|
||||
{
|
||||
g_return_if_fail (address != NULL);
|
||||
g_return_if_fail (address->refcount > 0);
|
||||
g_return_if_fail (gw != NULL);
|
||||
|
||||
memcpy (&address->gateway, gw, sizeof (struct in6_addr));
|
||||
}
|
||||
|
||||
/********************************************************************/
|
||||
|
||||
struct NMIP6Route {
|
||||
guint32 refcount;
|
||||
|
||||
|
|
|
|||
|
|
@ -88,6 +88,10 @@ guint32 nm_ip6_address_get_prefix (NMIP6Address *address);
|
|||
void nm_ip6_address_set_prefix (NMIP6Address *address,
|
||||
guint32 prefix);
|
||||
|
||||
const struct in6_addr *nm_ip6_address_get_gateway (NMIP6Address *address);
|
||||
void nm_ip6_address_set_gateway (NMIP6Address *address,
|
||||
const struct in6_addr *gw);
|
||||
|
||||
typedef struct NMIP6Route NMIP6Route;
|
||||
|
||||
NMIP6Route * nm_ip6_route_new (void);
|
||||
|
|
|
|||
|
|
@ -275,6 +275,8 @@ nm_utils_init (GError **error)
|
|||
if (!crypto_init (error))
|
||||
return FALSE;
|
||||
|
||||
_nm_utils_register_value_transformations ();
|
||||
|
||||
atexit (nm_utils_deinit);
|
||||
initialized = TRUE;
|
||||
}
|
||||
|
|
@ -745,7 +747,8 @@ nm_utils_convert_string_hash_to_string (const GValue *src_value, GValue *dest_va
|
|||
hash = (GHashTable *) g_value_get_boxed (src_value);
|
||||
|
||||
printable = g_string_new ("[");
|
||||
g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
|
||||
if (hash)
|
||||
g_hash_table_foreach (hash, convert_one_string_hash_entry, printable);
|
||||
g_string_append (printable, " ]");
|
||||
|
||||
g_value_take_string (dest_value, printable->str);
|
||||
|
|
@ -886,6 +889,19 @@ nm_utils_convert_ip6_addr_struct_array_to_string (const GValue *src_value, GValu
|
|||
continue;
|
||||
}
|
||||
g_string_append_printf (printable, "px = %u", prefix);
|
||||
g_string_append (printable, ", ");
|
||||
|
||||
/* IPv6 Gateway */
|
||||
tmp = g_value_array_get_nth (elements, 2);
|
||||
ba_addr = g_value_get_boxed (tmp);
|
||||
if (ba_addr->len != 16) {
|
||||
g_string_append (printable, "invalid");
|
||||
continue;
|
||||
}
|
||||
addr = (struct in6_addr *) ba_addr->data;
|
||||
memset (buf, 0, sizeof (buf));
|
||||
nm_utils_inet6_ntop (addr, buf);
|
||||
g_string_append_printf (printable, "gw = %s", buf);
|
||||
g_string_append (printable, " }");
|
||||
}
|
||||
g_string_append_c (printable, ']');
|
||||
|
|
@ -977,6 +993,58 @@ nm_utils_convert_ip6_route_struct_array_to_string (const GValue *src_value, GVal
|
|||
g_string_free (printable, FALSE);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
static void
|
||||
nm_utils_convert_old_ip6_addr_array (const GValue *src_value, GValue *dst_value)
|
||||
{
|
||||
GPtrArray *src_outer_array;
|
||||
GPtrArray *dst_outer_array;
|
||||
guint i;
|
||||
|
||||
g_return_if_fail (g_type_is_a (G_VALUE_TYPE (src_value), OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS));
|
||||
|
||||
src_outer_array = (GPtrArray *) g_value_get_boxed (src_value);
|
||||
dst_outer_array = g_ptr_array_new ();
|
||||
|
||||
for (i = 0; src_outer_array && (i < src_outer_array->len); i++) {
|
||||
GValueArray *src_addr_array;
|
||||
GValueArray *dst_addr_array;
|
||||
GValue element = {0, };
|
||||
GValue *src_addr, *src_prefix;
|
||||
GByteArray *ba;
|
||||
|
||||
src_addr_array = (GValueArray *) g_ptr_array_index (src_outer_array, i);
|
||||
|
||||
if ( (src_addr_array->n_values != 2)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (src_addr_array, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (src_addr_array, 1)) != G_TYPE_UINT)) {
|
||||
g_warning ("%s: invalid old IPv6 address type", __func__);
|
||||
return;
|
||||
}
|
||||
|
||||
dst_addr_array = g_value_array_new (3);
|
||||
|
||||
src_addr = g_value_array_get_nth (src_addr_array, 0);
|
||||
g_value_array_append (dst_addr_array, src_addr);
|
||||
src_prefix = g_value_array_get_nth (src_addr_array, 1);
|
||||
g_value_array_append (dst_addr_array, src_prefix);
|
||||
|
||||
/* Blank Gateway */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0", 16);
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (dst_addr_array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (dst_outer_array, dst_addr_array);
|
||||
}
|
||||
|
||||
g_value_take_boxed (dst_value, dst_outer_array);
|
||||
}
|
||||
|
||||
void
|
||||
_nm_utils_register_value_transformations (void)
|
||||
{
|
||||
|
|
@ -1013,6 +1081,9 @@ _nm_utils_register_value_transformations (void)
|
|||
g_value_register_transform_func (DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
|
||||
G_TYPE_STRING,
|
||||
nm_utils_convert_ip6_route_struct_array_to_string);
|
||||
g_value_register_transform_func (OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
nm_utils_convert_old_ip6_addr_array);
|
||||
registered = TRUE;
|
||||
}
|
||||
}
|
||||
|
|
@ -1459,8 +1530,8 @@ nm_utils_ip4_get_default_prefix (guint32 ip)
|
|||
* @value: gvalue containing a GPtrArray of GValueArrays of (GArray of guchars) and guint32
|
||||
*
|
||||
* Utility function to convert a #GPtrArray of #GValueArrays of (#GArray of guchars) and guint32
|
||||
* representing a list of NetworkManager IPv6 addresses (which is a pair of address
|
||||
* and prefix), into a GSList of #NMIP6Address objects. The specific format of
|
||||
* representing a list of NetworkManager IPv6 addresses (which is a tuple of address,
|
||||
* prefix, and gateway), into a GSList of #NMIP6Address objects. The specific format of
|
||||
* this serialization is not guaranteed to be stable and the #GValueArray may be
|
||||
* extended in the future.
|
||||
*
|
||||
|
|
@ -1479,16 +1550,28 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
GValueArray *elements = (GValueArray *) g_ptr_array_index (addresses, i);
|
||||
GValue *tmp;
|
||||
GByteArray *ba_addr;
|
||||
GByteArray *ba_gw = NULL;
|
||||
NMIP6Address *addr;
|
||||
guint32 prefix;
|
||||
|
||||
if ( (elements->n_values != 2)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
if (elements->n_values < 2 || elements->n_values > 3) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( (G_VALUE_TYPE (g_value_array_get_nth (elements, 0)) != DBUS_TYPE_G_UCHAR_ARRAY)
|
||||
|| (G_VALUE_TYPE (g_value_array_get_nth (elements, 1)) != G_TYPE_UINT)) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* Check optional 3rd element (gateway) */
|
||||
if ( elements->n_values == 3
|
||||
&& (G_VALUE_TYPE (g_value_array_get_nth (elements, 2)) != DBUS_TYPE_G_UCHAR_ARRAY)) {
|
||||
nm_warning ("%s: ignoring invalid IP6 address structure", __func__);
|
||||
continue;
|
||||
}
|
||||
|
||||
tmp = g_value_array_get_nth (elements, 0);
|
||||
ba_addr = g_value_get_boxed (tmp);
|
||||
if (ba_addr->len != 16) {
|
||||
|
|
@ -1505,9 +1588,22 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (elements->n_values == 3) {
|
||||
tmp = g_value_array_get_nth (elements, 2);
|
||||
ba_gw = g_value_get_boxed (tmp);
|
||||
if (ba_gw->len != 16) {
|
||||
nm_warning ("%s: ignoring invalid IP6 gateway address of length %d",
|
||||
__func__, ba_gw->len);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
addr = nm_ip6_address_new ();
|
||||
nm_ip6_address_set_prefix (addr, prefix);
|
||||
nm_ip6_address_set_address (addr, (const struct in6_addr *) ba_addr->data);
|
||||
if (ba_gw)
|
||||
nm_ip6_address_set_gateway (addr, (const struct in6_addr *) ba_gw->data);
|
||||
|
||||
list = g_slist_prepend (list, addr);
|
||||
}
|
||||
|
||||
|
|
@ -1522,10 +1618,10 @@ nm_utils_ip6_addresses_from_gvalue (const GValue *value)
|
|||
* g_value_unset().
|
||||
*
|
||||
* Utility function to convert a #GSList of #NMIP6Address objects into a
|
||||
* GPtrArray of GValueArrays of (GArray or guchars) and guint32 representing a list
|
||||
* of NetworkManager IPv6 addresses (which is a pair of address and prefix).
|
||||
* The specific format of this serialization is not guaranteed to be stable and may be
|
||||
* extended in the future.
|
||||
* GPtrArray of GValueArrays representing a list of NetworkManager IPv6 addresses
|
||||
* (which is a tuple of address, prefix, and gateway). The specific format of
|
||||
* this serialization is not guaranteed to be stable and may be extended in the
|
||||
* future.
|
||||
**/
|
||||
void
|
||||
nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
||||
|
|
@ -1541,8 +1637,9 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
|||
GValue element = {0, };
|
||||
GByteArray *ba;
|
||||
|
||||
array = g_value_array_new (2);
|
||||
array = g_value_array_new (3);
|
||||
|
||||
/* IP address */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_address (addr), 16);
|
||||
|
|
@ -1550,11 +1647,20 @@ nm_utils_ip6_addresses_to_gvalue (GSList *list, GValue *value)
|
|||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Prefix */
|
||||
g_value_init (&element, G_TYPE_UINT);
|
||||
g_value_set_uint (&element, nm_ip6_address_get_prefix (addr));
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Gateway */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, (guint8 *) nm_ip6_address_get_gateway (addr), 16);
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (addresses, array);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2008 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*
|
||||
*/
|
||||
|
||||
|
|
@ -28,7 +28,8 @@
|
|||
|
||||
#include "nm-setting-connection.h"
|
||||
#include "nm-setting-vpn.h"
|
||||
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-dbus-glib-types.h"
|
||||
|
||||
static void
|
||||
vpn_check_func (const char *key, const char *value, gpointer user_data)
|
||||
|
|
@ -128,6 +129,99 @@ test_setting_vpn_items (void)
|
|||
g_object_unref (s_vpn);
|
||||
}
|
||||
|
||||
#define OLD_DBUS_TYPE_G_IP6_ADDRESS (dbus_g_type_get_struct ("GValueArray", DBUS_TYPE_G_UCHAR_ARRAY, G_TYPE_UINT, G_TYPE_INVALID))
|
||||
#define OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS (dbus_g_type_get_collection ("GPtrArray", OLD_DBUS_TYPE_G_IP6_ADDRESS))
|
||||
|
||||
/* Test that setting the IPv6 setting's 'addresses' property using the old
|
||||
* IPv6 address format still works, i.e. that the GValue transformation function
|
||||
* from old->new is working correctly.
|
||||
*/
|
||||
static void
|
||||
test_setting_ip6_config_old_address_array (void)
|
||||
{
|
||||
NMSettingIP6Config *s_ip6;
|
||||
GPtrArray *addresses, *read_addresses;
|
||||
GValueArray *array, *read_array;
|
||||
GValue element = {0, }, written_value = {0, }, read_value = {0, };
|
||||
GByteArray *ba;
|
||||
const guint8 addr[16] = { 0x88, 0x77, 0x66, 0x55, 0x44, 0x33, 0x22, 0x11,
|
||||
0x11, 0x22, 0x33, 0x44, 0x66, 0x77, 0x88, 0x99 };
|
||||
const guint8 gw[16] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 };
|
||||
guint32 prefix = 56;
|
||||
GValue *read_addr, *read_prefix, *read_gw;
|
||||
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
ASSERT (s_ip6 != NULL,
|
||||
"ip6-old-addr", "error creating IP6 setting");
|
||||
|
||||
g_value_init (&written_value, OLD_DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
|
||||
|
||||
addresses = g_ptr_array_new ();
|
||||
array = g_value_array_new (3);
|
||||
|
||||
/* IP address */
|
||||
g_value_init (&element, DBUS_TYPE_G_UCHAR_ARRAY);
|
||||
ba = g_byte_array_new ();
|
||||
g_byte_array_append (ba, &addr[0], sizeof (addr));
|
||||
g_value_take_boxed (&element, ba);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
/* Prefix */
|
||||
g_value_init (&element, G_TYPE_UINT);
|
||||
g_value_set_uint (&element, prefix);
|
||||
g_value_array_append (array, &element);
|
||||
g_value_unset (&element);
|
||||
|
||||
g_ptr_array_add (addresses, array);
|
||||
g_value_set_boxed (&written_value, addresses);
|
||||
|
||||
/* Set the address array on the object */
|
||||
g_object_set_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &written_value);
|
||||
|
||||
/* Get it back so we can compare it */
|
||||
g_value_init (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS);
|
||||
g_object_get_property (G_OBJECT (s_ip6), NM_SETTING_IP6_CONFIG_ADDRESSES, &read_value);
|
||||
|
||||
ASSERT (G_VALUE_HOLDS (&read_value, DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS),
|
||||
"ip6-old-addr", "wrong addresses property value type '%s'",
|
||||
G_VALUE_TYPE_NAME (&read_value));
|
||||
|
||||
read_addresses = (GPtrArray *) g_value_get_boxed (&read_value);
|
||||
ASSERT (read_addresses != NULL,
|
||||
"ip6-old-addr", "missing addresses on readback");
|
||||
ASSERT (read_addresses->len == 1,
|
||||
"ip6-old-addr", "expected one address on readback");
|
||||
|
||||
read_array = (GValueArray *) g_ptr_array_index (read_addresses, 0);
|
||||
|
||||
read_addr = g_value_array_get_nth (read_array, 0);
|
||||
ba = g_value_get_boxed (read_addr);
|
||||
ASSERT (ba->len == sizeof (addr),
|
||||
"ip6-old-addr", "unexpected address item length %d", ba->len);
|
||||
ASSERT (memcmp (ba->data, &addr[0], sizeof (addr)) == 0,
|
||||
"ip6-old-addr", "unexpected failure comparing addresses");
|
||||
|
||||
read_prefix = g_value_array_get_nth (read_array, 1);
|
||||
ASSERT (g_value_get_uint (read_prefix) == prefix,
|
||||
"ip6-old-addr", "unexpected failure comparing prefix");
|
||||
|
||||
/* Ensure the gateway is all zeros, which is how the 2-item to 3-item
|
||||
* conversion happens.
|
||||
*/
|
||||
read_gw = g_value_array_get_nth (read_array, 2);
|
||||
ba = g_value_get_boxed (read_gw);
|
||||
ASSERT (ba->len == sizeof (gw),
|
||||
"ip6-old-addr", "unexpected gateway item length %d", ba->len);
|
||||
ASSERT (memcmp (ba->data, &gw[0], sizeof (gw)) == 0,
|
||||
"ip6-old-addr", "unexpected failure comparing gateways");
|
||||
|
||||
g_value_unset (&written_value);
|
||||
g_value_unset (&read_value);
|
||||
g_object_unref (s_ip6);
|
||||
}
|
||||
|
||||
int main (int argc, char **argv)
|
||||
{
|
||||
GError *error = NULL;
|
||||
|
|
@ -142,6 +236,7 @@ int main (int argc, char **argv)
|
|||
|
||||
/* The tests */
|
||||
test_setting_vpn_items ();
|
||||
test_setting_ip6_config_old_address_array ();
|
||||
|
||||
base = g_path_get_basename (argv[0]);
|
||||
fprintf (stdout, "%s: SUCCESS\n", base);
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ VOID:POINTER,POINTER
|
|||
VOID:STRING,STRING,STRING,UINT
|
||||
VOID:OBJECT,UINT,UINT
|
||||
VOID:STRING,INT
|
||||
VOID:STRING,UINT
|
||||
VOID:STRING,UINT,BOOLEAN
|
||||
VOID:INT,UINT
|
||||
VOID:INT,UINT,BOOLEAN
|
||||
VOID:OBJECT,OBJECT,ENUM
|
||||
VOID:POINTER,STRING
|
||||
VOID:STRING,BOXED
|
||||
|
|
|
|||
|
|
@ -14,7 +14,6 @@ src/nm-netlink-monitor.c
|
|||
src/main.c
|
||||
src/dhcp-manager/nm-dhcp-dhclient.c
|
||||
src/dhcp-manager/nm-dhcp-manager.c
|
||||
src/ip6-manager/nm-netlink-listener.c
|
||||
src/logging/nm-logging.c
|
||||
src/named-manager/nm-named-manager.c
|
||||
src/system-settings/nm-default-wired-connection.c
|
||||
|
|
|
|||
|
|
@ -68,9 +68,11 @@ libtest_policy_hosts_la_SOURCES = \
|
|||
nm-policy-hosts.h
|
||||
|
||||
libtest_policy_hosts_la_CPPFLAGS = \
|
||||
-DSYSCONFDIR=\"$(sysconfdir)\" \
|
||||
$(GLIB_CFLAGS)
|
||||
|
||||
libtest_policy_hosts_la_LIBADD = \
|
||||
${top_builddir}/src/logging/libnm-logging.la \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
||||
|
|
@ -123,6 +125,8 @@ NetworkManager_SOURCES = \
|
|||
nm-policy.h \
|
||||
nm-policy-hosts.c \
|
||||
nm-policy-hosts.h \
|
||||
nm-policy-hostname.c \
|
||||
nm-policy-hostname.h \
|
||||
NetworkManagerUtils.c \
|
||||
NetworkManagerUtils.h \
|
||||
nm-system.c \
|
||||
|
|
@ -137,8 +141,6 @@ NetworkManager_SOURCES = \
|
|||
nm-properties-changed-signal.h \
|
||||
wpa.c \
|
||||
wpa.h \
|
||||
nm-netlink.c \
|
||||
nm-netlink.h \
|
||||
nm-dhcp4-config.c \
|
||||
nm-dhcp4-config.h \
|
||||
nm-dhcp6-config.c \
|
||||
|
|
@ -206,9 +208,7 @@ BUILT_SOURCES = \
|
|||
NetworkManager_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(HAL_CFLAGS) \
|
||||
$(GUDEV_CFLAGS) \
|
||||
$(OPENSSL_CFLAGS) \
|
||||
$(LIBNL_CFLAGS) \
|
||||
$(GMODULE_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED \
|
||||
|
|
|
|||
|
|
@ -1,9 +1,5 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* Timothee Lecomte <timothee.lecomte@ens.fr>
|
||||
*
|
||||
* Heavily based on NetworkManagerRedhat.c by Dan Williams <dcbw@redhat.com>
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
|
|
@ -19,7 +15,8 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2004 Red Hat, Inc.
|
||||
* (C) Copyright 2004 - 2010 Red Hat, Inc.
|
||||
* (C) Copyright 2006 Timothee Lecomte <timothee.lecomte@ens.fr>
|
||||
*/
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
|
|
@ -36,8 +33,8 @@
|
|||
#include "NetworkManagerGeneric.h"
|
||||
#include "nm-system.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
|
||||
/* Because of a bug in libnl, rtnl.h should be included before route.h */
|
||||
#include <netlink/route/rtnl.h>
|
||||
|
|
|
|||
|
|
@ -390,11 +390,14 @@ static DhcState state_table[] = {
|
|||
{ DHC_REBIND4, "rebind" },
|
||||
{ DHC_REBIND6, "rebind6" },
|
||||
{ DHC_STOP, "stop" },
|
||||
{ DHC_STOP6, "stop6" },
|
||||
{ DHC_MEDIUM, "medium" },
|
||||
{ DHC_TIMEOUT, "timeout" },
|
||||
{ DHC_FAIL, "fail" },
|
||||
{ DHC_EXPIRE, "expire" },
|
||||
{ DHC_EXPIRE6, "expire6" },
|
||||
{ DHC_RELEASE, "release" },
|
||||
{ DHC_RELEASE6,"release6" },
|
||||
{ DHC_START, "start" },
|
||||
{ DHC_ABEND, "abend" },
|
||||
{ DHC_END, "end" },
|
||||
|
|
|
|||
|
|
@ -53,11 +53,14 @@ typedef enum {
|
|||
DHC_REBIND6, /* IPv6 new/different lease */
|
||||
DHC_DEPREF6, /* IPv6 lease depreferred */
|
||||
DHC_STOP, /* remove old lease */
|
||||
DHC_STOP6, /* remove old lease */
|
||||
DHC_MEDIUM, /* media selection begun */
|
||||
DHC_TIMEOUT, /* timed out contacting DHCP server */
|
||||
DHC_FAIL, /* all attempts to contact server timed out, sleeping */
|
||||
DHC_EXPIRE, /* lease has expired, renewing */
|
||||
DHC_EXPIRE6, /* lease has expired, renewing */
|
||||
DHC_RELEASE, /* releasing lease */
|
||||
DHC_RELEASE6, /* releasing lease */
|
||||
DHC_START, /* sent when dhclient started OK */
|
||||
DHC_ABEND, /* dhclient exited abnormally */
|
||||
DHC_END, /* dhclient exited normally */
|
||||
|
|
|
|||
|
|
@ -482,6 +482,13 @@ nm_dhcp_manager_start_ip4 (NMDHCPManager *self,
|
|||
priv = NM_DHCP_MANAGER_GET_PRIVATE (self);
|
||||
|
||||
if (s_ip4) {
|
||||
const char *method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (method) {
|
||||
/* Method must be 'auto' */
|
||||
g_return_val_if_fail (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO) == 0, NULL);
|
||||
}
|
||||
|
||||
if ( nm_setting_ip4_config_get_dhcp_send_hostname (s_ip4)
|
||||
&& (nm_setting_ip4_config_get_dhcp_hostname (s_ip4) == NULL)
|
||||
&& priv->hostname_provider != NULL) {
|
||||
|
|
|
|||
|
|
@ -11,14 +11,11 @@ noinst_LTLIBRARIES = libip6-manager.la
|
|||
|
||||
libip6_manager_la_SOURCES = \
|
||||
nm-ip6-manager.c \
|
||||
nm-ip6-manager.h \
|
||||
nm-netlink-listener.c \
|
||||
nm-netlink-listener.h
|
||||
nm-ip6-manager.h
|
||||
|
||||
libip6_manager_la_CPPFLAGS = \
|
||||
$(DBUS_CFLAGS) \
|
||||
$(GLIB_CFLAGS) \
|
||||
$(HAL_CFLAGS) \
|
||||
-DG_DISABLE_DEPRECATED
|
||||
|
||||
libip6_manager_la_LIBADD = \
|
||||
|
|
|
|||
|
|
@ -21,14 +21,16 @@
|
|||
#include <errno.h>
|
||||
#include <netinet/icmp6.h>
|
||||
|
||||
#include <netlink/route/addr.h>
|
||||
#include <netlink/route/rtnl.h>
|
||||
#include <netlink/route/route.h>
|
||||
|
||||
#include "nm-ip6-manager.h"
|
||||
#include "nm-netlink-listener.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-system.h"
|
||||
|
||||
/* Pre-DHCP addrconf timeout, in seconds */
|
||||
#define NM_IP6_TIMEOUT 10
|
||||
|
|
@ -40,8 +42,8 @@
|
|||
#define IF_RS_SENT 0x10
|
||||
|
||||
typedef struct {
|
||||
NMNetlinkListener *netlink;
|
||||
GHashTable *devices_by_iface, *devices_by_index;
|
||||
NMNetlinkMonitor *monitor;
|
||||
GHashTable *devices;
|
||||
|
||||
struct nl_handle *nlh;
|
||||
struct nl_cache *addr_cache, *route_cache;
|
||||
|
|
@ -49,41 +51,6 @@ typedef struct {
|
|||
|
||||
#define NM_IP6_MANAGER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), NM_TYPE_IP6_MANAGER, NMIP6ManagerPrivate))
|
||||
|
||||
typedef enum {
|
||||
NM_IP6_DEVICE_UNCONFIGURED,
|
||||
NM_IP6_DEVICE_GOT_LINK_LOCAL,
|
||||
NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT,
|
||||
NM_IP6_DEVICE_GOT_ADDRESS,
|
||||
NM_IP6_DEVICE_WAITING_FOR_DHCP,
|
||||
NM_IP6_DEVICE_GOT_DHCP,
|
||||
NM_IP6_DEVICE_TIMED_OUT
|
||||
} NMIP6DeviceState;
|
||||
|
||||
typedef struct {
|
||||
struct in6_addr addr;
|
||||
time_t expires;
|
||||
} NMIP6RDNSS;
|
||||
|
||||
typedef struct {
|
||||
NMIP6Manager *manager;
|
||||
char *iface;
|
||||
int index;
|
||||
|
||||
char *accept_ra_path;
|
||||
gboolean accept_ra_save_valid;
|
||||
guint32 accept_ra_save;
|
||||
|
||||
guint finish_addrconf_id;
|
||||
guint config_changed_id;
|
||||
|
||||
NMIP6DeviceState state;
|
||||
NMIP6DeviceState target_state;
|
||||
gboolean addrconf_complete;
|
||||
|
||||
GArray *rdnss_servers;
|
||||
guint rdnss_timeout_id;
|
||||
} NMIP6Device;
|
||||
|
||||
G_DEFINE_TYPE (NMIP6Manager, nm_ip6_manager, G_TYPE_OBJECT)
|
||||
|
||||
enum {
|
||||
|
|
@ -94,89 +61,48 @@ enum {
|
|||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
static NMIP6Manager *nm_ip6_manager_new (void);
|
||||
typedef enum {
|
||||
NM_IP6_DEVICE_UNCONFIGURED,
|
||||
NM_IP6_DEVICE_GOT_LINK_LOCAL,
|
||||
NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT,
|
||||
NM_IP6_DEVICE_GOT_ADDRESS,
|
||||
NM_IP6_DEVICE_TIMED_OUT
|
||||
} NMIP6DeviceState;
|
||||
|
||||
static void netlink_notification (NMNetlinkListener *listener, struct nl_msg *msg, gpointer user_data);
|
||||
typedef struct {
|
||||
struct in6_addr addr;
|
||||
time_t expires;
|
||||
} NMIP6RDNSS;
|
||||
|
||||
static void nm_ip6_device_destroy (NMIP6Device *device);
|
||||
/******************************************************************/
|
||||
|
||||
NMIP6Manager *
|
||||
nm_ip6_manager_get (void)
|
||||
{
|
||||
static NMIP6Manager *singleton = NULL;
|
||||
typedef struct {
|
||||
NMIP6Manager *manager;
|
||||
char *iface;
|
||||
int ifindex;
|
||||
|
||||
if (!singleton)
|
||||
singleton = nm_ip6_manager_new ();
|
||||
g_assert (singleton);
|
||||
char *accept_ra_path;
|
||||
gboolean accept_ra_save_valid;
|
||||
guint32 accept_ra_save;
|
||||
|
||||
return g_object_ref (singleton);
|
||||
}
|
||||
char *disable_ip6_path;
|
||||
gboolean disable_ip6_save_valid;
|
||||
guint32 disable_ip6_save;
|
||||
|
||||
static void
|
||||
nm_ip6_manager_init (NMIP6Manager *manager)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
guint finish_addrconf_id;
|
||||
guint config_changed_id;
|
||||
|
||||
priv->devices_by_iface = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) nm_ip6_device_destroy);
|
||||
priv->devices_by_index = g_hash_table_new (NULL, NULL);
|
||||
NMIP6DeviceState state;
|
||||
NMIP6DeviceState target_state;
|
||||
gboolean addrconf_complete;
|
||||
|
||||
priv->netlink = nm_netlink_listener_get ();
|
||||
g_signal_connect (priv->netlink, "notification",
|
||||
G_CALLBACK (netlink_notification), manager);
|
||||
nm_netlink_listener_subscribe (priv->netlink, RTNLGRP_IPV6_IFADDR, NULL);
|
||||
nm_netlink_listener_subscribe (priv->netlink, RTNLGRP_IPV6_PREFIX, NULL);
|
||||
nm_netlink_listener_subscribe (priv->netlink, RTNLGRP_ND_USEROPT, NULL);
|
||||
GArray *rdnss_servers;
|
||||
guint rdnss_timeout_id;
|
||||
|
||||
priv->nlh = nm_netlink_get_default_handle ();
|
||||
priv->addr_cache = rtnl_addr_alloc_cache (priv->nlh);
|
||||
priv->route_cache = rtnl_route_alloc_cache (priv->nlh);
|
||||
}
|
||||
guint ip6flags_poll_id;
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
g_hash_table_destroy (priv->devices_by_iface);
|
||||
g_hash_table_destroy (priv->devices_by_index);
|
||||
g_object_unref (priv->netlink);
|
||||
nl_cache_free (priv->addr_cache);
|
||||
nl_cache_free (priv->route_cache);
|
||||
|
||||
G_OBJECT_CLASS (nm_ip6_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
||||
|
||||
g_type_class_add_private (manager_class, sizeof (NMIP6ManagerPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* signals */
|
||||
signals[ADDRCONF_COMPLETE] =
|
||||
g_signal_new ("addrconf-complete",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete),
|
||||
NULL, NULL,
|
||||
_nm_marshal_VOID__STRING_UINT_BOOLEAN,
|
||||
G_TYPE_NONE, 3, G_TYPE_STRING, G_TYPE_UINT, G_TYPE_BOOLEAN);
|
||||
|
||||
signals[CONFIG_CHANGED] =
|
||||
g_signal_new ("config-changed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed),
|
||||
NULL, NULL,
|
||||
_nm_marshal_VOID__STRING_UINT,
|
||||
G_TYPE_NONE, 2, G_TYPE_STRING, G_TYPE_UINT);
|
||||
}
|
||||
guint32 ra_flags;
|
||||
} NMIP6Device;
|
||||
|
||||
static void
|
||||
nm_ip6_device_destroy (NMIP6Device *device)
|
||||
|
|
@ -189,6 +115,12 @@ nm_ip6_device_destroy (NMIP6Device *device)
|
|||
device->accept_ra_save ? "1\n" : "0\n");
|
||||
}
|
||||
|
||||
/* reset the saved IPv6 value */
|
||||
if (device->disable_ip6_save_valid) {
|
||||
nm_utils_do_sysctl (device->disable_ip6_path,
|
||||
device->disable_ip6_save ? "1\n" : "0\n");
|
||||
}
|
||||
|
||||
if (device->finish_addrconf_id)
|
||||
g_source_remove (device->finish_addrconf_id);
|
||||
if (device->config_changed_id)
|
||||
|
|
@ -198,27 +130,92 @@ nm_ip6_device_destroy (NMIP6Device *device)
|
|||
g_array_free (device->rdnss_servers, TRUE);
|
||||
if (device->rdnss_timeout_id)
|
||||
g_source_remove (device->rdnss_timeout_id);
|
||||
if (device->ip6flags_poll_id)
|
||||
g_source_remove (device->ip6flags_poll_id);
|
||||
|
||||
g_free (device->accept_ra_path);
|
||||
g_slice_free (NMIP6Device, device);
|
||||
}
|
||||
|
||||
static NMIP6Manager *
|
||||
nm_ip6_manager_new (void)
|
||||
static gboolean
|
||||
get_proc_sys_net_value (const char *path, const char *iface, guint32 *out_value)
|
||||
{
|
||||
NMIP6Manager *manager;
|
||||
NMIP6ManagerPrivate *priv;
|
||||
GError *error;
|
||||
char *contents = NULL;
|
||||
gboolean success = FALSE;
|
||||
long int tmp;
|
||||
|
||||
manager = g_object_new (NM_TYPE_IP6_MANAGER, NULL);
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
if (!priv->devices_by_iface || !priv->devices_by_index) {
|
||||
nm_log_err (LOGD_IP6, "not enough memory to initialize IP6 manager tables");
|
||||
g_object_unref (manager);
|
||||
manager = NULL;
|
||||
if (!g_file_get_contents (path, &contents, NULL, &error)) {
|
||||
nm_log_warn (LOGD_IP6, "(%s): error reading %s: (%d) %s",
|
||||
iface, path,
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
errno = 0;
|
||||
tmp = strtol (contents, NULL, 10);
|
||||
if ((errno == 0) && (tmp == 0 || tmp == 1)) {
|
||||
*out_value = (guint32) tmp;
|
||||
success = TRUE;
|
||||
}
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
return manager;
|
||||
return success;
|
||||
}
|
||||
|
||||
static NMIP6Device *
|
||||
nm_ip6_device_new (NMIP6Manager *manager, int ifindex)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
NMIP6Device *device;
|
||||
|
||||
g_return_val_if_fail (ifindex > 0, NULL);
|
||||
|
||||
device = g_slice_new0 (NMIP6Device);
|
||||
if (!device) {
|
||||
nm_log_err (LOGD_IP6, "(%d): out of memory creating IP6 addrconf object.",
|
||||
ifindex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->ifindex = ifindex;
|
||||
device->iface = g_strdup (nm_netlink_index_to_iface (ifindex));
|
||||
if (!device->iface) {
|
||||
nm_log_err (LOGD_IP6, "(%d): could not find interface name from index.",
|
||||
ifindex);
|
||||
goto error;
|
||||
}
|
||||
|
||||
device->manager = manager;
|
||||
|
||||
device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));
|
||||
|
||||
g_hash_table_replace (priv->devices, GINT_TO_POINTER (device->ifindex), device);
|
||||
|
||||
/* Grab the original value of "accept_ra" so we can restore it when the
|
||||
* device is taken down.
|
||||
*/
|
||||
device->accept_ra_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra",
|
||||
device->iface);
|
||||
g_assert (device->accept_ra_path);
|
||||
device->accept_ra_save_valid = get_proc_sys_net_value (device->accept_ra_path,
|
||||
device->iface,
|
||||
&device->accept_ra_save);
|
||||
|
||||
/* and the original value of IPv6 enable/disable */
|
||||
device->disable_ip6_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/disable_ipv6",
|
||||
device->iface);
|
||||
g_assert (device->disable_ip6_path);
|
||||
device->disable_ip6_save_valid = get_proc_sys_net_value (device->disable_ip6_path,
|
||||
device->iface,
|
||||
&device->disable_ip6_save);
|
||||
|
||||
return device;
|
||||
|
||||
error:
|
||||
nm_ip6_device_destroy (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static NMIP6Device *
|
||||
|
|
@ -226,13 +223,15 @@ nm_ip6_manager_get_device (NMIP6Manager *manager, int ifindex)
|
|||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
return g_hash_table_lookup (priv->devices_by_index,
|
||||
GINT_TO_POINTER (ifindex));
|
||||
return g_hash_table_lookup (priv->devices, GINT_TO_POINTER (ifindex));
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
typedef struct {
|
||||
NMIP6Device *device;
|
||||
guint dhcp_opts;
|
||||
gboolean success;
|
||||
} CallbackInfo;
|
||||
|
||||
static gboolean
|
||||
|
|
@ -241,25 +240,29 @@ finish_addrconf (gpointer user_data)
|
|||
CallbackInfo *info = user_data;
|
||||
NMIP6Device *device = info->device;
|
||||
NMIP6Manager *manager = device->manager;
|
||||
char *iface_copy;
|
||||
int ifindex;
|
||||
|
||||
device->finish_addrconf_id = 0;
|
||||
device->addrconf_complete = TRUE;
|
||||
ifindex = device->ifindex;
|
||||
|
||||
if (device->state >= device->target_state) {
|
||||
/* We're done, stop polling IPv6 flags */
|
||||
if (device->ip6flags_poll_id) {
|
||||
g_source_remove (device->ip6flags_poll_id);
|
||||
device->ip6flags_poll_id = 0;
|
||||
}
|
||||
|
||||
/* And tell listeners that addrconf is complete */
|
||||
if (info->success) {
|
||||
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
|
||||
device->iface, info->dhcp_opts, TRUE);
|
||||
ifindex, info->dhcp_opts, TRUE);
|
||||
} else {
|
||||
nm_log_info (LOGD_IP6, "(%s): IP6 addrconf timed out or failed.",
|
||||
device->iface);
|
||||
device->iface);
|
||||
|
||||
iface_copy = g_strdup (device->iface);
|
||||
|
||||
nm_ip6_manager_cancel_addrconf (manager, device->iface);
|
||||
nm_ip6_manager_cancel_addrconf (manager, ifindex);
|
||||
g_signal_emit (manager, signals[ADDRCONF_COMPLETE], 0,
|
||||
iface_copy, info->dhcp_opts, FALSE);
|
||||
|
||||
g_free (iface_copy);
|
||||
ifindex, info->dhcp_opts, FALSE);
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
|
|
@ -273,7 +276,7 @@ emit_config_changed (gpointer user_data)
|
|||
NMIP6Manager *manager = device->manager;
|
||||
|
||||
device->config_changed_id = 0;
|
||||
g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->iface, info->dhcp_opts);
|
||||
g_signal_emit (manager, signals[CONFIG_CHANGED], 0, device->ifindex, info->dhcp_opts);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -329,14 +332,14 @@ set_rdnss_timeout (NMIP6Device *device)
|
|||
}
|
||||
|
||||
static CallbackInfo *
|
||||
callback_info_new (NMIP6Device *device, guint dhcp_opts)
|
||||
callback_info_new (NMIP6Device *device, guint dhcp_opts, gboolean success)
|
||||
{
|
||||
CallbackInfo *info;
|
||||
|
||||
info = g_malloc0 (sizeof (CallbackInfo));
|
||||
info->device = device;
|
||||
info->dhcp_opts = dhcp_opts;
|
||||
|
||||
info->success = success;
|
||||
return info;
|
||||
}
|
||||
|
||||
|
|
@ -348,15 +351,14 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
|
|||
struct rtnl_addr *rtnladdr;
|
||||
struct nl_addr *nladdr;
|
||||
struct in6_addr *addr;
|
||||
struct rtnl_link *link;
|
||||
guint flags;
|
||||
CallbackInfo *info;
|
||||
guint dhcp_opts = IP6_DHCP_OPT_NONE;
|
||||
|
||||
for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache);
|
||||
/* Look for any IPv6 addresses the kernel may have set for the device */
|
||||
for (rtnladdr = (struct rtnl_addr *) nl_cache_get_first (priv->addr_cache);
|
||||
rtnladdr;
|
||||
rtnladdr = (struct rtnl_addr *)nl_cache_get_next ((struct nl_object *)rtnladdr)) {
|
||||
if (rtnl_addr_get_ifindex (rtnladdr) != device->index)
|
||||
rtnladdr = (struct rtnl_addr *) nl_cache_get_next ((struct nl_object *) rtnladdr)) {
|
||||
if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
|
||||
continue;
|
||||
|
||||
nladdr = rtnl_addr_get_local (rtnladdr);
|
||||
|
|
@ -373,32 +375,35 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
|
|||
}
|
||||
}
|
||||
|
||||
/* Note: we don't want to keep a cache of links, because the
|
||||
* kernel doesn't send notifications when the flags change, so the
|
||||
* cached rtnl_links would have out-of-date flags.
|
||||
*/
|
||||
link = nm_netlink_index_to_rtnl_link (device->index);
|
||||
flags = rtnl_link_get_flags (link);
|
||||
rtnl_link_put (link);
|
||||
/* We only care about router advertisements if we want for a real IPv6 address */
|
||||
if (device->target_state == NM_IP6_DEVICE_GOT_ADDRESS) {
|
||||
if ( (device->ra_flags & IF_RA_RCVD)
|
||||
&& (device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT))
|
||||
device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;
|
||||
|
||||
if ((flags & IF_RA_RCVD) && device->state < NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT)
|
||||
device->state = NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT;
|
||||
|
||||
if (flags & IF_RA_MANAGED)
|
||||
dhcp_opts = IP6_DHCP_OPT_MANAGED;
|
||||
else if (flags & IF_RA_OTHERCONF)
|
||||
dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
|
||||
if (device->ra_flags & IF_RA_MANAGED) {
|
||||
dhcp_opts = IP6_DHCP_OPT_MANAGED;
|
||||
nm_log_dbg (LOGD_IP6, "router advertisement deferred to DHCPv6");
|
||||
} else if (device->ra_flags & IF_RA_OTHERCONF) {
|
||||
dhcp_opts = IP6_DHCP_OPT_OTHERCONF;
|
||||
nm_log_dbg (LOGD_IP6, "router advertisement requests parallel DHCPv6");
|
||||
}
|
||||
}
|
||||
|
||||
if (!device->addrconf_complete) {
|
||||
if (device->state >= device->target_state ||
|
||||
device->state == NM_IP6_DEVICE_GOT_ROUTER_ADVERTISEMENT) {
|
||||
/* Managed mode (ie DHCP only) short-circuits automatic addrconf, so
|
||||
* we don't bother waiting for the device's target state to be reached
|
||||
* when the RA requests managed mode.
|
||||
*/
|
||||
if ( (device->state >= device->target_state)
|
||||
|| (dhcp_opts == IP6_DHCP_OPT_MANAGED)) {
|
||||
/* device->finish_addrconf_id may currently be a timeout
|
||||
* rather than an idle, so we remove the existing source.
|
||||
*/
|
||||
if (device->finish_addrconf_id)
|
||||
g_source_remove (device->finish_addrconf_id);
|
||||
|
||||
info = callback_info_new (device, dhcp_opts);
|
||||
info = callback_info_new (device, dhcp_opts, TRUE);
|
||||
device->finish_addrconf_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
finish_addrconf,
|
||||
info,
|
||||
|
|
@ -406,7 +411,7 @@ nm_ip6_device_sync_from_netlink (NMIP6Device *device, gboolean config_changed)
|
|||
}
|
||||
} else if (config_changed) {
|
||||
if (!device->config_changed_id) {
|
||||
info = callback_info_new (device, dhcp_opts);
|
||||
info = callback_info_new (device, dhcp_opts, TRUE);
|
||||
device->config_changed_id = g_idle_add_full (G_PRIORITY_DEFAULT_IDLE,
|
||||
emit_config_changed,
|
||||
info,
|
||||
|
|
@ -598,8 +603,59 @@ process_nduseropt (NMIP6Manager *manager, struct nl_msg *msg)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static struct nla_policy link_policy[IFLA_MAX + 1] = {
|
||||
[IFLA_PROTINFO] = { .type = NLA_NESTED },
|
||||
};
|
||||
|
||||
static struct nla_policy link_prot_policy[IFLA_INET6_MAX + 1] = {
|
||||
[IFLA_INET6_FLAGS] = { .type = NLA_U32 },
|
||||
};
|
||||
|
||||
static NMIP6Device *
|
||||
process_newlink (NMIP6Manager *manager, struct nl_msg *msg)
|
||||
{
|
||||
struct nlmsghdr *hdr = nlmsg_hdr (msg);
|
||||
struct ifinfomsg *ifi;
|
||||
NMIP6Device *device;
|
||||
struct nlattr *tb[IFLA_MAX + 1];
|
||||
struct nlattr *pi[IFLA_INET6_MAX + 1];
|
||||
int err;
|
||||
|
||||
ifi = nlmsg_data (hdr);
|
||||
if (ifi->ifi_family != AF_INET6)
|
||||
return NULL;
|
||||
|
||||
device = nm_ip6_manager_get_device (manager, ifi->ifi_index);
|
||||
if (!device || device->addrconf_complete)
|
||||
return NULL;
|
||||
|
||||
/* FIXME: we have to do this manually for now since libnl doesn't yet
|
||||
* support the IFLA_PROTINFO attribute of NEWLINK messages. When it does,
|
||||
* we can get rid of this function and just grab IFLA_PROTINFO from
|
||||
* nm_ip6_device_sync_from_netlink(), then get the IFLA_INET6_FLAGS out of
|
||||
* the PROTINFO.
|
||||
*/
|
||||
|
||||
err = nlmsg_parse (hdr, sizeof (*ifi), tb, IFLA_MAX, link_policy);
|
||||
if (err < 0)
|
||||
return NULL;
|
||||
if (!tb[IFLA_PROTINFO])
|
||||
return NULL;
|
||||
|
||||
err = nla_parse_nested (pi, IFLA_INET6_MAX, tb[IFLA_PROTINFO], link_prot_policy);
|
||||
if (err < 0)
|
||||
return NULL;
|
||||
if (!pi[IFLA_INET6_FLAGS])
|
||||
return NULL;
|
||||
|
||||
device->ra_flags = nla_get_u32 (pi[IFLA_INET6_FLAGS]);
|
||||
nm_log_dbg (LOGD_IP6, "(%s): got IPv6 flags 0x%X", device->iface, device->ra_flags);
|
||||
|
||||
return device;
|
||||
}
|
||||
|
||||
static void
|
||||
netlink_notification (NMNetlinkListener *listener, struct nl_msg *msg, gpointer user_data)
|
||||
netlink_notification (NMNetlinkMonitor *monitor, struct nl_msg *msg, gpointer user_data)
|
||||
{
|
||||
NMIP6Manager *manager = (NMIP6Manager *) user_data;
|
||||
NMIP6Device *device;
|
||||
|
|
@ -613,22 +669,22 @@ netlink_notification (NMNetlinkListener *listener, struct nl_msg *msg, gpointer
|
|||
device = process_addr (manager, msg);
|
||||
config_changed = TRUE;
|
||||
break;
|
||||
|
||||
case RTM_NEWROUTE:
|
||||
case RTM_DELROUTE:
|
||||
device = process_route (manager, msg);
|
||||
config_changed = TRUE;
|
||||
break;
|
||||
|
||||
case RTM_NEWPREFIX:
|
||||
device = process_prefix (manager, msg);
|
||||
break;
|
||||
|
||||
case RTM_NEWNDUSEROPT:
|
||||
device = process_nduseropt (manager, msg);
|
||||
config_changed = TRUE;
|
||||
break;
|
||||
|
||||
case RTM_NEWLINK:
|
||||
device = process_newlink (manager, msg);
|
||||
config_changed = TRUE;
|
||||
break;
|
||||
default:
|
||||
return;
|
||||
}
|
||||
|
|
@ -637,75 +693,9 @@ netlink_notification (NMNetlinkListener *listener, struct nl_msg *msg, gpointer
|
|||
nm_ip6_device_sync_from_netlink (device, config_changed);
|
||||
}
|
||||
|
||||
static NMIP6Device *
|
||||
nm_ip6_device_new (NMIP6Manager *manager, const char *iface)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
NMIP6Device *device;
|
||||
GError *error = NULL;
|
||||
char *contents = NULL;
|
||||
|
||||
device = g_slice_new0 (NMIP6Device);
|
||||
if (!device) {
|
||||
nm_log_err (LOGD_IP6, "(%s): out of memory creating IP6 addrconf object.", iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
device->iface = g_strdup (iface);
|
||||
if (!device->iface) {
|
||||
nm_log_err (LOGD_IP6, "(%s): out of memory creating IP6 addrconf object "
|
||||
"property 'iface'.",
|
||||
iface);
|
||||
goto error;
|
||||
}
|
||||
device->index = nm_netlink_iface_to_index (iface);
|
||||
|
||||
device->accept_ra_path = g_strdup_printf ("/proc/sys/net/ipv6/conf/%s/accept_ra", iface);
|
||||
if (!device->accept_ra_path) {
|
||||
nm_log_err (LOGD_IP6, "(%s): out of memory creating IP6 addrconf object "
|
||||
"property 'accept_ra_path'.",
|
||||
iface);
|
||||
goto error;
|
||||
}
|
||||
|
||||
device->manager = manager;
|
||||
|
||||
device->rdnss_servers = g_array_new (FALSE, FALSE, sizeof (NMIP6RDNSS));
|
||||
|
||||
g_hash_table_replace (priv->devices_by_iface, device->iface, device);
|
||||
g_hash_table_replace (priv->devices_by_index, GINT_TO_POINTER (device->index), device);
|
||||
|
||||
/* Grab the original value of "accept_ra" so we can restore it when the
|
||||
* device is taken down.
|
||||
*/
|
||||
if (!g_file_get_contents (device->accept_ra_path, &contents, NULL, &error)) {
|
||||
nm_log_warn (LOGD_IP6, "(%s): error reading %s: (%d) %s",
|
||||
iface, device->accept_ra_path,
|
||||
error ? error->code : -1,
|
||||
error && error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
long int tmp;
|
||||
|
||||
errno = 0;
|
||||
tmp = strtol (contents, NULL, 10);
|
||||
if ((errno == 0) && (tmp == 0 || tmp == 1)) {
|
||||
device->accept_ra_save = (guint32) tmp;
|
||||
device->accept_ra_save_valid = TRUE;
|
||||
}
|
||||
g_free (contents);
|
||||
}
|
||||
|
||||
return device;
|
||||
|
||||
error:
|
||||
nm_ip6_device_destroy (device);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
NMSettingIP6Config *s_ip6)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv;
|
||||
|
|
@ -713,60 +703,81 @@ nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
|||
const char *method = NULL;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
|
||||
g_return_if_fail (iface != NULL);
|
||||
g_return_if_fail (ifindex > 0);
|
||||
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
device = nm_ip6_device_new (manager, iface);
|
||||
device = nm_ip6_device_new (manager, ifindex);
|
||||
g_return_if_fail (device != NULL);
|
||||
g_return_if_fail ( strchr (device->iface, '/') == NULL
|
||||
&& strcmp (device->iface, "all") != 0
|
||||
&& strcmp (device->iface, "default") != 0);
|
||||
|
||||
if (s_ip6)
|
||||
method = nm_setting_ip6_config_get_method (s_ip6);
|
||||
if (!method)
|
||||
method = NM_SETTING_IP6_CONFIG_METHOD_AUTO;
|
||||
|
||||
/* Establish target state and turn router advertisement acceptance on or off */
|
||||
if ( !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_MANUAL)
|
||||
|| !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
||||
|| !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL)) {
|
||||
device->target_state = NM_IP6_DEVICE_GOT_LINK_LOCAL;
|
||||
else
|
||||
nm_utils_do_sysctl (device->accept_ra_path, "0\n");
|
||||
} else {
|
||||
device->target_state = NM_IP6_DEVICE_GOT_ADDRESS;
|
||||
nm_utils_do_sysctl (device->accept_ra_path, "1\n");
|
||||
}
|
||||
}
|
||||
|
||||
g_return_if_fail (strchr (iface, '/') == NULL &&
|
||||
strcmp (iface, "all") != 0 &&
|
||||
strcmp (iface, "default") != 0);
|
||||
|
||||
/* Turn router advertisement acceptance on or off... */
|
||||
nm_utils_do_sysctl (device->accept_ra_path,
|
||||
device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS ? "1\n" : "0\n");
|
||||
static gboolean
|
||||
poll_ip6_flags (gpointer user_data)
|
||||
{
|
||||
nm_netlink_monitor_request_ip6_info (NM_NETLINK_MONITOR (user_data), NULL);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
||||
const char *iface)
|
||||
nm_ip6_manager_begin_addrconf (NMIP6Manager *manager, int ifindex)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv;
|
||||
NMIP6Device *device;
|
||||
CallbackInfo *info;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
|
||||
g_return_if_fail (iface != NULL);
|
||||
g_return_if_fail (ifindex > 0);
|
||||
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
device = (NMIP6Device *) g_hash_table_lookup (priv->devices_by_iface, iface);
|
||||
device = (NMIP6Device *) g_hash_table_lookup (priv->devices, GINT_TO_POINTER (ifindex));
|
||||
g_return_if_fail (device != NULL);
|
||||
|
||||
nm_log_info (LOGD_IP6, "Activation (%s) Beginning IP6 addrconf.", iface);
|
||||
nm_log_info (LOGD_IP6, "Activation (%s) Beginning IP6 addrconf.", device->iface);
|
||||
|
||||
device->addrconf_complete = FALSE;
|
||||
device->ra_flags = 0;
|
||||
|
||||
/* Set up a timeout on the transaction to kill it after the timeout */
|
||||
info = callback_info_new (device, 0);
|
||||
info = callback_info_new (device, 0, FALSE);
|
||||
device->finish_addrconf_id = g_timeout_add_seconds_full (G_PRIORITY_DEFAULT,
|
||||
NM_IP6_TIMEOUT,
|
||||
finish_addrconf,
|
||||
info,
|
||||
(GDestroyNotify) g_free);
|
||||
|
||||
/* Bounce IPv6 on the interface to ensure the kernel will start looking for
|
||||
* new RAs; there doesn't seem to be a better way to do this right now.
|
||||
*/
|
||||
if (device->target_state >= NM_IP6_DEVICE_GOT_ADDRESS) {
|
||||
nm_utils_do_sysctl (device->disable_ip6_path, "1\n");
|
||||
g_usleep (200);
|
||||
nm_utils_do_sysctl (device->disable_ip6_path, "0\n");
|
||||
}
|
||||
|
||||
device->ip6flags_poll_id = g_timeout_add_seconds (1, poll_ip6_flags, priv->monitor);
|
||||
|
||||
/* Kick off the initial IPv6 flags request */
|
||||
nm_netlink_monitor_request_ip6_info (priv->monitor, NULL);
|
||||
|
||||
/* Sync flags, etc, from netlink; this will also notice if the
|
||||
* device is already fully configured and schedule the
|
||||
* ADDRCONF_COMPLETE signal in that case.
|
||||
|
|
@ -775,27 +786,23 @@ nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
|||
}
|
||||
|
||||
void
|
||||
nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager,
|
||||
const char *iface)
|
||||
nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager, int ifindex)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv;
|
||||
NMIP6Device *device;
|
||||
|
||||
g_return_if_fail (NM_IS_IP6_MANAGER (manager));
|
||||
g_return_if_fail (iface != NULL);
|
||||
g_return_if_fail (ifindex > 0);
|
||||
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
device = g_hash_table_lookup (priv->devices_by_iface, iface);
|
||||
if (device) {
|
||||
g_hash_table_remove (priv->devices_by_index, GINT_TO_POINTER (device->index));
|
||||
g_hash_table_remove (priv->devices_by_iface, iface);
|
||||
}
|
||||
g_hash_table_remove (NM_IP6_MANAGER_GET_PRIVATE (manager)->devices,
|
||||
GINT_TO_POINTER (ifindex));
|
||||
}
|
||||
|
||||
#define FIRST_ROUTE(m) ((struct rtnl_route *) nl_cache_get_first (m))
|
||||
#define NEXT_ROUTE(m) ((struct rtnl_route *) nl_cache_get_next ((struct nl_object *) m))
|
||||
|
||||
#define FIRST_ADDR(m) ((struct rtnl_addr *) nl_cache_get_first (m))
|
||||
#define NEXT_ADDR(m) ((struct rtnl_addr *) nl_cache_get_next ((struct nl_object *) m))
|
||||
|
||||
NMIP6Config *
|
||||
nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
||||
const char *iface)
|
||||
nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv;
|
||||
NMIP6Device *device;
|
||||
|
|
@ -807,51 +814,44 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
|||
struct rtnl_route *rtnlroute;
|
||||
struct nl_addr *nldest, *nlgateway;
|
||||
struct in6_addr *dest, *gateway;
|
||||
gboolean defgw_set = FALSE;
|
||||
struct in6_addr defgw;
|
||||
uint32_t metric;
|
||||
NMIP6Route *ip6route;
|
||||
int i;
|
||||
|
||||
g_return_val_if_fail (NM_IS_IP6_MANAGER (manager), NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
g_return_val_if_fail (ifindex > 0, NULL);
|
||||
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
device = (NMIP6Device *) g_hash_table_lookup (priv->devices_by_iface, iface);
|
||||
device = (NMIP6Device *) g_hash_table_lookup (priv->devices,
|
||||
GINT_TO_POINTER (ifindex));
|
||||
if (!device) {
|
||||
nm_log_warn (LOGD_IP6, "(%s): addrconf not started.", iface);
|
||||
nm_log_warn (LOGD_IP6, "(%d): addrconf not started.", ifindex);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
config = nm_ip6_config_new ();
|
||||
if (!config) {
|
||||
nm_log_err (LOGD_IP6, "(%s): out of memory creating IP6 config object.",
|
||||
iface);
|
||||
device->iface);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Add addresses */
|
||||
for (rtnladdr = (struct rtnl_addr *)nl_cache_get_first (priv->addr_cache);
|
||||
rtnladdr;
|
||||
rtnladdr = (struct rtnl_addr *)nl_cache_get_next ((struct nl_object *)rtnladdr)) {
|
||||
if (rtnl_addr_get_ifindex (rtnladdr) != device->index)
|
||||
continue;
|
||||
|
||||
nladdr = rtnl_addr_get_local (rtnladdr);
|
||||
if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
|
||||
continue;
|
||||
|
||||
addr = nl_addr_get_binary_addr (nladdr);
|
||||
ip6addr = nm_ip6_address_new ();
|
||||
nm_ip6_address_set_prefix (ip6addr, rtnl_addr_get_prefixlen (rtnladdr));
|
||||
nm_ip6_address_set_address (ip6addr, addr);
|
||||
nm_ip6_config_take_address (config, ip6addr);
|
||||
}
|
||||
/* Make sure we refill the route and address caches, otherwise we won't get
|
||||
* up-to-date information here since the netlink route/addr change messages
|
||||
* may be lagging a bit.
|
||||
*/
|
||||
nl_cache_refill (priv->nlh, priv->route_cache);
|
||||
nl_cache_refill (priv->nlh, priv->addr_cache);
|
||||
|
||||
/* Add routes */
|
||||
for (rtnlroute = (struct rtnl_route *)nl_cache_get_first (priv->route_cache);
|
||||
rtnlroute;
|
||||
rtnlroute = (struct rtnl_route *)nl_cache_get_next ((struct nl_object *)rtnlroute)) {
|
||||
if (rtnl_route_get_oif (rtnlroute) != device->index)
|
||||
for (rtnlroute = FIRST_ROUTE (priv->route_cache); rtnlroute; rtnlroute = NEXT_ROUTE (rtnlroute)) {
|
||||
/* Make sure it's an IPv6 route for this device */
|
||||
if (rtnl_route_get_oif (rtnlroute) != device->ifindex)
|
||||
continue;
|
||||
if (rtnl_route_get_family (rtnlroute) != AF_INET6)
|
||||
continue;
|
||||
|
||||
nldest = rtnl_route_get_dst (rtnlroute);
|
||||
|
|
@ -864,6 +864,15 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
|||
continue;
|
||||
gateway = nl_addr_get_binary_addr (nlgateway);
|
||||
|
||||
if (rtnl_route_get_dst_len (rtnlroute) == 0) {
|
||||
/* Default gateway route; don't add to normal routes but to each address */
|
||||
if (!defgw_set) {
|
||||
memcpy (&defgw, gateway, sizeof (defgw));
|
||||
defgw_set = TRUE;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
ip6route = nm_ip6_route_new ();
|
||||
nm_ip6_route_set_dest (ip6route, dest);
|
||||
nm_ip6_route_set_prefix (ip6route, rtnl_route_get_dst_len (rtnlroute));
|
||||
|
|
@ -874,6 +883,24 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
|||
nm_ip6_config_take_route (config, ip6route);
|
||||
}
|
||||
|
||||
/* Add addresses */
|
||||
for (rtnladdr = FIRST_ADDR (priv->addr_cache); rtnladdr; rtnladdr = NEXT_ADDR (rtnladdr)) {
|
||||
if (rtnl_addr_get_ifindex (rtnladdr) != device->ifindex)
|
||||
continue;
|
||||
|
||||
nladdr = rtnl_addr_get_local (rtnladdr);
|
||||
if (!nladdr || nl_addr_get_family (nladdr) != AF_INET6)
|
||||
continue;
|
||||
|
||||
addr = nl_addr_get_binary_addr (nladdr);
|
||||
ip6addr = nm_ip6_address_new ();
|
||||
nm_ip6_address_set_prefix (ip6addr, rtnl_addr_get_prefixlen (rtnladdr));
|
||||
nm_ip6_address_set_address (ip6addr, addr);
|
||||
nm_ip6_config_take_address (config, ip6addr);
|
||||
if (defgw_set)
|
||||
nm_ip6_address_set_gateway (ip6addr, &defgw);
|
||||
}
|
||||
|
||||
/* Add DNS servers */
|
||||
if (device->rdnss_servers) {
|
||||
NMIP6RDNSS *rdnss = (NMIP6RDNSS *)(device->rdnss_servers->data);
|
||||
|
|
@ -884,3 +911,104 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
|||
|
||||
return config;
|
||||
}
|
||||
|
||||
/******************************************************************/
|
||||
|
||||
static NMIP6Manager *
|
||||
nm_ip6_manager_new (void)
|
||||
{
|
||||
NMIP6Manager *manager;
|
||||
NMIP6ManagerPrivate *priv;
|
||||
|
||||
manager = g_object_new (NM_TYPE_IP6_MANAGER, NULL);
|
||||
priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
if (!priv->devices) {
|
||||
nm_log_err (LOGD_IP6, "not enough memory to initialize IP6 manager tables");
|
||||
g_object_unref (manager);
|
||||
manager = NULL;
|
||||
}
|
||||
|
||||
return manager;
|
||||
}
|
||||
|
||||
NMIP6Manager *
|
||||
nm_ip6_manager_get (void)
|
||||
{
|
||||
static NMIP6Manager *singleton = NULL;
|
||||
|
||||
if (!singleton) {
|
||||
singleton = nm_ip6_manager_new ();
|
||||
g_assert (singleton);
|
||||
} else
|
||||
g_object_ref (singleton);
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ip6_manager_init (NMIP6Manager *manager)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (manager);
|
||||
|
||||
priv->devices = g_hash_table_new_full (g_direct_hash, g_direct_equal,
|
||||
NULL,
|
||||
(GDestroyNotify) nm_ip6_device_destroy);
|
||||
|
||||
priv->monitor = nm_netlink_monitor_get ();
|
||||
nm_netlink_monitor_subscribe (priv->monitor, RTNLGRP_IPV6_IFADDR, NULL);
|
||||
nm_netlink_monitor_subscribe (priv->monitor, RTNLGRP_IPV6_PREFIX, NULL);
|
||||
nm_netlink_monitor_subscribe (priv->monitor, RTNLGRP_ND_USEROPT, NULL);
|
||||
nm_netlink_monitor_subscribe (priv->monitor, RTNLGRP_LINK, NULL);
|
||||
|
||||
g_signal_connect (priv->monitor, "notification",
|
||||
G_CALLBACK (netlink_notification), manager);
|
||||
|
||||
priv->nlh = nm_netlink_get_default_handle ();
|
||||
priv->addr_cache = rtnl_addr_alloc_cache (priv->nlh);
|
||||
priv->route_cache = rtnl_route_alloc_cache (priv->nlh);
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMIP6ManagerPrivate *priv = NM_IP6_MANAGER_GET_PRIVATE (object);
|
||||
|
||||
g_hash_table_destroy (priv->devices);
|
||||
g_object_unref (priv->monitor);
|
||||
nl_cache_free (priv->addr_cache);
|
||||
nl_cache_free (priv->route_cache);
|
||||
|
||||
G_OBJECT_CLASS (nm_ip6_manager_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_ip6_manager_class_init (NMIP6ManagerClass *manager_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (manager_class);
|
||||
|
||||
g_type_class_add_private (manager_class, sizeof (NMIP6ManagerPrivate));
|
||||
|
||||
/* virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* signals */
|
||||
signals[ADDRCONF_COMPLETE] =
|
||||
g_signal_new ("addrconf-complete",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMIP6ManagerClass, addrconf_complete),
|
||||
NULL, NULL,
|
||||
_nm_marshal_VOID__INT_UINT_BOOLEAN,
|
||||
G_TYPE_NONE, 3, G_TYPE_INT, G_TYPE_UINT, G_TYPE_BOOLEAN);
|
||||
|
||||
signals[CONFIG_CHANGED] =
|
||||
g_signal_new ("config-changed",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_FIRST,
|
||||
G_STRUCT_OFFSET (NMIP6ManagerClass, config_changed),
|
||||
NULL, NULL,
|
||||
_nm_marshal_VOID__INT_UINT,
|
||||
G_TYPE_NONE, 2, G_TYPE_INT, G_TYPE_UINT);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2009 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_IP6_MANAGER_H
|
||||
|
|
@ -54,7 +54,7 @@ typedef struct {
|
|||
* that the initial configuration is complete.
|
||||
*/
|
||||
void (*addrconf_complete) (NMIP6Manager *manager,
|
||||
char *iface,
|
||||
guint32 ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success);
|
||||
|
||||
|
|
@ -63,22 +63,22 @@ typedef struct {
|
|||
* of the interface has changed.
|
||||
*/
|
||||
void (*config_changed) (NMIP6Manager *manager,
|
||||
char *iface,
|
||||
guint32 ifindex,
|
||||
guint dhcp_opts);
|
||||
} NMIP6ManagerClass;
|
||||
|
||||
GType nm_ip6_manager_get_type (void);
|
||||
|
||||
NMIP6Manager *nm_ip6_manager_get (void);
|
||||
void nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
||||
const char *iface,
|
||||
NMSettingIP6Config *s_ip6);
|
||||
void nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
void nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
NMIP6Manager *nm_ip6_manager_get (void);
|
||||
void nm_ip6_manager_prepare_interface (NMIP6Manager *manager,
|
||||
int ifindex,
|
||||
NMSettingIP6Config *s_ip6);
|
||||
void nm_ip6_manager_begin_addrconf (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
void nm_ip6_manager_cancel_addrconf (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
|
||||
NMIP6Config * nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
||||
const char *iface);
|
||||
NMIP6Config * nm_ip6_manager_get_ip6_config (NMIP6Manager *manager,
|
||||
int ifindex);
|
||||
|
||||
#endif /* NM_IP6_MANAGER_H */
|
||||
|
|
|
|||
|
|
@ -1,406 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*
|
||||
* Some code borrowed from HAL:
|
||||
*
|
||||
* Copyright (C) 2003 David Zeuthen, <david@fubar.dk>
|
||||
* Copyright (C) 2004 Novell, Inc.
|
||||
*/
|
||||
|
||||
/* FIXME: this should be merged with src/nm-netlink-monitor.c */
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <linux/types.h>
|
||||
#include <linux/netlink.h>
|
||||
#include <linux/rtnetlink.h>
|
||||
#include <linux/if.h>
|
||||
#include <linux/unistd.h>
|
||||
#include <unistd.h>
|
||||
#include <stdio.h>
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib/gi18n.h>
|
||||
|
||||
#include "NetworkManager.h"
|
||||
#include "nm-system.h"
|
||||
#include "nm-netlink-listener.h"
|
||||
#include "nm-marshal.h"
|
||||
#include "nm-netlink.h"
|
||||
|
||||
#define NM_NETLINK_LISTENER_EVENT_CONDITIONS \
|
||||
((GIOCondition) (G_IO_IN | G_IO_PRI))
|
||||
|
||||
#define NM_NETLINK_LISTENER_ERROR_CONDITIONS \
|
||||
((GIOCondition) (G_IO_ERR | G_IO_NVAL))
|
||||
|
||||
#define NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS \
|
||||
((GIOCondition) (G_IO_HUP))
|
||||
|
||||
#define NM_NETLINK_LISTENER_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), \
|
||||
NM_TYPE_NETLINK_LISTENER, \
|
||||
NMNetlinkListenerPrivate))
|
||||
|
||||
typedef struct {
|
||||
struct nl_handle *nlh;
|
||||
struct nl_cb * nlh_cb;
|
||||
struct nl_cache * nlh_link_cache;
|
||||
|
||||
GIOChannel * io_channel;
|
||||
guint event_id;
|
||||
|
||||
guint request_status_id;
|
||||
} NMNetlinkListenerPrivate;
|
||||
|
||||
static gboolean nm_netlink_listener_event_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
gpointer user_data);
|
||||
|
||||
static gboolean nm_netlink_listener_error_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener);
|
||||
|
||||
static gboolean nm_netlink_listener_disconnect_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener);
|
||||
|
||||
static void close_connection (NMNetlinkListener *listener);
|
||||
|
||||
enum {
|
||||
NOTIFICATION = 0,
|
||||
ERROR,
|
||||
|
||||
LAST_SIGNAL
|
||||
};
|
||||
|
||||
static guint signals[LAST_SIGNAL] = { 0 };
|
||||
|
||||
G_DEFINE_TYPE (NMNetlinkListener, nm_netlink_listener, G_TYPE_OBJECT);
|
||||
|
||||
NMNetlinkListener *
|
||||
nm_netlink_listener_get (void)
|
||||
{
|
||||
static NMNetlinkListener *singleton = NULL;
|
||||
|
||||
if (!singleton)
|
||||
singleton = NM_NETLINK_LISTENER (g_object_new (NM_TYPE_NETLINK_LISTENER, NULL));
|
||||
else
|
||||
g_object_ref (singleton);
|
||||
|
||||
return singleton;
|
||||
}
|
||||
|
||||
static void
|
||||
nm_netlink_listener_init (NMNetlinkListener *listener)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
finalize (GObject *object)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (object);
|
||||
|
||||
if (priv->request_status_id)
|
||||
g_source_remove (priv->request_status_id);
|
||||
|
||||
if (priv->io_channel)
|
||||
close_connection (NM_NETLINK_LISTENER (object));
|
||||
|
||||
if (priv->nlh) {
|
||||
nl_handle_destroy (priv->nlh);
|
||||
priv->nlh = NULL;
|
||||
}
|
||||
|
||||
if (priv->nlh_cb) {
|
||||
nl_cb_put (priv->nlh_cb);
|
||||
priv->nlh_cb = NULL;
|
||||
}
|
||||
|
||||
G_OBJECT_CLASS (nm_netlink_listener_parent_class)->finalize (object);
|
||||
}
|
||||
|
||||
static void
|
||||
nm_netlink_listener_class_init (NMNetlinkListenerClass *listener_class)
|
||||
{
|
||||
GObjectClass *object_class = G_OBJECT_CLASS (listener_class);
|
||||
|
||||
g_type_class_add_private (listener_class, sizeof (NMNetlinkListenerPrivate));
|
||||
|
||||
/* Virtual methods */
|
||||
object_class->finalize = finalize;
|
||||
|
||||
/* Signals */
|
||||
signals[NOTIFICATION] =
|
||||
g_signal_new ("notification",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMNetlinkListenerClass, notification),
|
||||
NULL, NULL, g_cclosure_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
|
||||
signals[ERROR] =
|
||||
g_signal_new ("error",
|
||||
G_OBJECT_CLASS_TYPE (object_class),
|
||||
G_SIGNAL_RUN_LAST,
|
||||
G_STRUCT_OFFSET (NMNetlinkListenerClass, error),
|
||||
NULL, NULL, _nm_marshal_VOID__POINTER,
|
||||
G_TYPE_NONE, 1, G_TYPE_POINTER);
|
||||
}
|
||||
|
||||
static int
|
||||
netlink_event_input (struct nl_msg *msg, void *listener)
|
||||
{
|
||||
struct nlmsghdr *hdr = nlmsg_hdr (msg);
|
||||
|
||||
if (hdr->nlmsg_pid != 0)
|
||||
return NL_STOP;
|
||||
|
||||
g_signal_emit (listener, signals[NOTIFICATION], 0, msg);
|
||||
|
||||
/* Stop processing messages */
|
||||
return NL_STOP;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
open_connection (NMNetlinkListener *listener, GError **error)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
int fd;
|
||||
GError *channel_error = NULL;
|
||||
GIOFlags channel_flags;
|
||||
|
||||
g_return_val_if_fail (priv->io_channel == NULL, FALSE);
|
||||
|
||||
priv->nlh_cb = nl_cb_alloc (NL_CB_DEFAULT);
|
||||
priv->nlh = nl_handle_alloc_cb (priv->nlh_cb);
|
||||
if (!priv->nlh) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_HANDLE,
|
||||
_("unable to allocate netlink handle: %s"),
|
||||
nl_geterror ());
|
||||
goto error;
|
||||
}
|
||||
|
||||
nl_disable_sequence_check (priv->nlh);
|
||||
nl_socket_modify_cb (priv->nlh, NL_CB_VALID, NL_CB_CUSTOM, netlink_event_input, listener);
|
||||
if (nl_connect (priv->nlh, NETLINK_ROUTE) < 0) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_CONNECT,
|
||||
_("unable to connect to netlink: %s"),
|
||||
nl_geterror ());
|
||||
goto error;
|
||||
}
|
||||
|
||||
fd = nl_socket_get_fd (priv->nlh);
|
||||
priv->io_channel = g_io_channel_unix_new (fd);
|
||||
|
||||
g_io_channel_set_encoding (priv->io_channel, NULL, &channel_error);
|
||||
/* Encoding is NULL, so no conversion error can possibly occur */
|
||||
g_assert (channel_error == NULL);
|
||||
|
||||
g_io_channel_set_close_on_unref (priv->io_channel, TRUE);
|
||||
channel_flags = g_io_channel_get_flags (priv->io_channel);
|
||||
channel_error = NULL;
|
||||
g_io_channel_set_flags (priv->io_channel,
|
||||
channel_flags | G_IO_FLAG_NONBLOCK,
|
||||
&channel_error);
|
||||
if (channel_error != NULL) {
|
||||
g_propagate_error (error, channel_error);
|
||||
goto error;
|
||||
}
|
||||
|
||||
priv->event_id = g_io_add_watch (priv->io_channel,
|
||||
(NM_NETLINK_LISTENER_EVENT_CONDITIONS |
|
||||
NM_NETLINK_LISTENER_ERROR_CONDITIONS |
|
||||
NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS),
|
||||
nm_netlink_listener_event_handler,
|
||||
listener);
|
||||
return TRUE;
|
||||
|
||||
error:
|
||||
if (priv->io_channel)
|
||||
close_connection (listener);
|
||||
|
||||
if (priv->nlh) {
|
||||
nl_handle_destroy (priv->nlh);
|
||||
priv->nlh = NULL;
|
||||
}
|
||||
|
||||
if (priv->nlh_cb) {
|
||||
nl_cb_put (priv->nlh_cb);
|
||||
priv->nlh_cb = NULL;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static void
|
||||
close_connection (NMNetlinkListener *listener)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
|
||||
g_return_if_fail (priv->io_channel != NULL);
|
||||
|
||||
if (priv->event_id) {
|
||||
g_source_remove (priv->event_id);
|
||||
priv->event_id = 0;
|
||||
}
|
||||
|
||||
g_io_channel_shutdown (priv->io_channel,
|
||||
TRUE /* flush pending data */,
|
||||
NULL);
|
||||
|
||||
g_io_channel_unref (priv->io_channel);
|
||||
priv->io_channel = NULL;
|
||||
}
|
||||
|
||||
GQuark
|
||||
nm_netlink_listener_error_quark (void)
|
||||
{
|
||||
static GQuark error_quark = 0;
|
||||
|
||||
if (error_quark == 0)
|
||||
error_quark = g_quark_from_static_string ("nm-netlink-listener-error-quark");
|
||||
|
||||
return error_quark;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_netlink_listener_subscribe (NMNetlinkListener *listener,
|
||||
int group,
|
||||
GError **error)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
|
||||
g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), FALSE);
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
|
||||
if (!priv->nlh) {
|
||||
if (!open_connection (listener, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
if (nl_socket_add_membership (priv->nlh, group) < 0) {
|
||||
g_set_error (error, NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_JOIN_GROUP,
|
||||
_("unable to join netlink group: %s"),
|
||||
nl_geterror ());
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
nm_netlink_listener_unsubscribe (NMNetlinkListener *listener, int group)
|
||||
{
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_NETLINK_LISTENER (listener));
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
g_return_if_fail (priv->nlh != NULL);
|
||||
|
||||
nl_socket_drop_membership (priv->nlh, group);
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_event_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMNetlinkListener *listener = (NMNetlinkListener *) user_data;
|
||||
NMNetlinkListenerPrivate *priv;
|
||||
GError *error = NULL;
|
||||
|
||||
g_return_val_if_fail (NM_IS_NETLINK_LISTENER (listener), TRUE);
|
||||
|
||||
priv = NM_NETLINK_LISTENER_GET_PRIVATE (listener);
|
||||
g_return_val_if_fail (priv->event_id > 0, TRUE);
|
||||
|
||||
if (io_condition & NM_NETLINK_LISTENER_ERROR_CONDITIONS)
|
||||
return nm_netlink_listener_error_handler (channel, io_condition, listener);
|
||||
else if (io_condition & NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS)
|
||||
return nm_netlink_listener_disconnect_handler (channel, io_condition, listener);
|
||||
|
||||
g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_LISTENER_EVENT_CONDITIONS)), FALSE);
|
||||
|
||||
if (nl_recvmsgs_default (priv->nlh) < 0) {
|
||||
error = g_error_new (NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_PROCESSING_MESSAGE,
|
||||
_("error processing netlink message: %s"),
|
||||
nl_geterror ());
|
||||
|
||||
g_signal_emit (G_OBJECT (listener),
|
||||
signals[ERROR],
|
||||
0, error);
|
||||
g_error_free (error);
|
||||
}
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_error_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener)
|
||||
{
|
||||
GError *socket_error;
|
||||
const char *err_msg;
|
||||
int err_code;
|
||||
socklen_t err_len;
|
||||
|
||||
g_return_val_if_fail (io_condition & NM_NETLINK_LISTENER_ERROR_CONDITIONS, FALSE);
|
||||
|
||||
err_code = 0;
|
||||
err_len = sizeof (err_code);
|
||||
if (getsockopt (g_io_channel_unix_get_fd (channel),
|
||||
SOL_SOCKET, SO_ERROR, (void *) &err_code, &err_len))
|
||||
err_msg = strerror (err_code);
|
||||
else
|
||||
err_msg = _("error occurred while waiting for data on socket");
|
||||
|
||||
socket_error = g_error_new (NM_NETLINK_LISTENER_ERROR,
|
||||
NM_NETLINK_LISTENER_ERROR_WAITING_FOR_SOCKET_DATA,
|
||||
"%s",
|
||||
err_msg);
|
||||
|
||||
g_signal_emit (G_OBJECT (listener),
|
||||
signals[ERROR],
|
||||
0, socket_error);
|
||||
|
||||
g_error_free (socket_error);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
nm_netlink_listener_disconnect_handler (GIOChannel *channel,
|
||||
GIOCondition io_condition,
|
||||
NMNetlinkListener *listener)
|
||||
{
|
||||
|
||||
g_return_val_if_fail (!(io_condition & ~(NM_NETLINK_LISTENER_DISCONNECT_CONDITIONS)), FALSE);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
|
|
@ -1,78 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Netlink socket listener
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2009 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*/
|
||||
|
||||
#ifndef NM_NETLINK_LISTENER_H
|
||||
#define NM_NETLINK_LISTENER_H
|
||||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
|
||||
#include "nm-netlink.h"
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_NETLINK_LISTENER (nm_netlink_listener_get_type ())
|
||||
#define NM_NETLINK_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_LISTENER, NMNetlinkListener))
|
||||
#define NM_NETLINK_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NETLINK_LISTENER, NMNetlinkListenerClass))
|
||||
#define NM_IS_NETLINK_LISTENER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_LISTENER))
|
||||
#define NM_IS_NETLINK_LISTENER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NETLINK_LISTENER))
|
||||
#define NM_NETLINK_LISTENER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_NETLINK_LISTENER, NMNetlinkListenerClass))
|
||||
#define NM_NETLINK_LISTENER_ERROR (nm_netlink_listener_error_quark ())
|
||||
|
||||
typedef enum {
|
||||
NM_NETLINK_LISTENER_ERROR_GENERIC = 0,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_HANDLE,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_CONNECT,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_JOIN_GROUP,
|
||||
NM_NETLINK_LISTENER_ERROR_NETLINK_ALLOC_LINK_CACHE,
|
||||
NM_NETLINK_LISTENER_ERROR_PROCESSING_MESSAGE,
|
||||
NM_NETLINK_LISTENER_ERROR_BAD_ALLOC,
|
||||
NM_NETLINK_LISTENER_ERROR_WAITING_FOR_SOCKET_DATA,
|
||||
NM_NETLINK_LISTENER_ERROR_LINK_CACHE_UPDATE
|
||||
} NMNetlinkListenerError;
|
||||
|
||||
typedef struct {
|
||||
GObject parent;
|
||||
} NMNetlinkListener;
|
||||
|
||||
typedef struct {
|
||||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*notification) (NMNetlinkListener *listener, struct nl_msg *msg);
|
||||
void (*error) (NMNetlinkListener *listener, GError *error);
|
||||
} NMNetlinkListenerClass;
|
||||
|
||||
GType nm_netlink_listener_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_listener_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
NMNetlinkListener *nm_netlink_listener_get (void);
|
||||
|
||||
gboolean nm_netlink_listener_subscribe (NMNetlinkListener *listener,
|
||||
int group,
|
||||
GError **error);
|
||||
void nm_netlink_listener_unsubscribe (NMNetlinkListener *listener,
|
||||
int group);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_NETLINK_LISTENER_H */
|
||||
|
|
@ -10,5 +10,6 @@ libnm_logging_la_CPPFLAGS = \
|
|||
-DG_DISABLE_DEPRECATED
|
||||
|
||||
libnm_logging_la_LIBADD = \
|
||||
-ldl \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
|
||||
#include "nm-named-manager.h"
|
||||
#include "nm-ip4-config.h"
|
||||
#include "nm-ip6-config.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-system.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
|
|
@ -60,8 +61,10 @@ G_DEFINE_TYPE(NMNamedManager, nm_named_manager, G_TYPE_OBJECT)
|
|||
|
||||
|
||||
struct NMNamedManagerPrivate {
|
||||
NMIP4Config *vpn_config;
|
||||
NMIP4Config *device_config;
|
||||
NMIP4Config *ip4_vpn_config;
|
||||
NMIP4Config *ip4_device_config;
|
||||
NMIP6Config *ip6_vpn_config;
|
||||
NMIP6Config *ip6_device_config;
|
||||
GSList *configs;
|
||||
};
|
||||
|
||||
|
|
@ -513,25 +516,33 @@ rewrite_resolv_conf (NMNamedManager *mgr, const char *iface, GError **error)
|
|||
rc.domain = NULL;
|
||||
rc.searches = g_ptr_array_new ();
|
||||
|
||||
if (priv->vpn_config)
|
||||
merge_one_ip4_config (&rc, priv->vpn_config);
|
||||
if (priv->ip4_vpn_config)
|
||||
merge_one_ip4_config (&rc, priv->ip4_vpn_config);
|
||||
if (priv->ip4_device_config)
|
||||
merge_one_ip4_config (&rc, priv->ip4_device_config);
|
||||
|
||||
if (priv->device_config)
|
||||
merge_one_ip4_config (&rc, priv->device_config);
|
||||
if (priv->ip6_vpn_config)
|
||||
merge_one_ip6_config (&rc, priv->ip6_vpn_config);
|
||||
if (priv->ip6_device_config)
|
||||
merge_one_ip6_config (&rc, priv->ip6_device_config);
|
||||
|
||||
for (iter = priv->configs; iter; iter = g_slist_next (iter)) {
|
||||
if ( (iter->data == priv->ip4_vpn_config)
|
||||
|| (iter->data == priv->ip4_device_config)
|
||||
|| (iter->data == priv->ip6_vpn_config)
|
||||
|| (iter->data == priv->ip6_device_config))
|
||||
continue;
|
||||
|
||||
if (NM_IS_IP4_CONFIG (iter->data)) {
|
||||
NMIP4Config *config = NM_IP4_CONFIG (iter->data);
|
||||
|
||||
if ((config == priv->vpn_config) || (config == priv->device_config))
|
||||
continue;
|
||||
|
||||
merge_one_ip4_config (&rc, config);
|
||||
} else {
|
||||
} else if (NM_IS_IP6_CONFIG (iter->data)) {
|
||||
NMIP6Config *config = NM_IP6_CONFIG (iter->data);
|
||||
|
||||
merge_one_ip6_config (&rc, config);
|
||||
}
|
||||
} else
|
||||
g_assert_not_reached ();
|
||||
}
|
||||
|
||||
domain = rc.domain;
|
||||
|
|
@ -598,10 +609,10 @@ nm_named_manager_add_ip4_config (NMNamedManager *mgr,
|
|||
|
||||
switch (cfg_type) {
|
||||
case NM_NAMED_IP_CONFIG_TYPE_VPN:
|
||||
priv->vpn_config = config;
|
||||
priv->ip4_vpn_config = config;
|
||||
break;
|
||||
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
|
||||
priv->device_config = config;
|
||||
priv->ip4_device_config = config;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -639,11 +650,10 @@ nm_named_manager_remove_ip4_config (NMNamedManager *mgr,
|
|||
|
||||
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;
|
||||
if (config == priv->ip4_vpn_config)
|
||||
priv->ip4_vpn_config = NULL;
|
||||
if (config == priv->ip4_device_config)
|
||||
priv->ip4_device_config = NULL;
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
|
|
@ -669,10 +679,21 @@ nm_named_manager_add_ip6_config (NMNamedManager *mgr,
|
|||
g_return_val_if_fail (iface != NULL, FALSE);
|
||||
g_return_val_if_fail (config != NULL, FALSE);
|
||||
|
||||
g_return_val_if_fail (cfg_type == NM_NAMED_IP_CONFIG_TYPE_DEFAULT, FALSE);
|
||||
|
||||
priv = NM_NAMED_MANAGER_GET_PRIVATE (mgr);
|
||||
|
||||
switch (cfg_type) {
|
||||
case NM_NAMED_IP_CONFIG_TYPE_VPN:
|
||||
/* FIXME: not quite yet... */
|
||||
g_return_val_if_fail (cfg_type != NM_NAMED_IP_CONFIG_TYPE_VPN, FALSE);
|
||||
priv->ip6_vpn_config = config;
|
||||
break;
|
||||
case NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE:
|
||||
priv->ip6_device_config = config;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* Don't allow the same zone added twice */
|
||||
if (!g_slist_find (priv->configs, config))
|
||||
priv->configs = g_slist_append (priv->configs, g_object_ref (config));
|
||||
|
|
@ -705,6 +726,11 @@ nm_named_manager_remove_ip6_config (NMNamedManager *mgr,
|
|||
|
||||
priv->configs = g_slist_remove (priv->configs, config);
|
||||
|
||||
if (config == priv->ip6_vpn_config)
|
||||
priv->ip6_vpn_config = NULL;
|
||||
if (config == priv->ip6_device_config)
|
||||
priv->ip6_device_config = NULL;
|
||||
|
||||
g_object_unref (config);
|
||||
|
||||
if (!rewrite_resolv_conf (mgr, iface, &error)) {
|
||||
|
|
|
|||
|
|
@ -72,6 +72,7 @@ typedef struct {
|
|||
|
||||
NMActiveConnectionState state;
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
gboolean shared;
|
||||
GSList *share_rules;
|
||||
|
||||
|
|
@ -88,6 +89,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
PROP_VPN,
|
||||
|
||||
LAST_PROP
|
||||
|
|
@ -104,7 +106,7 @@ device_state_changed (NMDevice *device,
|
|||
NMActRequest *self = NM_ACT_REQUEST (user_data);
|
||||
NMActRequestPrivate *priv = NM_ACT_REQUEST_GET_PRIVATE (self);
|
||||
NMActiveConnectionState new_ac_state;
|
||||
gboolean new_default = FALSE;
|
||||
gboolean new_default = FALSE, new_default6 = FALSE;
|
||||
|
||||
/* Set NMActiveConnection state based on the device's state */
|
||||
switch (new_state) {
|
||||
|
|
@ -117,6 +119,7 @@ device_state_changed (NMDevice *device,
|
|||
case NM_DEVICE_STATE_ACTIVATED:
|
||||
new_ac_state = NM_ACTIVE_CONNECTION_STATE_ACTIVATED;
|
||||
new_default = priv->is_default;
|
||||
new_default6 = priv->is_default6;
|
||||
break;
|
||||
default:
|
||||
new_ac_state = NM_ACTIVE_CONNECTION_STATE_UNKNOWN;
|
||||
|
|
@ -132,6 +135,11 @@ device_state_changed (NMDevice *device,
|
|||
priv->is_default = new_default;
|
||||
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT);
|
||||
}
|
||||
|
||||
if (new_default6 != priv->is_default6) {
|
||||
priv->is_default6 = new_default6;
|
||||
g_object_notify (G_OBJECT (self), NM_ACTIVE_CONNECTION_DEFAULT6);
|
||||
}
|
||||
}
|
||||
|
||||
NMActRequest *
|
||||
|
|
@ -271,6 +279,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, priv->is_default);
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, priv->is_default6);
|
||||
break;
|
||||
case PROP_VPN:
|
||||
g_value_set_boolean (value, FALSE);
|
||||
break;
|
||||
|
|
@ -334,7 +345,14 @@ nm_act_request_class_init (NMActRequestClass *req_class)
|
|||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
|
|
@ -548,6 +566,29 @@ nm_act_request_get_default (NMActRequest *req)
|
|||
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default;
|
||||
}
|
||||
|
||||
void
|
||||
nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6)
|
||||
{
|
||||
NMActRequestPrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_ACT_REQUEST (req));
|
||||
|
||||
priv = NM_ACT_REQUEST_GET_PRIVATE (req);
|
||||
if (priv->is_default6 == is_default6)
|
||||
return;
|
||||
|
||||
priv->is_default6 = is_default6;
|
||||
g_object_notify (G_OBJECT (req), NM_ACTIVE_CONNECTION_DEFAULT6);
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_act_request_get_default6 (NMActRequest *req)
|
||||
{
|
||||
g_return_val_if_fail (NM_IS_ACT_REQUEST (req), FALSE);
|
||||
|
||||
return NM_ACT_REQUEST_GET_PRIVATE (req)->is_default6;
|
||||
}
|
||||
|
||||
static void
|
||||
share_child_setup (gpointer user_data G_GNUC_UNUSED)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* (C) Copyright 2005 - 2008 Red Hat, Inc.
|
||||
* (C) Copyright 2005 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_ACTIVATION_REQUEST_H
|
||||
|
|
@ -76,6 +76,10 @@ void nm_act_request_set_default (NMActRequest *req, gboolean is_default
|
|||
|
||||
gboolean nm_act_request_get_default (NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_default6 (NMActRequest *req, gboolean is_default6);
|
||||
|
||||
gboolean nm_act_request_get_default6 (NMActRequest *req);
|
||||
|
||||
gboolean nm_act_request_get_shared (NMActRequest *req);
|
||||
|
||||
void nm_act_request_set_shared (NMActRequest *req, gboolean shared);
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2008 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_ACTIVE_CONNECTION_H
|
||||
|
|
@ -30,6 +30,7 @@
|
|||
#define NM_ACTIVE_CONNECTION_DEVICES "devices"
|
||||
#define NM_ACTIVE_CONNECTION_STATE "state"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT "default"
|
||||
#define NM_ACTIVE_CONNECTION_DEFAULT6 "default6"
|
||||
#define NM_ACTIVE_CONNECTION_VPN "vpn"
|
||||
|
||||
char *nm_active_connection_get_next_object_path (void);
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include <linux/if.h>
|
||||
#include <errno.h>
|
||||
|
||||
#include <netlink/route/addr.h>
|
||||
|
||||
#include "nm-glib-compat.h"
|
||||
#include "nm-device-ethernet.h"
|
||||
#include "nm-device-interface.h"
|
||||
|
|
@ -43,7 +45,6 @@
|
|||
#include "nm-supplicant-manager.h"
|
||||
#include "nm-supplicant-interface.h"
|
||||
#include "nm-supplicant-config.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-system.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -105,7 +106,6 @@ typedef struct {
|
|||
|
||||
struct ether_addr hw_addr;
|
||||
gboolean carrier;
|
||||
guint32 ifindex;
|
||||
|
||||
NMNetlinkMonitor * monitor;
|
||||
gulong link_connected_id;
|
||||
|
|
@ -133,7 +133,6 @@ enum {
|
|||
PROP_HW_ADDRESS,
|
||||
PROP_SPEED,
|
||||
PROP_CARRIER,
|
||||
PROP_IFINDEX,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -246,11 +245,10 @@ carrier_on (NMNetlinkMonitor *monitor,
|
|||
{
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
guint32 caps;
|
||||
|
||||
/* Make sure signal is for us */
|
||||
if (idx == priv->ifindex) {
|
||||
if (idx == nm_device_get_ifindex (device)) {
|
||||
/* Ignore spurious netlink messages */
|
||||
caps = nm_device_get_capabilities (device);
|
||||
if (!(caps & NM_DEVICE_CAP_CARRIER_DETECT))
|
||||
|
|
@ -267,11 +265,10 @@ carrier_off (NMNetlinkMonitor *monitor,
|
|||
{
|
||||
NMDevice *device = NM_DEVICE (user_data);
|
||||
NMDeviceEthernet *self = NM_DEVICE_ETHERNET (device);
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
guint32 caps;
|
||||
|
||||
/* Make sure signal is for us */
|
||||
if (idx == priv->ifindex) {
|
||||
if (idx == nm_device_get_ifindex (device)) {
|
||||
NMDeviceState state;
|
||||
gboolean defer = FALSE;
|
||||
|
||||
|
|
@ -312,7 +309,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_ETHERNET_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
caps = nm_device_get_capabilities (self);
|
||||
if (caps & NM_DEVICE_CAP_CARRIER_DETECT) {
|
||||
|
|
@ -331,7 +329,7 @@ constructor (GType type,
|
|||
|
||||
/* Get initial link state */
|
||||
if (!nm_netlink_monitor_get_flags_sync (priv->monitor,
|
||||
priv->ifindex,
|
||||
nm_device_get_ifindex (NM_DEVICE (self)),
|
||||
&ifflags,
|
||||
&error)) {
|
||||
nm_log_warn (LOGD_HW | LOGD_ETHER,
|
||||
|
|
@ -426,8 +424,7 @@ real_hw_take_down (NMDevice *dev)
|
|||
NMDevice *
|
||||
nm_device_ethernet_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
g_return_val_if_fail (udi != NULL, NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
|
@ -437,7 +434,6 @@ nm_device_ethernet_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_ETHERNET_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "Ethernet",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_ETHERNET,
|
||||
NULL);
|
||||
|
|
@ -459,14 +455,6 @@ nm_device_ethernet_get_address (NMDeviceEthernet *self, struct ether_addr *addr)
|
|||
memcpy (addr, &(NM_DEVICE_ETHERNET_GET_PRIVATE (self)->hw_addr), sizeof (struct ether_addr));
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_device_ethernet_get_ifindex (NMDeviceEthernet *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_ETHERNET_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
/* Returns speed in Mb/s */
|
||||
static guint32
|
||||
nm_device_ethernet_get_speed (NMDeviceEthernet *self)
|
||||
|
|
@ -1618,7 +1606,7 @@ ip4_match_config (NMDevice *self, NMConnection *connection)
|
|||
int ifindex;
|
||||
AddrData check_data;
|
||||
|
||||
ifindex = nm_device_ethernet_get_ifindex (NM_DEVICE_ETHERNET (self));
|
||||
ifindex = nm_device_get_ifindex (self);
|
||||
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
g_assert (s_con);
|
||||
|
|
@ -1790,9 +1778,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_CARRIER:
|
||||
g_value_set_boolean (value, priv->carrier);
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, priv->ifindex);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1803,13 +1788,7 @@ static void
|
|||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceEthernetPrivate *priv = NM_DEVICE_ETHERNET_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -1876,14 +1855,6 @@ nm_device_ethernet_class_init (NMDeviceEthernetClass *klass)
|
|||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_ETHERNET_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
/* Signals */
|
||||
signals[PROPERTIES_CHANGED] =
|
||||
nm_properties_changed_signal_new (object_class,
|
||||
|
|
|
|||
|
|
@ -39,7 +39,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_ETHERNET_HW_ADDRESS "hw-address"
|
||||
#define NM_DEVICE_ETHERNET_SPEED "speed"
|
||||
#define NM_DEVICE_ETHERNET_CARRIER "carrier"
|
||||
#define NM_DEVICE_ETHERNET_IFINDEX "ifindex"
|
||||
|
||||
typedef struct {
|
||||
NMDevice parent;
|
||||
|
|
@ -58,14 +57,11 @@ GType nm_device_ethernet_get_type (void);
|
|||
|
||||
NMDevice *nm_device_ethernet_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
const char *driver);
|
||||
|
||||
void nm_device_ethernet_get_address (NMDeviceEthernet *dev,
|
||||
struct ether_addr *addr);
|
||||
|
||||
guint32 nm_device_ethernet_get_ifindex (NMDeviceEthernet *dev);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
#endif /* NM_DEVICE_ETHERNET_H */
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@
|
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2010 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "nm-marshal.h"
|
||||
|
|
@ -186,6 +186,14 @@ nm_device_interface_init (gpointer g_iface)
|
|||
RFKILL_TYPE_UNKNOWN,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
g_object_interface_install_property
|
||||
(g_iface,
|
||||
g_param_spec_int (NM_DEVICE_INTERFACE_IFINDEX,
|
||||
"Ifindex",
|
||||
"Ifindex",
|
||||
0, G_MAXINT, 0,
|
||||
G_PARAM_READABLE | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
/* Signals */
|
||||
g_signal_new ("state-changed",
|
||||
iface_type,
|
||||
|
|
|
|||
|
|
@ -57,8 +57,9 @@ typedef enum
|
|||
#define NM_DEVICE_INTERFACE_STATE "state"
|
||||
#define NM_DEVICE_INTERFACE_DEVICE_TYPE "device-type" /* ugh */
|
||||
#define NM_DEVICE_INTERFACE_MANAGED "managed"
|
||||
#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_TYPE_DESC "type-desc" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_RFKILL_TYPE "rfkill-type" /* Internal only */
|
||||
#define NM_DEVICE_INTERFACE_IFINDEX "ifindex" /* Internal only */
|
||||
|
||||
typedef enum {
|
||||
NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000,
|
||||
|
|
@ -77,6 +78,7 @@ typedef enum {
|
|||
NM_DEVICE_INTERFACE_PROP_MANAGED,
|
||||
NM_DEVICE_INTERFACE_PROP_TYPE_DESC,
|
||||
NM_DEVICE_INTERFACE_PROP_RFKILL_TYPE,
|
||||
NM_DEVICE_INTERFACE_PROP_IFINDEX,
|
||||
} NMDeviceInterfaceProp;
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -69,7 +69,6 @@ enum {
|
|||
PROP_HW_ADDRESS,
|
||||
PROP_COMPANION,
|
||||
PROP_ACTIVE_CHANNEL,
|
||||
PROP_IFINDEX,
|
||||
|
||||
LAST_PROP
|
||||
};
|
||||
|
|
@ -98,7 +97,6 @@ struct _NMDeviceOlpcMeshPrivate
|
|||
gboolean dispose_has_run;
|
||||
|
||||
struct ether_addr hw_addr;
|
||||
guint32 ifindex;
|
||||
|
||||
GByteArray * ssid;
|
||||
|
||||
|
|
@ -263,7 +261,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_OLPC_MESH, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
iface = nm_device_get_iface (NM_DEVICE (self));
|
||||
fd = socket (PF_INET, SOCK_DGRAM, 0);
|
||||
|
|
@ -539,15 +538,6 @@ nm_device_olpc_mesh_set_ssid (NMDeviceOlpcMesh *self, const GByteArray * ssid)
|
|||
close (sk);
|
||||
}
|
||||
|
||||
|
||||
guint32
|
||||
nm_device_olpc_mesh_get_ifindex (NMDeviceOlpcMesh *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_OLPC_MESH_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
/****************************************************************************/
|
||||
|
||||
static void
|
||||
|
|
@ -701,9 +691,6 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_ACTIVE_CHANNEL:
|
||||
g_value_set_uint (value, nm_device_olpc_mesh_get_channel (device));
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, nm_device_olpc_mesh_get_ifindex (device));
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -714,13 +701,7 @@ static void
|
|||
set_property (GObject *object, guint prop_id,
|
||||
const GValue *value, GParamSpec *pspec)
|
||||
{
|
||||
NMDeviceOlpcMeshPrivate *priv = NM_DEVICE_OLPC_MESH_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
default:
|
||||
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
|
||||
break;
|
||||
|
|
@ -780,13 +761,6 @@ nm_device_olpc_mesh_class_init (NMDeviceOlpcMeshClass *klass)
|
|||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_OLPC_MESH_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
|
||||
|
||||
signals[PROPERTIES_CHANGED] =
|
||||
nm_properties_changed_signal_new (object_class,
|
||||
G_STRUCT_OFFSET (NMDeviceOlpcMeshClass, properties_changed));
|
||||
|
|
@ -986,8 +960,7 @@ state_changed_cb (NMDevice *device, NMDeviceState state, gpointer user_data)
|
|||
NMDevice *
|
||||
nm_device_olpc_mesh_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
GObject *obj;
|
||||
|
||||
|
|
@ -999,7 +972,6 @@ nm_device_olpc_mesh_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_OLPC_MESH_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 OLPC Mesh",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_OLPC_MESH,
|
||||
NULL);
|
||||
|
|
|
|||
|
|
@ -46,7 +46,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_OLPC_MESH_COMPANION "companion"
|
||||
#define NM_DEVICE_OLPC_MESH_BITRATE "bitrate"
|
||||
#define NM_DEVICE_OLPC_MESH_ACTIVE_CHANNEL "active-channel"
|
||||
#define NM_DEVICE_OLPC_MESH_IFINDEX "ifindex"
|
||||
|
||||
#ifndef NM_DEVICE_OLPC_MESH_DEFINED
|
||||
#define NM_DEVICE_OLPC_MESH_DEFINED
|
||||
|
|
@ -75,10 +74,7 @@ GType nm_device_olpc_mesh_get_type (void);
|
|||
|
||||
NMDevice *nm_device_olpc_mesh_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
|
||||
guint32 nm_device_olpc_mesh_get_ifindex (NMDeviceOlpcMesh *self);
|
||||
const char *driver);
|
||||
|
||||
G_END_DECLS
|
||||
|
||||
|
|
|
|||
|
|
@ -82,7 +82,6 @@ enum {
|
|||
PROP_BITRATE,
|
||||
PROP_ACTIVE_ACCESS_POINT,
|
||||
PROP_CAPABILITIES,
|
||||
PROP_IFINDEX,
|
||||
PROP_SCANNING,
|
||||
PROP_IPW_RFKILL_STATE,
|
||||
|
||||
|
|
@ -144,7 +143,6 @@ struct _NMDeviceWifiPrivate {
|
|||
gboolean disposed;
|
||||
|
||||
struct ether_addr hw_addr;
|
||||
guint32 ifindex;
|
||||
|
||||
/* Legacy rfkill for ipw2x00; will be fixed with 2.6.33 kernel */
|
||||
char * ipw_rfkill_path;
|
||||
|
|
@ -579,7 +577,8 @@ constructor (GType type,
|
|||
priv = NM_DEVICE_WIFI_GET_PRIVATE (self);
|
||||
|
||||
nm_log_dbg (LOGD_HW | LOGD_WIFI, "(%s): kernel ifindex %d",
|
||||
nm_device_get_iface (NM_DEVICE (self)), priv->ifindex);
|
||||
nm_device_get_iface (NM_DEVICE (self)),
|
||||
nm_device_get_ifindex (NM_DEVICE (self)));
|
||||
|
||||
memset (&range, 0, sizeof (struct iw_range));
|
||||
success = wireless_get_range (NM_DEVICE_WIFI (object), &range, &response_len);
|
||||
|
|
@ -3462,14 +3461,6 @@ device_state_changed (NMDevice *device,
|
|||
remove_all_aps (self);
|
||||
}
|
||||
|
||||
guint32
|
||||
nm_device_wifi_get_ifindex (NMDeviceWifi *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, FALSE);
|
||||
|
||||
return NM_DEVICE_WIFI_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
NMAccessPoint *
|
||||
nm_device_wifi_get_activation_ap (NMDeviceWifi *self)
|
||||
{
|
||||
|
|
@ -3563,8 +3554,7 @@ real_set_enabled (NMDeviceInterface *device, gboolean enabled)
|
|||
NMDevice *
|
||||
nm_device_wifi_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex)
|
||||
const char *driver)
|
||||
{
|
||||
g_return_val_if_fail (udi != NULL, NULL);
|
||||
g_return_val_if_fail (iface != NULL, NULL);
|
||||
|
|
@ -3574,7 +3564,6 @@ nm_device_wifi_new (const char *udi,
|
|||
NM_DEVICE_INTERFACE_UDI, udi,
|
||||
NM_DEVICE_INTERFACE_IFACE, iface,
|
||||
NM_DEVICE_INTERFACE_DRIVER, driver,
|
||||
NM_DEVICE_WIFI_IFINDEX, ifindex,
|
||||
NM_DEVICE_INTERFACE_TYPE_DESC, "802.11 WiFi",
|
||||
NM_DEVICE_INTERFACE_DEVICE_TYPE, NM_DEVICE_TYPE_WIFI,
|
||||
NM_DEVICE_INTERFACE_RFKILL_TYPE, RFKILL_TYPE_WLAN,
|
||||
|
|
@ -3675,9 +3664,6 @@ get_property (GObject *object, guint prop_id,
|
|||
else
|
||||
g_value_set_boxed (value, "/");
|
||||
break;
|
||||
case PROP_IFINDEX:
|
||||
g_value_set_uint (value, nm_device_wifi_get_ifindex (device));
|
||||
break;
|
||||
case PROP_SCANNING:
|
||||
g_value_set_boolean (value, nm_supplicant_interface_get_scanning (priv->supplicant.iface));
|
||||
break;
|
||||
|
|
@ -3697,10 +3683,6 @@ set_property (GObject *object, guint prop_id,
|
|||
NMDeviceWifiPrivate *priv = NM_DEVICE_WIFI_GET_PRIVATE (object);
|
||||
|
||||
switch (prop_id) {
|
||||
case PROP_IFINDEX:
|
||||
/* construct-only */
|
||||
priv->ifindex = g_value_get_uint (value);
|
||||
break;
|
||||
case PROP_IPW_RFKILL_STATE:
|
||||
/* construct only */
|
||||
priv->ipw_rfkill_state = g_value_get_uint (value);
|
||||
|
|
@ -3788,13 +3770,6 @@ nm_device_wifi_class_init (NMDeviceWifiClass *klass)
|
|||
0, G_MAXUINT32, NM_WIFI_DEVICE_CAP_NONE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_IFINDEX,
|
||||
g_param_spec_uint (NM_DEVICE_WIFI_IFINDEX,
|
||||
"Ifindex",
|
||||
"Interface index",
|
||||
0, G_MAXUINT32, 0,
|
||||
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | NM_PROPERTY_PARAM_NO_EXPORT));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_SCANNING,
|
||||
g_param_spec_boolean (NM_DEVICE_WIFI_SCANNING,
|
||||
"Scanning",
|
||||
|
|
|
|||
|
|
@ -47,7 +47,6 @@ G_BEGIN_DECLS
|
|||
#define NM_DEVICE_WIFI_BITRATE "bitrate"
|
||||
#define NM_DEVICE_WIFI_ACTIVE_ACCESS_POINT "active-access-point"
|
||||
#define NM_DEVICE_WIFI_CAPABILITIES "wireless-capabilities"
|
||||
#define NM_DEVICE_WIFI_IFINDEX "ifindex"
|
||||
#define NM_DEVICE_WIFI_SCANNING "scanning"
|
||||
#define NM_DEVICE_WIFI_IPW_RFKILL_STATE "ipw-rfkill-state"
|
||||
|
||||
|
|
@ -84,8 +83,7 @@ GType nm_device_wifi_get_type (void);
|
|||
|
||||
NMDevice *nm_device_wifi_new (const char *udi,
|
||||
const char *iface,
|
||||
const char *driver,
|
||||
guint32 ifindex);
|
||||
const char *driver);
|
||||
|
||||
void nm_device_wifi_get_address (NMDeviceWifi *dev,
|
||||
struct ether_addr *addr);
|
||||
|
|
@ -102,8 +100,6 @@ NM80211Mode nm_device_wifi_get_mode (NMDeviceWifi *self);
|
|||
|
||||
NMAccessPoint * nm_device_wifi_get_activation_ap (NMDeviceWifi *self);
|
||||
|
||||
guint32 nm_device_wifi_get_ifindex (NMDeviceWifi *self);
|
||||
|
||||
RfKillState nm_device_wifi_get_ipw_rfkill_state (NMDeviceWifi *self);
|
||||
|
||||
G_END_DECLS
|
||||
|
|
|
|||
122
src/nm-device.c
122
src/nm-device.c
|
|
@ -45,7 +45,7 @@
|
|||
#include "nm-named-manager.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-setting-ip4-config.h"
|
||||
#include "nm-setting-ip6-config.h"
|
||||
#include "nm-setting-connection.h"
|
||||
|
|
@ -83,7 +83,9 @@ typedef struct {
|
|||
char * udi;
|
||||
char * path;
|
||||
char * iface; /* may change, could be renamed by user */
|
||||
int ifindex;
|
||||
char * ip_iface;
|
||||
int ip_ifindex;
|
||||
NMDeviceType type;
|
||||
char * type_desc;
|
||||
guint32 capabilities;
|
||||
|
|
@ -304,6 +306,13 @@ nm_device_get_iface (NMDevice *self)
|
|||
return NM_DEVICE_GET_PRIVATE (self)->iface;
|
||||
}
|
||||
|
||||
int
|
||||
nm_device_get_ifindex (NMDevice *self)
|
||||
{
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
return NM_DEVICE_GET_PRIVATE (self)->ifindex;
|
||||
}
|
||||
|
||||
const char *
|
||||
nm_device_get_ip_iface (NMDevice *self)
|
||||
|
|
@ -317,14 +326,36 @@ nm_device_get_ip_iface (NMDevice *self)
|
|||
return priv->ip_iface ? priv->ip_iface : priv->iface;
|
||||
}
|
||||
|
||||
int
|
||||
nm_device_get_ip_ifindex (NMDevice *self)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_val_if_fail (self != NULL, 0);
|
||||
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
/* If it's not set, default to iface */
|
||||
return priv->ip_iface ? priv->ip_ifindex : priv->ifindex;
|
||||
}
|
||||
|
||||
void
|
||||
nm_device_set_ip_iface (NMDevice *self, const char *iface)
|
||||
{
|
||||
NMDevicePrivate *priv;
|
||||
|
||||
g_return_if_fail (NM_IS_DEVICE (self));
|
||||
|
||||
g_free (NM_DEVICE_GET_PRIVATE (self)->ip_iface);
|
||||
NM_DEVICE_GET_PRIVATE (self)->ip_iface = iface ? g_strdup (iface) : NULL;
|
||||
priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
g_free (priv->ip_iface);
|
||||
priv->ip_ifindex = 0;
|
||||
|
||||
priv->ip_iface = g_strdup (iface);
|
||||
if (priv->ip_iface) {
|
||||
priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface);
|
||||
if (!priv->ip_ifindex) {
|
||||
nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", iface);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -545,7 +576,7 @@ activation_source_schedule (NMDevice *self, GSourceFunc func, int family)
|
|||
|
||||
static void
|
||||
ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint dhcp_opts,
|
||||
gboolean success,
|
||||
gpointer user_data)
|
||||
|
|
@ -558,7 +589,7 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
NMDeviceStateReason reason = NM_DEVICE_STATE_REASON_NONE;
|
||||
NMDeviceState state;
|
||||
|
||||
if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
|
||||
if (ifindex != nm_device_get_ip_ifindex (self))
|
||||
return;
|
||||
req = nm_device_get_act_request (self);
|
||||
if (!req)
|
||||
|
|
@ -614,13 +645,13 @@ ip6_addrconf_complete (NMIP6Manager *ip6_manager,
|
|||
|
||||
static void
|
||||
ip6_config_changed (NMIP6Manager *ip6_manager,
|
||||
const char *iface,
|
||||
int ifindex,
|
||||
guint dhcp_opts,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMDevice *self = NM_DEVICE (user_data);
|
||||
|
||||
if (strcmp (nm_device_get_ip_iface (self), iface) != 0)
|
||||
if (ifindex != nm_device_get_ip_ifindex (self))
|
||||
return;
|
||||
if (!nm_device_get_act_request (self))
|
||||
return;
|
||||
|
|
@ -675,7 +706,9 @@ addrconf6_setup (NMDevice *self)
|
|||
|
||||
ip_iface = nm_device_get_ip_iface (self);
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
nm_ip6_manager_prepare_interface (priv->ip6_manager, ip_iface, s_ip6);
|
||||
nm_ip6_manager_prepare_interface (priv->ip6_manager,
|
||||
nm_device_get_ip_ifindex (self),
|
||||
s_ip6);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -697,6 +730,7 @@ addrconf6_cleanup (NMDevice *self)
|
|||
priv->ip6_config_changed_sigid = 0;
|
||||
}
|
||||
|
||||
nm_ip6_manager_cancel_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self));
|
||||
g_object_unref (priv->ip6_manager);
|
||||
priv->ip6_manager = NULL;
|
||||
}
|
||||
|
|
@ -1278,6 +1312,22 @@ dhcp_state_changed (NMDHCPClient *client,
|
|||
else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED)
|
||||
nm_device_state_changed (device, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
||||
break;
|
||||
case DHC_STOP:
|
||||
case DHC_STOP6:
|
||||
case DHC_EXPIRE:
|
||||
case DHC_EXPIRE6:
|
||||
if (dev_state == NM_DEVICE_STATE_ACTIVATED) {
|
||||
if (ipv6)
|
||||
nm_dhcp6_config_reset (priv->dhcp6_config);
|
||||
else
|
||||
nm_dhcp4_config_reset (priv->dhcp4_config);
|
||||
|
||||
/* dhclient quit and can't get/renew a lease; so kill the connection */
|
||||
nm_device_state_changed (device,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
@ -1304,6 +1354,7 @@ dhcp_timeout (NMDHCPClient *client, gpointer user_data)
|
|||
static NMActStageReturn
|
||||
real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
||||
{
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
NMConnection *connection;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
|
|
@ -1333,7 +1384,6 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (!s_ip4 || !method || !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_AUTO)) {
|
||||
NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self);
|
||||
guint8 *anycast = NULL;
|
||||
|
||||
/* Begin a DHCP transaction on the interface */
|
||||
|
|
@ -1389,6 +1439,10 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
*reason = NM_DEVICE_STATE_REASON_AUTOIP_START_FAILED;
|
||||
ret = NM_ACT_STAGE_RETURN_FAILURE;
|
||||
}
|
||||
} else if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
/* Nothing to do... */
|
||||
priv->ip4_ready = TRUE;
|
||||
ret = NM_ACT_STAGE_RETURN_STOP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
|
|
@ -1481,10 +1535,14 @@ real_act_stage3_ip6_config_start (NMDevice *self, NMDeviceStateReason *reason)
|
|||
|
||||
if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
priv->ip6_waiting_for_config = TRUE;
|
||||
nm_ip6_manager_begin_addrconf (priv->ip6_manager, ip_iface);
|
||||
nm_ip6_manager_begin_addrconf (priv->ip6_manager, nm_device_get_ip_ifindex (self));
|
||||
ret = NM_ACT_STAGE_RETURN_POSTPONE;
|
||||
} else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_DHCP))
|
||||
ret = dhcp6_start (self, connection, IP6_DHCP_OPT_MANAGED, reason);
|
||||
else if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_IGNORE)) {
|
||||
priv->ip6_ready = TRUE;
|
||||
ret = NM_ACT_STAGE_RETURN_STOP;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -1517,6 +1575,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
|||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
||||
/* Nothing to do */
|
||||
} else
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
||||
|
||||
|
|
@ -1526,6 +1586,8 @@ nm_device_activate_stage3_ip_config_start (gpointer user_data)
|
|||
else if (ret == NM_ACT_STAGE_RETURN_FAILURE) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
} else if (ret == NM_ACT_STAGE_RETURN_STOP) {
|
||||
/* Nothing to do */
|
||||
} else
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_POSTPONE);
|
||||
|
||||
|
|
@ -1674,7 +1736,8 @@ real_act_stage4_get_ip4_config (NMDevice *self,
|
|||
*config = nm_device_new_ip4_shared_config (self, reason);
|
||||
if (*config)
|
||||
priv->dnsmasq_manager = nm_dnsmasq_manager_new (ip_iface);
|
||||
}
|
||||
} else if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED))
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
if (!*config) {
|
||||
|
|
@ -1866,7 +1929,8 @@ real_act_stage4_get_ip6_config (NMDevice *self,
|
|||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
|
||||
if (ip6_method_matches (connection, NM_SETTING_IP6_CONFIG_METHOD_AUTO)) {
|
||||
*config = nm_ip6_manager_get_ip6_config (priv->ip6_manager, ip_iface);
|
||||
*config = nm_ip6_manager_get_ip6_config (priv->ip6_manager,
|
||||
nm_device_get_ip_ifindex (self));
|
||||
if (*config) {
|
||||
/* Merge user-defined overrides into the IP6Config to be applied */
|
||||
nm_utils_merge_ip6_config (*config, s_ip6);
|
||||
|
|
@ -1896,10 +1960,8 @@ real_act_stage4_get_ip6_config (NMDevice *self,
|
|||
} else {
|
||||
*reason = NM_DEVICE_STATE_REASON_DHCP_ERROR;
|
||||
}
|
||||
} else {
|
||||
*config = NULL;
|
||||
} else
|
||||
ret = NM_ACT_STAGE_RETURN_SUCCESS;
|
||||
}
|
||||
|
||||
out:
|
||||
return ret;
|
||||
|
|
@ -2022,7 +2084,7 @@ nm_device_activate_stage4_ip6_config_timeout (gpointer user_data)
|
|||
goto out;
|
||||
}
|
||||
g_assert (ret == NM_ACT_STAGE_RETURN_SUCCESS);
|
||||
/* FIXME g_assert (ip6_config); */
|
||||
g_assert (ip6_config);
|
||||
|
||||
g_object_set_data (G_OBJECT (nm_device_get_act_request (self)),
|
||||
NM_ACT_REQUEST_IP6_CONFIG, ip6_config);
|
||||
|
|
@ -2230,6 +2292,16 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
|
||||
assumed = nm_act_request_get_assumed (priv->act_request);
|
||||
|
||||
if (!ip6_config && !ip4_config) {
|
||||
nm_log_info (LOGD_DEVICE,
|
||||
"Activation (%s) Stage 5 of 5 (IP Configure Commit) failed (no IP configuration found)",
|
||||
iface);
|
||||
nm_device_state_changed (self,
|
||||
NM_DEVICE_STATE_FAILED,
|
||||
NM_DEVICE_STATE_REASON_IP_CONFIG_UNAVAILABLE);
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (ip4_config && !nm_device_set_ip4_config (self, ip4_config, assumed, &reason)) {
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
|
|
@ -2239,6 +2311,8 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
nm_log_info (LOGD_DEVICE | LOGD_IP6,
|
||||
"Activation (%s) Stage 5 of 5 (IP Configure Commit) IPv6 failed",
|
||||
iface);
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, reason);
|
||||
goto out;
|
||||
}
|
||||
|
||||
connection = nm_act_request_get_connection (nm_device_get_act_request (self));
|
||||
|
|
@ -2248,7 +2322,7 @@ nm_device_activate_stage5_ip_config_commit (gpointer user_data)
|
|||
if (s_ip4)
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
if (s_ip4 && !strcmp (method, "shared")) {
|
||||
if (s_ip4 && !strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_SHARED)) {
|
||||
if (!start_sharing (self)) {
|
||||
nm_log_warn (LOGD_SHARING, "Activation (%s) Stage 5 of 5 (IP Configure Commit) start sharing failed.", iface);
|
||||
nm_device_state_changed (self, NM_DEVICE_STATE_FAILED, NM_DEVICE_STATE_REASON_SHARED_START_FAILED);
|
||||
|
|
@ -3088,7 +3162,14 @@ set_property (GObject *object, guint prop_id,
|
|||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_IFACE:
|
||||
g_free (priv->iface);
|
||||
priv->ifindex = 0;
|
||||
priv->iface = g_value_dup_string (value);
|
||||
if (priv->iface) {
|
||||
priv->ifindex = nm_netlink_iface_to_index (priv->iface);
|
||||
if (priv->ifindex < 0) {
|
||||
nm_log_warn (LOGD_HW, "(%s): failed to look up interface index", priv->iface);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_DRIVER:
|
||||
priv->driver = g_strdup (g_value_get_string (value));
|
||||
|
|
@ -3136,6 +3217,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case NM_DEVICE_INTERFACE_PROP_IFACE:
|
||||
g_value_set_string (value, priv->iface);
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_IFINDEX:
|
||||
g_value_set_int (value, priv->ifindex);
|
||||
break;
|
||||
case NM_DEVICE_INTERFACE_PROP_DRIVER:
|
||||
g_value_set_string (value, priv->driver);
|
||||
break;
|
||||
|
|
@ -3234,6 +3318,10 @@ nm_device_class_init (NMDeviceClass *klass)
|
|||
NM_DEVICE_INTERFACE_PROP_IFACE,
|
||||
NM_DEVICE_INTERFACE_IFACE);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
NM_DEVICE_INTERFACE_PROP_IFINDEX,
|
||||
NM_DEVICE_INTERFACE_IFINDEX);
|
||||
|
||||
g_object_class_override_property (object_class,
|
||||
NM_DEVICE_INTERFACE_PROP_DRIVER,
|
||||
NM_DEVICE_INTERFACE_DRIVER);
|
||||
|
|
|
|||
|
|
@ -38,7 +38,8 @@ typedef enum NMActStageReturn
|
|||
{
|
||||
NM_ACT_STAGE_RETURN_FAILURE = 0,
|
||||
NM_ACT_STAGE_RETURN_SUCCESS,
|
||||
NM_ACT_STAGE_RETURN_POSTPONE
|
||||
NM_ACT_STAGE_RETURN_POSTPONE,
|
||||
NM_ACT_STAGE_RETURN_STOP /* This activation chain is done */
|
||||
} NMActStageReturn;
|
||||
|
||||
|
||||
|
|
@ -128,7 +129,9 @@ void nm_device_set_path (NMDevice *dev, const char *path);
|
|||
|
||||
const char * nm_device_get_udi (NMDevice *dev);
|
||||
const char * nm_device_get_iface (NMDevice *dev);
|
||||
int nm_device_get_ifindex (NMDevice *dev);
|
||||
const char * nm_device_get_ip_iface (NMDevice *dev);
|
||||
int nm_device_get_ip_ifindex(NMDevice *dev);
|
||||
const char * nm_device_get_driver (NMDevice *dev);
|
||||
const char * nm_device_get_type_desc (NMDevice *dev);
|
||||
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2006 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
|
|
@ -692,34 +692,33 @@ nm_ip6_config_class_init (NMIP6ConfigClass *config_class)
|
|||
object_class->finalize = finalize;
|
||||
|
||||
/* properties */
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ADDRESSES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"IP6 addresses",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_NAMESERVERS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS,
|
||||
"Nameservers",
|
||||
"DNS list",
|
||||
DBUS_TYPE_G_UINT_ARRAY,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DOMAINS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS,
|
||||
"Domains",
|
||||
"Domains",
|
||||
DBUS_TYPE_G_ARRAY_OF_STRING,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_ROUTES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
|
||||
"Routes",
|
||||
"Routes",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UINT,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property (object_class, PROP_ADDRESSES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ADDRESSES,
|
||||
"Addresses",
|
||||
"IP6 addresses",
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ADDRESS,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_NAMESERVERS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_NAMESERVERS,
|
||||
"Nameservers",
|
||||
"DNS list",
|
||||
DBUS_TYPE_G_ARRAY_OF_ARRAY_OF_UCHAR,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_DOMAINS,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_DOMAINS,
|
||||
"Domains",
|
||||
"Domains",
|
||||
DBUS_TYPE_G_ARRAY_OF_STRING,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
g_object_class_install_property (object_class, PROP_ROUTES,
|
||||
g_param_spec_boxed (NM_IP6_CONFIG_ROUTES,
|
||||
"Routes",
|
||||
"Routes",
|
||||
DBUS_TYPE_G_ARRAY_OF_IP6_ROUTE,
|
||||
G_PARAM_READABLE));
|
||||
|
||||
dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (config_class),
|
||||
&dbus_glib_nm_ip6_config_object_info);
|
||||
|
|
|
|||
|
|
@ -1523,7 +1523,8 @@ add_device (NMManager *self, NMDevice *device)
|
|||
driver = nm_device_get_driver (device);
|
||||
if (!driver)
|
||||
driver = "unknown";
|
||||
nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s')", iface, type_desc, driver);
|
||||
nm_log_info (LOGD_HW, "(%s): new %s device (driver: '%s' ifindex: %d)",
|
||||
iface, type_desc, driver, nm_device_get_ifindex (device));
|
||||
|
||||
path = g_strdup_printf ("/org/freedesktop/NetworkManager/Devices/%d", devcount++);
|
||||
nm_device_set_path (device, path);
|
||||
|
|
@ -1794,20 +1795,11 @@ find_device_by_ifindex (NMManager *self, guint32 ifindex)
|
|||
GSList *iter;
|
||||
|
||||
for (iter = priv->devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *device = NM_DEVICE (iter->data);
|
||||
gint candidate_idx = 0;
|
||||
NMDevice *candidate = NM_DEVICE (iter->data);
|
||||
|
||||
if (NM_IS_DEVICE_ETHERNET (device))
|
||||
candidate_idx = nm_device_ethernet_get_ifindex (NM_DEVICE_ETHERNET (device));
|
||||
else if (NM_IS_DEVICE_WIFI (device))
|
||||
candidate_idx = nm_device_wifi_get_ifindex (NM_DEVICE_WIFI (device));
|
||||
else if (NM_IS_DEVICE_OLPC_MESH (device))
|
||||
candidate_idx = nm_device_olpc_mesh_get_ifindex (NM_DEVICE_OLPC_MESH (device));
|
||||
|
||||
if (candidate_idx == ifindex)
|
||||
return device;
|
||||
if (ifindex == nm_device_get_ifindex (candidate))
|
||||
return candidate;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -15,7 +15,7 @@
|
|||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2005 - 2008 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2005 - 2008 Novell, Inc.
|
||||
* Copyright (C) 2005 Ray Strode
|
||||
*/
|
||||
|
|
@ -25,16 +25,15 @@
|
|||
|
||||
#include <glib.h>
|
||||
#include <glib-object.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/route/link.h>
|
||||
|
||||
G_BEGIN_DECLS
|
||||
|
||||
#define NM_TYPE_NETLINK_MONITOR (nm_netlink_monitor_get_type ())
|
||||
#define NM_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitor))
|
||||
#define NM_TYPE_NETLINK_MONITOR (nm_netlink_monitor_get_type ())
|
||||
#define NM_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitor))
|
||||
#define NM_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitorClass))
|
||||
#define NM_IS_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_IS_NETLINK_MONITOR(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_IS_NETLINK_MONITOR_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), NM_TYPE_NETLINK_MONITOR))
|
||||
#define NM_NETLINK_MONITOR_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS((obj), NM_TYPE_NETLINK_MONITOR, NMNetlinkMonitorClass))
|
||||
#define NM_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_quark ())
|
||||
|
||||
typedef enum {
|
||||
NM_NETLINK_MONITOR_ERROR_GENERIC = 0,
|
||||
|
|
@ -56,29 +55,45 @@ typedef struct {
|
|||
GObjectClass parent_class;
|
||||
|
||||
/* Signals */
|
||||
void (*carrier_on) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*carrier_off) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*error) (NMNetlinkMonitor *monitor, GError *error);
|
||||
void (*notification) (NMNetlinkMonitor *monitor, struct nl_msg *msg);
|
||||
void (*carrier_on) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*carrier_off) (NMNetlinkMonitor *monitor, int index);
|
||||
void (*error) (NMNetlinkMonitor *monitor, GError *error);
|
||||
} NMNetlinkMonitorClass;
|
||||
|
||||
|
||||
GType nm_netlink_monitor_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_monitor_error_quark (void) G_GNUC_CONST;
|
||||
#define NM_NETLINK_MONITOR_ERROR (nm_netlink_monitor_error_quark ())
|
||||
GType nm_netlink_monitor_get_type (void) G_GNUC_CONST;
|
||||
GQuark nm_netlink_monitor_error_quark (void) G_GNUC_CONST;
|
||||
|
||||
NMNetlinkMonitor *nm_netlink_monitor_get (void);
|
||||
|
||||
gboolean nm_netlink_monitor_open_connection (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
gboolean nm_netlink_monitor_open_connection (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
void nm_netlink_monitor_close_connection (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_attach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_detach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_attach (NMNetlinkMonitor *monitor);
|
||||
void nm_netlink_monitor_detach (NMNetlinkMonitor *monitor);
|
||||
|
||||
gboolean nm_netlink_monitor_subscribe (NMNetlinkMonitor *monitor,
|
||||
int group,
|
||||
GError **error);
|
||||
void nm_netlink_monitor_unsubscribe (NMNetlinkMonitor *monitor,
|
||||
int group);
|
||||
|
||||
gboolean nm_netlink_monitor_request_ip6_info (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
|
||||
gboolean nm_netlink_monitor_request_status (NMNetlinkMonitor *monitor,
|
||||
GError **error);
|
||||
GError **error);
|
||||
gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor,
|
||||
guint32 ifindex,
|
||||
guint32 *ifflags,
|
||||
GError **error);
|
||||
|
||||
G_END_DECLS
|
||||
/* Generic utility functions */
|
||||
int nm_netlink_iface_to_index (const char *iface);
|
||||
char * nm_netlink_index_to_iface (int idx);
|
||||
struct rtnl_link *nm_netlink_index_to_rtnl_link (int idx);
|
||||
struct nl_handle *nm_netlink_get_default_handle (void);
|
||||
|
||||
#endif /* NM_NETLINK_MONITOR_H */
|
||||
|
|
|
|||
149
src/nm-netlink.c
149
src/nm-netlink.c
|
|
@ -1,149 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
#include <glib.h>
|
||||
#include <signal.h>
|
||||
#include <pthread.h>
|
||||
#include <unistd.h>
|
||||
#include <netlink/object-api.h>
|
||||
|
||||
static struct nl_cache * link_cache = NULL;
|
||||
static struct nl_handle * def_nl_handle = NULL;
|
||||
|
||||
|
||||
static struct nl_cache *
|
||||
get_link_cache (void)
|
||||
{
|
||||
struct nl_handle * nlh;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
if (G_UNLIKELY (!nlh)) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink handle.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (G_UNLIKELY (!link_cache))
|
||||
link_cache = rtnl_link_alloc_cache (nlh);
|
||||
|
||||
if (G_UNLIKELY (!link_cache)) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink link cache: %s", nl_geterror ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nl_cache_update (nlh, link_cache);
|
||||
return link_cache;
|
||||
}
|
||||
|
||||
|
||||
struct nl_handle *
|
||||
nm_netlink_get_default_handle (void)
|
||||
{
|
||||
struct nl_cb *cb;
|
||||
#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
|
||||
struct nl_cache *addr_cache;
|
||||
#endif
|
||||
|
||||
if (def_nl_handle)
|
||||
return def_nl_handle;
|
||||
|
||||
cb = nl_cb_alloc(NL_CB_VERBOSE);
|
||||
def_nl_handle = nl_handle_alloc_cb (cb);
|
||||
if (!def_nl_handle) {
|
||||
nm_log_err (LOGD_HW, "couldn't allocate netlink handle.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (nl_connect (def_nl_handle, NETLINK_ROUTE) < 0) {
|
||||
nm_log_err (LOGD_HW, "couldn't connect to netlink: %s", nl_geterror ());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND
|
||||
/* Work around apparent libnl bug; rtnl_addr requires that all
|
||||
* addresses have the "peer" attribute set in order to be compared
|
||||
* for equality, but this attribute is not normally set. As a
|
||||
* result, most addresses will not compare as equal even to
|
||||
* themselves, busting caching.
|
||||
*/
|
||||
addr_cache = rtnl_addr_alloc_cache (def_nl_handle);
|
||||
nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80;
|
||||
nl_cache_free (addr_cache);
|
||||
#endif
|
||||
|
||||
return def_nl_handle;
|
||||
}
|
||||
|
||||
int
|
||||
nm_netlink_iface_to_index (const char *iface)
|
||||
{
|
||||
struct nl_cache * cache;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, -1);
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return RTNL_LINK_NOT_FOUND;
|
||||
|
||||
return rtnl_link_name2i (cache, iface);
|
||||
}
|
||||
|
||||
|
||||
#define MAX_IFACE_LEN 33
|
||||
char *
|
||||
nm_netlink_index_to_iface (int idx)
|
||||
{
|
||||
struct nl_cache * cache;
|
||||
char * buf = NULL;
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
buf = g_malloc0 (MAX_IFACE_LEN);
|
||||
if (buf == NULL) {
|
||||
nm_log_warn (LOGD_HW, "Not enough memory to allocate interface name buffer.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (rtnl_link_i2name (cache, idx, buf, MAX_IFACE_LEN - 1) == NULL) {
|
||||
g_free (buf);
|
||||
buf = NULL;
|
||||
}
|
||||
|
||||
return buf;
|
||||
}
|
||||
|
||||
struct rtnl_link *
|
||||
nm_netlink_index_to_rtnl_link (int idx)
|
||||
{
|
||||
struct nl_cache *cache;
|
||||
|
||||
cache = get_link_cache ();
|
||||
if (!cache)
|
||||
return NULL;
|
||||
|
||||
return rtnl_link_get (cache, idx);
|
||||
}
|
||||
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2007 - 2008 Red Hat, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_NETLINK_H
|
||||
#define NM_NETLINK_H
|
||||
|
||||
#include <asm/types.h>
|
||||
#include <netlink/route/addr.h>
|
||||
#include <netlink/netlink.h>
|
||||
#include <netlink/utils.h>
|
||||
#include <netlink/route/link.h>
|
||||
|
||||
int nm_netlink_iface_to_index (const char *iface);
|
||||
char * nm_netlink_index_to_iface (int idx);
|
||||
struct rtnl_link * nm_netlink_index_to_rtnl_link (int idx);
|
||||
|
||||
struct nl_handle * nm_netlink_get_default_handle (void);
|
||||
|
||||
#endif /* NM_NETLINK_H */
|
||||
196
src/nm-policy-hostname.c
Normal file
196
src/nm-policy-hostname.c
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2004 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "nm-logging.h"
|
||||
#include "nm-policy-hostname.h"
|
||||
#include "nm-policy-hosts.h"
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
struct HostnameThread {
|
||||
GThread *thread;
|
||||
|
||||
GMutex *lock;
|
||||
gboolean dead;
|
||||
int ret;
|
||||
|
||||
guint32 ip4_addr;
|
||||
char hostname[NI_MAXHOST + 1];
|
||||
|
||||
HostnameThreadCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
|
||||
static gboolean
|
||||
hostname_thread_run_cb (gpointer user_data)
|
||||
{
|
||||
HostnameThread *ht = (HostnameThread *) user_data;
|
||||
|
||||
(*ht->callback) (ht, ht->ret, ht->hostname, ht->user_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
hostname_thread_worker (gpointer data)
|
||||
{
|
||||
HostnameThread *ht = (HostnameThread *) data;
|
||||
struct sockaddr_in addr;
|
||||
int i;
|
||||
|
||||
g_mutex_lock (ht->lock);
|
||||
if (ht->dead) {
|
||||
g_mutex_unlock (ht->lock);
|
||||
return (gpointer) NULL;
|
||||
}
|
||||
g_mutex_unlock (ht->lock);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = ht->ip4_addr;
|
||||
|
||||
ht->ret = getnameinfo ((struct sockaddr *) &addr, sizeof (struct sockaddr_in),
|
||||
ht->hostname, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (ht->ret == 0) {
|
||||
for (i = 0; i < strlen (ht->hostname); i++)
|
||||
ht->hostname[i] = tolower (ht->hostname[i]);
|
||||
}
|
||||
|
||||
/* Don't track the idle handler ID because by the time the g_idle_add()
|
||||
* returns the ID, the handler may already have run and freed the
|
||||
* HostnameThread.
|
||||
*/
|
||||
g_idle_add (hostname_thread_run_cb, ht);
|
||||
return (gpointer) TRUE;
|
||||
}
|
||||
|
||||
void
|
||||
hostname_thread_free (HostnameThread *ht)
|
||||
{
|
||||
g_return_if_fail (ht != NULL);
|
||||
|
||||
g_mutex_free (ht->lock);
|
||||
memset (ht, 0, sizeof (HostnameThread));
|
||||
g_free (ht);
|
||||
}
|
||||
|
||||
HostnameThread *
|
||||
hostname_thread_new (guint32 ip4_addr, HostnameThreadCallback callback, gpointer user_data)
|
||||
{
|
||||
HostnameThread *ht;
|
||||
|
||||
ht = g_malloc0 (sizeof (HostnameThread));
|
||||
g_assert (ht);
|
||||
|
||||
ht->lock = g_mutex_new ();
|
||||
ht->callback = callback;
|
||||
ht->user_data = user_data;
|
||||
ht->ip4_addr = ip4_addr;
|
||||
|
||||
ht->thread = g_thread_create (hostname_thread_worker, ht, FALSE, NULL);
|
||||
if (!ht->thread) {
|
||||
hostname_thread_free (ht);
|
||||
ht = NULL;
|
||||
}
|
||||
|
||||
return ht;
|
||||
}
|
||||
|
||||
void
|
||||
hostname_thread_kill (HostnameThread *ht)
|
||||
{
|
||||
g_return_if_fail (ht != NULL);
|
||||
|
||||
g_mutex_lock (ht->lock);
|
||||
ht->dead = TRUE;
|
||||
g_mutex_unlock (ht->lock);
|
||||
}
|
||||
|
||||
gboolean
|
||||
hostname_thread_is_dead (HostnameThread *ht)
|
||||
{
|
||||
g_return_val_if_fail (ht != NULL, TRUE);
|
||||
|
||||
return ht->dead;
|
||||
}
|
||||
|
||||
/************************************************************************/
|
||||
|
||||
#define FALLBACK_HOSTNAME "localhost.localdomain"
|
||||
|
||||
gboolean
|
||||
nm_policy_set_system_hostname (const char *new_hostname, const char *msg)
|
||||
{
|
||||
char old_hostname[HOST_NAME_MAX + 1];
|
||||
int ret = 0;
|
||||
const char *name = new_hostname ? new_hostname : FALLBACK_HOSTNAME;
|
||||
gboolean set_hostname = TRUE, changed = FALSE;
|
||||
|
||||
old_hostname[HOST_NAME_MAX] = '\0';
|
||||
errno = 0;
|
||||
ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||
errno, strerror (errno));
|
||||
} else {
|
||||
/* Don't set the hostname if it isn't actually changing */
|
||||
if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||
|| (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME)))
|
||||
set_hostname = FALSE;
|
||||
}
|
||||
|
||||
if (set_hostname) {
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||
ret = sethostname (name, strlen (name));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||
name, errno, strerror (errno));
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
/* But even if the hostname isn't changing, always try updating /etc/hosts
|
||||
* just in case the hostname changed while NM wasn't running; we need to
|
||||
* make sure that /etc/hosts has valid mappings for '127.0.0.1' and the
|
||||
* current system hostname. If those exist,
|
||||
* nm_policy_hosts_update_etc_hosts() will just return and won't touch
|
||||
* /etc/hosts at all.
|
||||
*/
|
||||
if (!nm_policy_hosts_update_etc_hosts (name, FALLBACK_HOSTNAME, &changed)) {
|
||||
/* error updating /etc/hosts; fallback to localhost.localdomain */
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '" FALLBACK_HOSTNAME "' (error updating /etc/hosts)");
|
||||
ret = sethostname (FALLBACK_HOSTNAME, strlen (FALLBACK_HOSTNAME));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the fallback system hostname (%s): (%d) %s",
|
||||
FALLBACK_HOSTNAME, errno, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
47
src/nm-policy-hostname.h
Normal file
47
src/nm-policy-hostname.h
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
|
||||
/* NetworkManager -- Network link manager
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation; either version 2 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License along
|
||||
* with this program; if not, write to the Free Software Foundation, Inc.,
|
||||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||
*
|
||||
* Copyright (C) 2004 - 2010 Red Hat, Inc.
|
||||
* Copyright (C) 2007 - 2008 Novell, Inc.
|
||||
*/
|
||||
|
||||
#ifndef NM_POLICY_HOSTNAME_H
|
||||
#define NM_POLICY_HOSTNAME_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
gboolean nm_policy_set_system_hostname (const char *new_hostname, const char *msg);
|
||||
|
||||
|
||||
typedef struct HostnameThread HostnameThread;
|
||||
|
||||
typedef void (*HostnameThreadCallback) (HostnameThread *ht,
|
||||
int error,
|
||||
const char *hostname,
|
||||
gpointer user_data);
|
||||
|
||||
HostnameThread * hostname_thread_new (guint32 ip4_addr,
|
||||
HostnameThreadCallback callback,
|
||||
gpointer user_data);
|
||||
|
||||
void hostname_thread_free (HostnameThread *ht);
|
||||
|
||||
gboolean hostname_thread_is_dead (HostnameThread *ht);
|
||||
|
||||
void hostname_thread_kill (HostnameThread *ht);
|
||||
|
||||
#endif /* NM_POLICY_HOSTNAME_H */
|
||||
|
|
@ -25,6 +25,7 @@
|
|||
#include <ctype.h>
|
||||
|
||||
#include "nm-policy-hosts.h"
|
||||
#include "nm-logging.h"
|
||||
|
||||
gboolean
|
||||
nm_policy_hosts_find_token (const char *line, const char *token)
|
||||
|
|
@ -171,3 +172,64 @@ nm_policy_get_etc_hosts (const char **lines,
|
|||
return contents;
|
||||
}
|
||||
|
||||
gboolean
|
||||
nm_policy_hosts_update_etc_hosts (const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
gboolean *out_changed)
|
||||
{
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
GError *error = NULL;
|
||||
GString *new_contents = NULL;
|
||||
gsize contents_len = 0;
|
||||
gboolean success = FALSE;
|
||||
|
||||
g_return_val_if_fail (hostname != NULL, FALSE);
|
||||
g_return_val_if_fail (out_changed != NULL, FALSE);
|
||||
|
||||
if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Get the new /etc/hosts contents */
|
||||
lines = g_strsplit_set (contents, "\n\r", 0);
|
||||
new_contents = nm_policy_get_etc_hosts ((const char **) lines,
|
||||
contents_len,
|
||||
hostname,
|
||||
fallback_hostname,
|
||||
&error);
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
|
||||
if (new_contents) {
|
||||
nm_log_info (LOGD_DNS, "Updating /etc/hosts with new system hostname");
|
||||
|
||||
g_clear_error (&error);
|
||||
/* And actually update /etc/hosts */
|
||||
if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
success = TRUE;
|
||||
*out_changed = TRUE;
|
||||
}
|
||||
|
||||
g_string_free (new_contents, TRUE);
|
||||
} else if (!error) {
|
||||
/* No change required */
|
||||
success = TRUE;
|
||||
} else {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error->code, error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
}
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -23,14 +23,18 @@
|
|||
|
||||
#include <glib.h>
|
||||
|
||||
gboolean nm_policy_hosts_update_etc_hosts (const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
gboolean *out_changed);
|
||||
|
||||
/* Only for testcases; don't use outside of nm-policy-hosts.c */
|
||||
gboolean nm_policy_hosts_find_token (const char *line, const char *token);
|
||||
|
||||
GString *nm_policy_get_etc_hosts (const char **lines,
|
||||
gsize existing_len,
|
||||
const char *hostname,
|
||||
const char *fallback_hostname,
|
||||
GError **error);
|
||||
|
||||
/* Only for testcases; don't use outside of nm-policy-hosts.c */
|
||||
gboolean nm_policy_hosts_find_token (const char *line, const char *token);
|
||||
|
||||
#endif /* NM_POLICY_HOSTS_H */
|
||||
|
||||
|
|
|
|||
510
src/nm-policy.c
510
src/nm-policy.c
|
|
@ -42,24 +42,7 @@
|
|||
#include "nm-named-manager.h"
|
||||
#include "nm-vpn-manager.h"
|
||||
#include "nm-policy-hosts.h"
|
||||
|
||||
typedef struct LookupThread LookupThread;
|
||||
|
||||
typedef void (*LookupCallback) (LookupThread *thread, gpointer user_data);
|
||||
|
||||
struct LookupThread {
|
||||
GThread *thread;
|
||||
|
||||
GMutex *lock;
|
||||
gboolean die;
|
||||
int ret;
|
||||
|
||||
guint32 ip4_addr;
|
||||
char hostname[NI_MAXHOST + 1];
|
||||
|
||||
LookupCallback callback;
|
||||
gpointer user_data;
|
||||
};
|
||||
#include "nm-policy-hostname.h"
|
||||
|
||||
struct NMPolicy {
|
||||
NMManager *manager;
|
||||
|
|
@ -72,99 +55,14 @@ struct NMPolicy {
|
|||
gulong vpn_activated_id;
|
||||
gulong vpn_deactivated_id;
|
||||
|
||||
NMDevice *default_device;
|
||||
NMDevice *default_device4;
|
||||
NMDevice *default_device6;
|
||||
|
||||
LookupThread *lookup;
|
||||
HostnameThread *lookup;
|
||||
|
||||
char *orig_hostname; /* hostname at NM start time */
|
||||
};
|
||||
|
||||
static gboolean
|
||||
lookup_thread_run_cb (gpointer user_data)
|
||||
{
|
||||
LookupThread *thread = (LookupThread *) user_data;
|
||||
|
||||
(*thread->callback) (thread, thread->user_data);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gpointer
|
||||
lookup_thread_worker (gpointer data)
|
||||
{
|
||||
LookupThread *thread = (LookupThread *) data;
|
||||
struct sockaddr_in addr;
|
||||
|
||||
g_mutex_lock (thread->lock);
|
||||
if (thread->die) {
|
||||
g_mutex_unlock (thread->lock);
|
||||
return (gpointer) NULL;
|
||||
}
|
||||
g_mutex_unlock (thread->lock);
|
||||
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_addr.s_addr = thread->ip4_addr;
|
||||
|
||||
thread->ret = getnameinfo ((struct sockaddr *) &addr, sizeof (struct sockaddr_in),
|
||||
thread->hostname, NI_MAXHOST, NULL, 0,
|
||||
NI_NAMEREQD);
|
||||
if (thread->ret == 0) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < strlen (thread->hostname); i++)
|
||||
thread->hostname[i] = tolower (thread->hostname[i]);
|
||||
}
|
||||
|
||||
/* Don't track the idle handler ID because by the time the g_idle_add()
|
||||
* returns the ID, the handler may already have run and freed the
|
||||
* LookupThread.
|
||||
*/
|
||||
g_idle_add (lookup_thread_run_cb, thread);
|
||||
return (gpointer) TRUE;
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_thread_free (LookupThread *thread)
|
||||
{
|
||||
g_return_if_fail (thread != NULL);
|
||||
|
||||
g_mutex_free (thread->lock);
|
||||
memset (thread, 0, sizeof (LookupThread));
|
||||
g_free (thread);
|
||||
}
|
||||
|
||||
static LookupThread *
|
||||
lookup_thread_new (guint32 ip4_addr, LookupCallback callback, gpointer user_data)
|
||||
{
|
||||
LookupThread *thread;
|
||||
|
||||
thread = g_malloc0 (sizeof (LookupThread));
|
||||
if (!thread)
|
||||
return NULL;
|
||||
|
||||
thread->lock = g_mutex_new ();
|
||||
thread->callback = callback;
|
||||
thread->user_data = user_data;
|
||||
thread->ip4_addr = ip4_addr;
|
||||
|
||||
thread->thread = g_thread_create (lookup_thread_worker, thread, FALSE, NULL);
|
||||
if (!thread->thread) {
|
||||
lookup_thread_free (thread);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return thread;
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_thread_die (LookupThread *thread)
|
||||
{
|
||||
g_return_if_fail (thread != NULL);
|
||||
|
||||
g_mutex_lock (thread->lock);
|
||||
thread->die = TRUE;
|
||||
g_mutex_unlock (thread->lock);
|
||||
}
|
||||
|
||||
#define INVALID_TAG "invalid"
|
||||
|
||||
static const char *
|
||||
|
|
@ -181,7 +79,7 @@ get_connection_id (NMConnection *connection)
|
|||
}
|
||||
|
||||
static NMDevice *
|
||||
get_best_device (NMManager *manager, NMActRequest **out_req)
|
||||
get_best_ip4_device (NMManager *manager, NMActRequest **out_req)
|
||||
{
|
||||
GSList *devices, *iter;
|
||||
NMDevice *best = NULL;
|
||||
|
|
@ -253,142 +151,107 @@ get_best_device (NMManager *manager, NMActRequest **out_req)
|
|||
return best;
|
||||
}
|
||||
|
||||
#define FALLBACK_HOSTNAME "localhost.localdomain"
|
||||
|
||||
static gboolean
|
||||
update_etc_hosts (const char *hostname, gboolean *out_changed)
|
||||
static NMDevice *
|
||||
get_best_ip6_device (NMManager *manager, NMActRequest **out_req)
|
||||
{
|
||||
char *contents = NULL;
|
||||
char **lines = NULL;
|
||||
GError *error = NULL;
|
||||
GString *new_contents = NULL;
|
||||
gsize contents_len = 0;
|
||||
gboolean success = FALSE;
|
||||
GSList *devices, *iter;
|
||||
NMDevice *best = NULL;
|
||||
int best_prio = G_MAXINT;
|
||||
|
||||
g_return_val_if_fail (hostname != NULL, FALSE);
|
||||
g_return_val_if_fail (out_changed != NULL, FALSE);
|
||||
g_return_val_if_fail (manager != NULL, NULL);
|
||||
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
|
||||
g_return_val_if_fail (out_req != NULL, NULL);
|
||||
g_return_val_if_fail (*out_req == NULL, NULL);
|
||||
|
||||
if (!g_file_get_contents (SYSCONFDIR "/hosts", &contents, &contents_len, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
return FALSE;
|
||||
}
|
||||
devices = nm_manager_get_devices (manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *dev = NM_DEVICE (iter->data);
|
||||
NMActRequest *req;
|
||||
NMConnection *connection;
|
||||
NMIP6Config *ip6_config;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
int prio;
|
||||
guint i;
|
||||
gboolean can_default = FALSE;
|
||||
const char *method = NULL;
|
||||
|
||||
/* Get the new /etc/hosts contents */
|
||||
lines = g_strsplit_set (contents, "\n\r", 0);
|
||||
new_contents = nm_policy_get_etc_hosts ((const char **) lines,
|
||||
contents_len,
|
||||
hostname,
|
||||
FALLBACK_HOSTNAME,
|
||||
&error);
|
||||
g_strfreev (lines);
|
||||
g_free (contents);
|
||||
if (nm_device_get_state (dev) != NM_DEVICE_STATE_ACTIVATED)
|
||||
continue;
|
||||
|
||||
if (new_contents) {
|
||||
nm_log_info (LOGD_DNS, "Updating /etc/hosts with new system hostname");
|
||||
ip6_config = nm_device_get_ip6_config (dev);
|
||||
if (!ip6_config)
|
||||
continue;
|
||||
|
||||
g_clear_error (&error);
|
||||
/* And actually update /etc/hosts */
|
||||
if (!g_file_set_contents (SYSCONFDIR "/hosts", new_contents->str, -1, &error)) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't update " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error ? error->code : 0,
|
||||
(error && error->message) ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
} else {
|
||||
success = TRUE;
|
||||
*out_changed = TRUE;
|
||||
req = nm_device_get_act_request (dev);
|
||||
g_assert (req);
|
||||
connection = nm_act_request_get_connection (req);
|
||||
g_assert (connection);
|
||||
|
||||
/* Never set the default route through an IPv4LL-addressed device */
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6)
|
||||
method = nm_setting_ip6_config_get_method (s_ip6);
|
||||
|
||||
if (method && !strcmp (method, NM_SETTING_IP6_CONFIG_METHOD_LINK_LOCAL))
|
||||
continue;
|
||||
|
||||
/* Make sure at least one of this device's IP addresses has a gateway */
|
||||
for (i = 0; i < nm_ip6_config_get_num_addresses (ip6_config); i++) {
|
||||
NMIP6Address *addr;
|
||||
|
||||
addr = nm_ip6_config_get_address (ip6_config, i);
|
||||
if (nm_ip6_address_get_gateway (addr)) {
|
||||
can_default = TRUE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_string_free (new_contents, TRUE);
|
||||
} else if (!error) {
|
||||
/* No change required */
|
||||
success = TRUE;
|
||||
} else {
|
||||
nm_log_warn (LOGD_DNS, "couldn't read " SYSCONFDIR "/hosts: (%d) %s",
|
||||
error->code, error->message ? error->message : "(unknown)");
|
||||
g_clear_error (&error);
|
||||
if (!can_default && !NM_IS_DEVICE_MODEM (dev))
|
||||
continue;
|
||||
|
||||
/* 'never-default' devices can't ever be the default */
|
||||
if (s_ip6 && nm_setting_ip6_config_get_never_default (s_ip6))
|
||||
continue;
|
||||
|
||||
prio = nm_device_get_priority (dev);
|
||||
if (prio > 0 && prio < best_prio) {
|
||||
best = dev;
|
||||
best_prio = prio;
|
||||
*out_req = req;
|
||||
}
|
||||
}
|
||||
|
||||
return success;
|
||||
return best;
|
||||
}
|
||||
|
||||
static void
|
||||
set_system_hostname (const char *new_hostname, const char *msg)
|
||||
_set_hostname (const char *new_hostname, const char *msg)
|
||||
{
|
||||
char old_hostname[HOST_NAME_MAX + 1];
|
||||
int ret = 0;
|
||||
const char *name = new_hostname ? new_hostname : FALLBACK_HOSTNAME;
|
||||
gboolean set_hostname = TRUE, changed = FALSE;
|
||||
|
||||
old_hostname[HOST_NAME_MAX] = '\0';
|
||||
errno = 0;
|
||||
ret = gethostname (old_hostname, HOST_NAME_MAX);
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't get the system hostname: (%d) %s",
|
||||
errno, strerror (errno));
|
||||
} else {
|
||||
/* Don't set the hostname if it isn't actually changing */
|
||||
if ( (new_hostname && !strcmp (old_hostname, new_hostname))
|
||||
|| (!new_hostname && !strcmp (old_hostname, FALLBACK_HOSTNAME)))
|
||||
set_hostname = FALSE;
|
||||
}
|
||||
|
||||
if (set_hostname) {
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '%s' (%s)", name, msg);
|
||||
ret = sethostname (name, strlen (name));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the system hostname to '%s': (%d) %s",
|
||||
name, errno, strerror (errno));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
/* But still always try updating /etc/hosts just in case the hostname
|
||||
* changed while NM wasn't running; we need to make sure that /etc/hosts
|
||||
* has valid mappings for '127.0.0.1' and the current system hostname. If
|
||||
* those exist, update_etc_hosts() will just return and won't touch
|
||||
* /etc/hosts at all.
|
||||
*/
|
||||
if (!update_etc_hosts (name, &changed)) {
|
||||
/* error updating /etc/hosts; fallback to localhost.localdomain */
|
||||
nm_log_info (LOGD_DNS, "Setting system hostname to '" FALLBACK_HOSTNAME "' (error updating /etc/hosts)");
|
||||
ret = sethostname (FALLBACK_HOSTNAME, strlen (FALLBACK_HOSTNAME));
|
||||
if (ret != 0) {
|
||||
nm_log_warn (LOGD_DNS, "couldn't set the fallback system hostname (%s): (%d) %s",
|
||||
FALLBACK_HOSTNAME, errno, strerror (errno));
|
||||
}
|
||||
}
|
||||
|
||||
if (changed)
|
||||
if (nm_policy_set_system_hostname (new_hostname, msg))
|
||||
nm_utils_call_dispatcher ("hostname", NULL, NULL, NULL);
|
||||
}
|
||||
|
||||
static void
|
||||
lookup_callback (LookupThread *thread, gpointer user_data)
|
||||
lookup_callback (HostnameThread *thread,
|
||||
int result,
|
||||
const char *hostname,
|
||||
gpointer user_data)
|
||||
{
|
||||
NMPolicy *policy = (NMPolicy *) user_data;
|
||||
char *msg;
|
||||
|
||||
/* If the thread was told to die or it's not the current in-progress
|
||||
* hostname lookup, nothing to do.
|
||||
*/
|
||||
if (thread->die || (thread != policy->lookup))
|
||||
goto done;
|
||||
|
||||
policy->lookup = NULL;
|
||||
if (!strlen (thread->hostname)) {
|
||||
char *msg;
|
||||
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
msg = g_strdup_printf ("address lookup failed: %d", thread->ret);
|
||||
set_system_hostname (NULL, msg);
|
||||
g_free (msg);
|
||||
} else
|
||||
set_system_hostname (thread->hostname, "from address lookup");
|
||||
|
||||
done:
|
||||
lookup_thread_free (thread);
|
||||
/* Update the hostname if the calling lookup thread is the in-progress one */
|
||||
if (!hostname_thread_is_dead (thread) && (thread == policy->lookup)) {
|
||||
policy->lookup = NULL;
|
||||
if (!hostname) {
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
msg = g_strdup_printf ("address lookup failed: %d", result);
|
||||
_set_hostname (NULL, msg);
|
||||
g_free (msg);
|
||||
} else
|
||||
_set_hostname (hostname, "from address lookup");
|
||||
}
|
||||
hostname_thread_free (thread);
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
@ -403,7 +266,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
g_return_if_fail (policy != NULL);
|
||||
|
||||
if (policy->lookup) {
|
||||
lookup_thread_die (policy->lookup);
|
||||
hostname_thread_kill (policy->lookup);
|
||||
policy->lookup = NULL;
|
||||
}
|
||||
|
||||
|
|
@ -419,20 +282,20 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
/* Try a persistent hostname first */
|
||||
g_object_get (G_OBJECT (policy->manager), NM_MANAGER_HOSTNAME, &configured_hostname, NULL);
|
||||
if (configured_hostname) {
|
||||
set_system_hostname (configured_hostname, "from system configuration");
|
||||
_set_hostname (configured_hostname, "from system configuration");
|
||||
g_free (configured_hostname);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Try automatically determined hostname from the best device's IP config */
|
||||
if (!best)
|
||||
best = get_best_device (policy->manager, &best_req);
|
||||
best = get_best_ip4_device (policy->manager, &best_req);
|
||||
|
||||
if (!best) {
|
||||
/* No best device; fall back to original hostname or if there wasn't
|
||||
* one, 'localhost.localdomain'
|
||||
*/
|
||||
set_system_hostname (policy->orig_hostname, "no default device");
|
||||
_set_hostname (policy->orig_hostname, "no default device");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -446,7 +309,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
/* Sanity check */
|
||||
while (*p) {
|
||||
if (!isblank (*p++)) {
|
||||
set_system_hostname (dhcp4_hostname, "from DHCP");
|
||||
_set_hostname (dhcp4_hostname, "from DHCP");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
@ -459,7 +322,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
* when NM started up.
|
||||
*/
|
||||
if (policy->orig_hostname) {
|
||||
set_system_hostname (policy->orig_hostname, "from system startup");
|
||||
_set_hostname (policy->orig_hostname, "from system startup");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -471,7 +334,7 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
|| (nm_ip4_config_get_num_nameservers (ip4_config) == 0)
|
||||
|| (nm_ip4_config_get_num_addresses (ip4_config) == 0)) {
|
||||
/* No valid IP4 config (!!); fall back to localhost.localdomain */
|
||||
set_system_hostname (NULL, "no IPv4 config");
|
||||
_set_hostname (NULL, "no IPv4 config");
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -479,15 +342,15 @@ update_system_hostname (NMPolicy *policy, NMDevice *best)
|
|||
g_assert (addr); /* checked for > 1 address above */
|
||||
|
||||
/* Start the hostname lookup thread */
|
||||
policy->lookup = lookup_thread_new (nm_ip4_address_get_address (addr), lookup_callback, policy);
|
||||
policy->lookup = hostname_thread_new (nm_ip4_address_get_address (addr), lookup_callback, policy);
|
||||
if (!policy->lookup) {
|
||||
/* Fall back to 'localhost.localdomain' */
|
||||
set_system_hostname (NULL, "error starting hostname thread");
|
||||
_set_hostname (NULL, "error starting hostname thread");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
NMNamedIPConfigType dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
NMDevice *best = NULL;
|
||||
|
|
@ -501,10 +364,10 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
|||
NMSettingConnection *s_con = NULL;
|
||||
const char *connection_id;
|
||||
|
||||
best = get_best_device (policy->manager, &best_req);
|
||||
best = get_best_ip4_device (policy->manager, &best_req);
|
||||
if (!best)
|
||||
goto out;
|
||||
if (!force_update && (best == policy->default_device))
|
||||
if (!force_update && (best == policy->default_device4))
|
||||
goto out;
|
||||
|
||||
/* If a VPN connection is active, it is preferred */
|
||||
|
|
@ -598,16 +461,149 @@ update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
|||
|
||||
connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
|
||||
if (connection_id) {
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for routing and DNS.", connection_id, ip_iface);
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv4 routing and DNS.", connection_id, ip_iface);
|
||||
} else {
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for routing and DNS.", ip_iface);
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for IPv4 routing and DNS.", ip_iface);
|
||||
}
|
||||
|
||||
out:
|
||||
/* Update the system hostname */
|
||||
update_system_hostname (policy, best);
|
||||
policy->default_device4 = best;
|
||||
}
|
||||
|
||||
policy->default_device = best;
|
||||
static void
|
||||
update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
NMNamedIPConfigType dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
NMDevice *best = NULL;
|
||||
NMActRequest *best_req = NULL;
|
||||
NMNamedManager *named_mgr;
|
||||
GSList *devices = NULL, *iter;
|
||||
#if NOT_YET
|
||||
GSList *vpns;
|
||||
#endif
|
||||
NMIP6Config *ip6_config = NULL;
|
||||
NMIP6Address *addr;
|
||||
const char *ip_iface = NULL;
|
||||
NMConnection *connection = NULL;
|
||||
NMSettingConnection *s_con = NULL;
|
||||
const char *connection_id;
|
||||
|
||||
best = get_best_ip6_device (policy->manager, &best_req);
|
||||
if (!best)
|
||||
goto out;
|
||||
if (!force_update && (best == policy->default_device6))
|
||||
goto out;
|
||||
|
||||
#if NOT_YET
|
||||
/* If a VPN connection is active, it is preferred */
|
||||
vpns = nm_vpn_manager_get_active_connections (policy->vpn_manager);
|
||||
for (iter = vpns; iter; iter = g_slist_next (iter)) {
|
||||
NMVPNConnection *candidate = NM_VPN_CONNECTION (iter->data);
|
||||
NMConnection *vpn_connection;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
gboolean can_default = TRUE;
|
||||
NMVPNConnectionState vpn_state;
|
||||
|
||||
/* If it's marked 'never-default', don't make it default */
|
||||
vpn_connection = nm_vpn_connection_get_connection (candidate);
|
||||
g_assert (vpn_connection);
|
||||
s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (vpn_connection, NM_TYPE_SETTING_IP6_CONFIG);
|
||||
if (s_ip6 && nm_setting_ip6_config_get_never_default (s_ip6))
|
||||
can_default = FALSE;
|
||||
|
||||
vpn_state = nm_vpn_connection_get_vpn_state (candidate);
|
||||
if (can_default && (vpn_state == NM_VPN_CONNECTION_STATE_ACTIVATED)) {
|
||||
NMIP6Config *parent_ip6;
|
||||
NMDevice *parent;
|
||||
|
||||
ip_iface = nm_vpn_connection_get_ip_iface (candidate);
|
||||
connection = nm_vpn_connection_get_connection (candidate);
|
||||
ip6_config = nm_vpn_connection_get_ip6_config (candidate);
|
||||
addr = nm_ip6_config_get_address (ip6_config, 0);
|
||||
|
||||
parent = nm_vpn_connection_get_parent_device (candidate);
|
||||
parent_ip6 = nm_device_get_ip6_config (parent);
|
||||
|
||||
nm_system_replace_default_ip6_route_vpn (ip_iface,
|
||||
nm_ip6_address_get_gateway (addr),
|
||||
nm_vpn_connection_get_ip4_internal_gateway (candidate),
|
||||
nm_ip6_config_get_mss (ip4_config),
|
||||
nm_device_get_ip_iface (parent),
|
||||
nm_ip6_config_get_mss (parent_ip4));
|
||||
|
||||
dns_type = NM_NAMED_IP_CONFIG_TYPE_VPN;
|
||||
}
|
||||
g_object_unref (candidate);
|
||||
}
|
||||
g_slist_free (vpns);
|
||||
#endif
|
||||
|
||||
/* The best device gets the default route if a VPN connection didn't */
|
||||
if (!ip_iface || !ip6_config) {
|
||||
connection = nm_act_request_get_connection (best_req);
|
||||
ip_iface = nm_device_get_ip_iface (best);
|
||||
ip6_config = nm_device_get_ip6_config (best);
|
||||
g_assert (ip6_config);
|
||||
addr = nm_ip6_config_get_address (ip6_config, 0);
|
||||
|
||||
nm_system_replace_default_ip6_route (ip_iface, nm_ip6_address_get_gateway (addr));
|
||||
|
||||
dns_type = NM_NAMED_IP_CONFIG_TYPE_BEST_DEVICE;
|
||||
}
|
||||
|
||||
if (!ip_iface || !ip6_config) {
|
||||
nm_log_warn (LOGD_CORE, "couldn't determine IP interface (%p) or IPv6 config (%p)!",
|
||||
ip_iface, ip6_config);
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Update the default active connection. Only mark the new default
|
||||
* active connection after setting default = FALSE on all other connections
|
||||
* first. The order is important, we don't want two connections marked
|
||||
* default at the same time ever.
|
||||
*/
|
||||
devices = nm_manager_get_devices (policy->manager);
|
||||
for (iter = devices; iter; iter = g_slist_next (iter)) {
|
||||
NMDevice *dev = NM_DEVICE (iter->data);
|
||||
NMActRequest *req;
|
||||
|
||||
req = nm_device_get_act_request (dev);
|
||||
if (req && (req != best_req))
|
||||
nm_act_request_set_default6 (req, FALSE);
|
||||
}
|
||||
|
||||
named_mgr = nm_named_manager_get ();
|
||||
nm_named_manager_add_ip6_config (named_mgr, ip_iface, ip6_config, dns_type);
|
||||
g_object_unref (named_mgr);
|
||||
|
||||
/* Now set new default active connection _after_ updating DNS info, so that
|
||||
* if the connection is shared dnsmasq picks up the right stuff.
|
||||
*/
|
||||
if (best_req)
|
||||
nm_act_request_set_default6 (best_req, TRUE);
|
||||
|
||||
if (connection)
|
||||
s_con = (NMSettingConnection *) nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION);
|
||||
|
||||
connection_id = s_con ? nm_setting_connection_get_id (s_con) : NULL;
|
||||
if (connection_id) {
|
||||
nm_log_info (LOGD_CORE, "Policy set '%s' (%s) as default for IPv6 routing and DNS.", connection_id, ip_iface);
|
||||
} else {
|
||||
nm_log_info (LOGD_CORE, "Policy set (%s) as default for IPv6 routing and DNS.", ip_iface);
|
||||
}
|
||||
|
||||
out:
|
||||
policy->default_device6 = best;
|
||||
}
|
||||
|
||||
static void
|
||||
update_routing_and_dns (NMPolicy *policy, gboolean force_update)
|
||||
{
|
||||
update_ip4_routing_and_dns (policy, force_update);
|
||||
update_ip6_routing_and_dns (policy, force_update);
|
||||
|
||||
/* Update the system hostname */
|
||||
update_system_hostname (policy, policy->default_device4);
|
||||
}
|
||||
|
||||
typedef struct {
|
||||
|
|
@ -796,10 +792,23 @@ device_state_changed (NMDevice *device,
|
|||
/* Mark the connection invalid if it failed during activation so that
|
||||
* it doesn't get automatically chosen over and over and over again.
|
||||
*/
|
||||
if (connection && IS_ACTIVATING_STATE (old_state)) {
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
|
||||
nm_connection_clear_secrets (connection);
|
||||
if (connection) {
|
||||
gboolean fail = FALSE;
|
||||
|
||||
if (IS_ACTIVATING_STATE (old_state)) {
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid.", get_connection_id (connection));
|
||||
fail = TRUE;
|
||||
} else if ( (old_state == NM_DEVICE_STATE_ACTIVATED)
|
||||
&& (reason == NM_DEVICE_STATE_REASON_IP_CONFIG_EXPIRED)) {
|
||||
nm_log_info (LOGD_DEVICE, "Marking connection '%s' invalid because IP configuration expired.",
|
||||
get_connection_id (connection));
|
||||
fail = TRUE;
|
||||
}
|
||||
|
||||
if (fail) {
|
||||
g_object_set_data (G_OBJECT (connection), INVALID_TAG, GUINT_TO_POINTER (TRUE));
|
||||
nm_connection_clear_secrets (connection);
|
||||
}
|
||||
}
|
||||
schedule_activate_check (policy, device, 3);
|
||||
break;
|
||||
|
|
@ -828,9 +837,9 @@ device_state_changed (NMDevice *device,
|
|||
}
|
||||
|
||||
static void
|
||||
device_ip4_config_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
device_ip_config_changed (NMDevice *device,
|
||||
GParamSpec *pspec,
|
||||
gpointer user_data)
|
||||
{
|
||||
update_routing_and_dns ((NMPolicy *) user_data, TRUE);
|
||||
}
|
||||
|
|
@ -872,7 +881,12 @@ device_added (NMManager *manager, NMDevice *device, gpointer user_data)
|
|||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP4_CONFIG,
|
||||
G_CALLBACK (device_ip4_config_changed),
|
||||
G_CALLBACK (device_ip_config_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
id = g_signal_connect (device, "notify::" NM_DEVICE_INTERFACE_IP6_CONFIG,
|
||||
G_CALLBACK (device_ip_config_changed),
|
||||
policy);
|
||||
policy->dev_signal_ids = add_device_signal_id (policy->dev_signal_ids, id, device);
|
||||
|
||||
|
|
@ -1083,7 +1097,7 @@ nm_policy_destroy (NMPolicy *policy)
|
|||
* by the lookup thread callback.
|
||||
*/
|
||||
if (policy->lookup) {
|
||||
lookup_thread_die (policy->lookup);
|
||||
hostname_thread_kill (policy->lookup);
|
||||
policy->lookup = NULL;
|
||||
}
|
||||
|
||||
|
|
|
|||
155
src/nm-system.c
155
src/nm-system.c
|
|
@ -48,7 +48,7 @@
|
|||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-utils.h"
|
||||
#include "nm-logging.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
|
||||
/* Because of a bug in libnl, rtnl.h should be included before route.h */
|
||||
#include <netlink/route/rtnl.h>
|
||||
|
|
@ -460,7 +460,7 @@ nm_system_device_set_ip6_route (const char *iface,
|
|||
g_return_val_if_fail (route != NULL, NULL);
|
||||
|
||||
/* Destination */
|
||||
dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *)ip6_dest, sizeof (*ip6_dest));
|
||||
dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_dest, sizeof (*ip6_dest));
|
||||
g_return_val_if_fail (dest_addr != NULL, NULL);
|
||||
nl_addr_set_prefixlen (dest_addr, (int) ip6_prefix);
|
||||
|
||||
|
|
@ -469,7 +469,7 @@ nm_system_device_set_ip6_route (const char *iface,
|
|||
|
||||
/* Gateway */
|
||||
if (ip6_gateway && !IN6_IS_ADDR_UNSPECIFIED (ip6_gateway)) {
|
||||
gw_addr = nl_addr_build (AF_INET6, (struct in6_addr *)ip6_gateway, sizeof (*ip6_gateway));
|
||||
gw_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_gateway, sizeof (*ip6_gateway));
|
||||
if (gw_addr) {
|
||||
rtnl_route_set_gateway (route, gw_addr);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||
|
|
@ -940,6 +940,153 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss)
|
|||
return success;
|
||||
}
|
||||
|
||||
static struct rtnl_route *
|
||||
add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct nl_handle *nlh;
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_addr *gw_addr = NULL;
|
||||
int iface_idx, err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, NULL);
|
||||
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx < 0)
|
||||
return NULL;
|
||||
|
||||
/* Gateway might be over a bridge; try adding a route to gateway first */
|
||||
route = rtnl_route_alloc ();
|
||||
if (route == NULL)
|
||||
return NULL;
|
||||
|
||||
rtnl_route_set_family (route, AF_INET6);
|
||||
rtnl_route_set_table (route, RT_TABLE_MAIN);
|
||||
rtnl_route_set_oif (route, iface_idx);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_LINK);
|
||||
|
||||
gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw));
|
||||
if (!gw_addr)
|
||||
goto error;
|
||||
nl_addr_set_prefixlen (gw_addr, 128);
|
||||
rtnl_route_set_dst (route, gw_addr);
|
||||
nl_addr_put (gw_addr);
|
||||
|
||||
/* Add direct route to the gateway */
|
||||
err = rtnl_route_add (nlh, route, 0);
|
||||
if (err) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to add IPv4 route to gateway (%d)",
|
||||
iface, err);
|
||||
goto error;
|
||||
}
|
||||
|
||||
return route;
|
||||
|
||||
error:
|
||||
rtnl_route_put (route);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int
|
||||
replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct rtnl_route *route = NULL;
|
||||
struct nl_handle *nlh;
|
||||
struct nl_addr *gw_addr = NULL;
|
||||
int iface_idx, err = -1;
|
||||
|
||||
g_return_val_if_fail (iface != NULL, -ENODEV);
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, -ENOMEM);
|
||||
|
||||
iface_idx = nm_netlink_iface_to_index (iface);
|
||||
if (iface_idx < 0)
|
||||
return -ENODEV;
|
||||
|
||||
route = rtnl_route_alloc();
|
||||
g_return_val_if_fail (route != NULL, -ENOMEM);
|
||||
|
||||
rtnl_route_set_family (route, AF_INET6);
|
||||
rtnl_route_set_table (route, RT_TABLE_MAIN);
|
||||
rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE);
|
||||
rtnl_route_set_oif (route, iface_idx);
|
||||
|
||||
if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) {
|
||||
/* Build up the gateway address */
|
||||
gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw));
|
||||
if (!gw_addr) {
|
||||
err = -ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
nl_addr_set_prefixlen (gw_addr, -1);
|
||||
rtnl_route_set_gateway (route, gw_addr);
|
||||
}
|
||||
|
||||
/* Add the new default route */
|
||||
err = rtnl_route_add (nlh, route, NLM_F_REPLACE);
|
||||
if (err == -EEXIST) {
|
||||
/* FIXME: even though we use NLM_F_REPLACE the kernel won't replace
|
||||
* the route if it's the same. Should try to remove it first, then
|
||||
* add the new one again here.
|
||||
*/
|
||||
err = 0;
|
||||
}
|
||||
|
||||
out:
|
||||
if (gw_addr)
|
||||
nl_addr_put (gw_addr);
|
||||
rtnl_route_put (route);
|
||||
return err;
|
||||
}
|
||||
|
||||
/*
|
||||
* nm_system_replace_default_ip6_route
|
||||
*
|
||||
* Replace default IPv6 route with one via the given gateway
|
||||
*
|
||||
*/
|
||||
gboolean
|
||||
nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *gw)
|
||||
{
|
||||
struct rtnl_route *gw_route = NULL;
|
||||
struct nl_handle *nlh;
|
||||
gboolean success = FALSE;
|
||||
int err;
|
||||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
g_return_val_if_fail (nlh != NULL, FALSE);
|
||||
|
||||
err = replace_default_ip6_route (iface, gw);
|
||||
if (err == 0) {
|
||||
return TRUE;
|
||||
} else if (err != -ESRCH) {
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route: %d",
|
||||
iface, err);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
/* Try adding a direct route to the gateway first */
|
||||
gw_route = add_ip6_route_to_gateway (iface, gw);
|
||||
if (!gw_route)
|
||||
return FALSE;
|
||||
|
||||
/* Try adding the original route again */
|
||||
err = replace_default_ip6_route (iface, gw);
|
||||
if (err != 0) {
|
||||
rtnl_route_del (nlh, gw_route, 0);
|
||||
nm_log_err (LOGD_DEVICE | LOGD_IP6,
|
||||
"(%s): failed to set IPv6 default route (pass #2): %d",
|
||||
iface, err);
|
||||
} else
|
||||
success = TRUE;
|
||||
|
||||
rtnl_route_put (gw_route);
|
||||
return success;
|
||||
}
|
||||
|
||||
static void flush_addresses (const char *iface, gboolean ipv4_only)
|
||||
{
|
||||
int iface_idx;
|
||||
|
|
@ -986,7 +1133,7 @@ foreach_route (void (*callback)(struct nl_object *, gpointer),
|
|||
|
||||
nlh = nm_netlink_get_default_handle ();
|
||||
route_cache = rtnl_route_alloc_cache (nlh);
|
||||
nl_cache_mngt_provide (route_cache);
|
||||
g_assert (route_cache);
|
||||
nl_cache_foreach (route_cache, callback, user_data);
|
||||
nl_cache_free (route_cache);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,6 +40,9 @@ gboolean nm_system_replace_default_ip4_route (const char *iface,
|
|||
guint32 gw,
|
||||
guint32 mss);
|
||||
|
||||
gboolean nm_system_replace_default_ip6_route (const char *iface,
|
||||
const struct in6_addr *gw);
|
||||
|
||||
gboolean nm_system_replace_default_ip4_route_vpn (const char *iface,
|
||||
guint32 ext_gw,
|
||||
guint32 int_gw,
|
||||
|
|
|
|||
|
|
@ -384,11 +384,11 @@ device_creator (NMUdevManager *manager,
|
|||
}
|
||||
|
||||
if (is_olpc_mesh (udev_device)) /* must be before is_wireless */
|
||||
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_olpc_mesh_new (path, ifname, driver);
|
||||
else if (is_wireless (udev_device))
|
||||
device = (GObject *) nm_device_wifi_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_wifi_new (path, ifname, driver);
|
||||
else
|
||||
device = (GObject *) nm_device_ethernet_new (path, ifname, driver, ifindex);
|
||||
device = (GObject *) nm_device_ethernet_new (path, ifname, driver);
|
||||
|
||||
out:
|
||||
if (grandparent)
|
||||
|
|
|
|||
|
|
@ -35,6 +35,7 @@ test_policy_hosts_CPPFLAGS = \
|
|||
$(GLIB_CFLAGS)
|
||||
|
||||
test_policy_hosts_LDADD = \
|
||||
-ldl \
|
||||
$(top_builddir)/src/libtest-policy-hosts.la \
|
||||
$(GLIB_LIBS)
|
||||
|
||||
|
|
|
|||
|
|
@ -45,7 +45,7 @@
|
|||
#include "nm-dbus-glib-types.h"
|
||||
#include "NetworkManagerUtils.h"
|
||||
#include "nm-named-manager.h"
|
||||
#include "nm-netlink.h"
|
||||
#include "nm-netlink-monitor.h"
|
||||
#include "nm-glib-compat.h"
|
||||
|
||||
#include "nm-vpn-connection-glue.h"
|
||||
|
|
@ -69,6 +69,7 @@ typedef struct {
|
|||
gulong device_ip4;
|
||||
|
||||
gboolean is_default;
|
||||
gboolean is_default6;
|
||||
NMActiveConnectionState state;
|
||||
|
||||
NMVPNConnectionState vpn_state;
|
||||
|
|
@ -102,6 +103,7 @@ enum {
|
|||
PROP_DEVICES,
|
||||
PROP_STATE,
|
||||
PROP_DEFAULT,
|
||||
PROP_DEFAULT6,
|
||||
PROP_VPN,
|
||||
PROP_VPN_STATE,
|
||||
PROP_BANNER,
|
||||
|
|
@ -1052,6 +1054,9 @@ get_property (GObject *object, guint prop_id,
|
|||
case PROP_DEFAULT:
|
||||
g_value_set_boolean (value, priv->is_default);
|
||||
break;
|
||||
case PROP_DEFAULT6:
|
||||
g_value_set_boolean (value, priv->is_default6);
|
||||
break;
|
||||
case PROP_VPN:
|
||||
g_value_set_boolean (value, TRUE);
|
||||
break;
|
||||
|
|
@ -1122,7 +1127,14 @@ nm_vpn_connection_class_init (NMVPNConnectionClass *connection_class)
|
|||
(object_class, PROP_DEFAULT,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT,
|
||||
"Default",
|
||||
"Is the default active connection",
|
||||
"Is the default IPv4 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
(object_class, PROP_DEFAULT6,
|
||||
g_param_spec_boolean (NM_ACTIVE_CONNECTION_DEFAULT6,
|
||||
"Default6",
|
||||
"Is the default IPv6 active connection",
|
||||
FALSE,
|
||||
G_PARAM_READABLE));
|
||||
g_object_class_install_property
|
||||
|
|
|
|||
|
|
@ -1215,7 +1215,10 @@ make_ip4_setting (shvarFile *ifcfg,
|
|||
if (!tmp_ip4 && !tmp_prefix && !tmp_netmask) {
|
||||
if (valid_ip6_config) {
|
||||
/* Nope, no IPv4 */
|
||||
goto done;
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||
NULL);
|
||||
return NM_SETTING (s_ip4);
|
||||
}
|
||||
|
||||
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
||||
|
|
|
|||
|
|
@ -2165,6 +2165,7 @@ test_read_wired_ipv6_only (void)
|
|||
const char *expected_dns1 = "1:2:3:4::a";
|
||||
NMIP6Address *ip6_addr;
|
||||
struct in6_addr addr;
|
||||
const char *method;
|
||||
|
||||
connection = connection_from_file (TEST_IFCFG_WIRED_IPV6_ONLY,
|
||||
NULL,
|
||||
|
|
@ -2217,11 +2218,18 @@ test_read_wired_ipv6_only (void)
|
|||
/* ===== IPv4 SETTING ===== */
|
||||
|
||||
s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG));
|
||||
ASSERT (s_ip4 == NULL,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s setting",
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: missing %s setting",
|
||||
TEST_IFCFG_WIRED_IPV6_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
ASSERT (strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED) == 0,
|
||||
"wired-ipv6-only-verify-ip4", "failed to verify %s: unexpected %s / %s key value",
|
||||
TEST_IFCFG_WIRED_IPV6_MANUAL,
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME,
|
||||
NM_SETTING_IP4_CONFIG_METHOD);
|
||||
|
||||
/* ===== IPv6 SETTING ===== */
|
||||
|
||||
s_ip6 = NM_SETTING_IP6_CONFIG (nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG));
|
||||
|
|
@ -5408,6 +5416,7 @@ test_write_wired_static_ip6_only (void)
|
|||
NMConnection *reread;
|
||||
NMSettingConnection *s_con;
|
||||
NMSettingWired *s_wired;
|
||||
NMSettingIP4Config *s_ip4;
|
||||
NMSettingIP6Config *s_ip6;
|
||||
static unsigned char tmpmac[] = { 0x31, 0x33, 0x33, 0x37, 0xbe, 0xcd };
|
||||
GByteArray *mac;
|
||||
|
|
@ -5461,6 +5470,17 @@ test_write_wired_static_ip6_only (void)
|
|||
g_object_set (s_wired, NM_SETTING_WIRED_MAC_ADDRESS, mac, NULL);
|
||||
g_byte_array_free (mac, TRUE);
|
||||
|
||||
/* IP4 setting */
|
||||
s_ip4 = (NMSettingIP4Config *) nm_setting_ip4_config_new ();
|
||||
ASSERT (s_ip4 != NULL,
|
||||
"wired-static-ip6-only-write", "failed to allocate new %s setting",
|
||||
NM_SETTING_IP4_CONFIG_SETTING_NAME);
|
||||
nm_connection_add_setting (connection, NM_SETTING (s_ip4));
|
||||
|
||||
g_object_set (s_ip4,
|
||||
NM_SETTING_IP4_CONFIG_METHOD, NM_SETTING_IP4_CONFIG_METHOD_DISABLED,
|
||||
NULL);
|
||||
|
||||
/* IP6 setting */
|
||||
s_ip6 = (NMSettingIP6Config *) nm_setting_ip6_config_new ();
|
||||
ASSERT (s_ip6 != NULL,
|
||||
|
|
@ -5517,9 +5537,6 @@ test_write_wired_static_ip6_only (void)
|
|||
ASSERT (nm_connection_verify (reread, &error),
|
||||
"wired-static-ip6-only-write-reread-verify", "failed to verify %s: %s", testfile, error->message);
|
||||
|
||||
ASSERT (nm_connection_get_setting (reread, NM_TYPE_SETTING_IP4_CONFIG) == NULL,
|
||||
"wired-static-ip6-only-write-reread-verify", "unexpected IPv4 setting");
|
||||
|
||||
ASSERT (nm_connection_compare (connection, reread, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE,
|
||||
"wired-static-ip6-only-write", "written and re-read connection weren't the same.");
|
||||
|
||||
|
|
|
|||
|
|
@ -934,9 +934,17 @@ write_ip4_setting (NMConnection *connection, shvarFile *ifcfg, GError **error)
|
|||
guint32 i, num;
|
||||
GString *searches;
|
||||
gboolean success = FALSE;
|
||||
const char *method = NULL;
|
||||
|
||||
s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG);
|
||||
if (!s_ip4) {
|
||||
if (s_ip4)
|
||||
method = nm_setting_ip4_config_get_method (s_ip4);
|
||||
|
||||
/* Missing IP4 setting is assumed to be DHCP */
|
||||
if (!method)
|
||||
method = NM_SETTING_IP4_CONFIG_METHOD_AUTO;
|
||||
|
||||
if (!strcmp (method, NM_SETTING_IP4_CONFIG_METHOD_DISABLED)) {
|
||||
int result;
|
||||
|
||||
/* IPv4 disabled, clear IPv4 related parameters */
|
||||
|
|
|
|||
|
|
@ -298,9 +298,9 @@ ip6_addr_writer (GKeyFile *file,
|
|||
GValueArray *values = g_ptr_array_index (array, i);
|
||||
char *key_name, *ip6_addr;
|
||||
|
||||
if (values->n_values % 2) {
|
||||
nm_warning ("%s: error writing IP6 address %d; address array length"
|
||||
" %d is not a multiple of 2.",
|
||||
if (values->n_values != 3) {
|
||||
nm_warning ("%s: error writing IP6 address %d (address array length "
|
||||
"%d is not 3)",
|
||||
__func__, i, values->n_values);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue