2007-08-26 Dan Williams <dcbw@redhat.com>

Convert to using interface indexes as the primary method of identifying
	devices inside NetworkManager.  Indexes are (?) stable, but devices can
	be renamed at any time.  Device object paths now refer to the device
	index rather than the name, and you can map those two manually if you like
	by looking in the /sys/class/net/<name>/ifindex file.  Also moves most
	netlink-related code to nm-netlink.c, and cleans up nm-netlink-monitor.c
	to use interface indexes rather than names.



git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@2731 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
Dan Williams
2007-08-26 15:55:27 +00:00
parent c7b06312e7
commit cd00315325
23 changed files with 351 additions and 263 deletions

View File

@@ -1,3 +1,13 @@
2007-08-26 Dan Williams <dcbw@redhat.com>
Convert to using interface indexes as the primary method of identifying
devices inside NetworkManager. Indexes are (?) stable, but devices can
be renamed at any time. Device object paths now refer to the device
index rather than the name, and you can map those two manually if you like
by looking in the /sys/class/net/<name>/ifindex file. Also moves most
netlink-related code to nm-netlink.c, and cleans up nm-netlink-monitor.c
to use interface indexes rather than names.
2007-08-26 Dan Williams <dcbw@redhat.com>
* src/nm-netlink-monitor.h

View File

@@ -72,7 +72,9 @@ NetworkManager_SOURCES = \
nm-marshal-main.c \
kernel-types.h \
wpa.c \
wpa.h
wpa.h \
nm-netlink.c \
nm-netlink.h
nm-marshal.h: Makefile.am nm-marshal.list
$(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --header > \

View File

@@ -81,27 +81,6 @@ nm_dbus_new_invalid_args_error (DBusMessage *replyto,
"Invalid method arguments.");
}
/*
* nm_dbus_get_object_path_for_device
*
* Copies the object path for a device object. Caller must free returned string.
*
*/
char * nm_dbus_get_object_path_for_device (NMDevice *dev)
{
char *object_path, *escaped_object_path;
g_return_val_if_fail (dev != NULL, NULL);
object_path = g_strdup_printf ("%s/%s", NM_DBUS_PATH_DEVICE, nm_device_get_iface (dev));
escaped_object_path = nm_dbus_escape_object_path (object_path);
g_free (object_path);
return escaped_object_path;
}
/*-------------------------------------------------------------*/
/* Handler code */
/*-------------------------------------------------------------*/

View File

@@ -39,8 +39,6 @@ static inline gboolean message_is_error (DBusMessage *msg)
return (dbus_message_get_type (msg) == DBUS_MESSAGE_TYPE_ERROR);
}
char * nm_dbus_get_object_path_for_device (NMDevice *dev);
DBusMessage * nm_dbus_create_error_message (DBusMessage *message, const char *exception_namespace, const char *exception, const char *format, ...);
DBusMessage * nm_dbus_new_invalid_args_error (DBusMessage *replyto, const char *namespace);

View File

@@ -45,6 +45,7 @@
#include "nm-device.h"
#include "NetworkManagerUtils.h"
#include "nm-utils.h"
#include "nm-netlink.h"
#include <netlink/route/addr.h>
#include <netlink/netlink.h>
@@ -179,117 +180,6 @@ out:
}
static struct nl_cache * get_link_cache (struct nl_handle *nlh)
{
static struct nl_cache * link_cache = NULL;
if (!link_cache)
link_cache = rtnl_link_alloc_cache (nlh);
if (!link_cache)
nm_warning ("couldn't allocate rtnl link cache!");
else
nl_cache_update (nlh, link_cache);
return link_cache;
}
static void iface_to_rtnl_index (const char *iface, struct nl_handle *nlh, struct rtnl_addr *addr)
{
struct nl_cache * cache = NULL;
int i;
g_return_if_fail (iface != NULL);
g_return_if_fail (nlh != NULL);
g_return_if_fail (addr != NULL);
if ((cache = get_link_cache (nlh)))
{
i = rtnl_link_name2i (cache, iface);
if (RTNL_LINK_NOT_FOUND != i)
rtnl_addr_set_ifindex (addr, i);
}
else
nm_warning ("couldn't allocate link cache.");
}
static struct rtnl_link * iface_to_rtnl_link (const char *iface, struct nl_handle *nlh)
{
struct nl_cache * cache = NULL;
struct rtnl_link * have_link = NULL;
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (nlh != NULL, NULL);
if ((cache = get_link_cache (nlh)))
have_link = rtnl_link_get_by_name (cache, iface);
else
nm_warning ("couldn't allocate link cache.");
return have_link;
}
static struct nl_handle * new_nl_handle (void)
{
struct nl_handle * nlh = NULL;
nlh = nl_handle_alloc_nondefault(NL_CB_VERBOSE);
nl_handle_set_pid (nlh, (pthread_self() << 16 | getpid()));
if (nl_connect(nlh, NETLINK_ROUTE) < 0)
{
nm_warning("couldn't connect to netlink: %s\n", nl_geterror());
nl_handle_destroy (nlh);
nlh = NULL;
}
return nlh;
}
int
nm_system_get_rtnl_index_from_iface (const char *iface)
{
struct nl_handle * nlh = NULL;
struct nl_cache * cache = NULL;
int i = RTNL_LINK_NOT_FOUND;
nlh = new_nl_handle ();
if (nlh && (cache = get_link_cache (nlh)))
i = rtnl_link_name2i (cache, iface);
nl_close (nlh);
nl_handle_destroy (nlh);
return i;
}
#define MAX_IFACE_LEN 32
char *
nm_system_get_iface_from_rtnl_index (int rtnl_index)
{
struct nl_handle * nlh = NULL;
struct nl_cache * cache = NULL;
char * buf = NULL;
nlh = new_nl_handle ();
if (nlh && (cache = get_link_cache (nlh)))
{
buf = g_malloc0 (MAX_IFACE_LEN);
if (!rtnl_link_i2name (cache, rtnl_index, buf, MAX_IFACE_LEN - 1))
{
g_free (buf);
buf = NULL;
}
}
nl_close (nlh);
nl_handle_destroy (nlh);
return buf;
}
/*
* nm_system_device_set_from_ip4_config
*
@@ -317,11 +207,11 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev)
nm_system_device_flush_routes (dev);
nm_system_flush_arp_cache ();
nlh = new_nl_handle ();
nlh = nm_netlink_get_default_handle ();
if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_DEFAULT)))
{
iface_to_rtnl_index (nm_device_get_iface (dev), nlh, addr);
rtnl_addr_set_ifindex (addr, nm_device_get_index (dev));
if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", nm_device_get_iface (dev), err, nl_geterror());
rtnl_addr_put (addr);
@@ -329,9 +219,6 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev)
else
nm_warning ("couldn't create rtnl address!\n");
nl_close (nlh);
nl_handle_destroy (nlh);
sleep (1);
nm_system_device_set_ip4_route (dev, nm_ip4_config_get_gateway (config), 0, 0, nm_ip4_config_get_mss (config));
@@ -452,12 +339,12 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
{
nm_system_device_set_up_down_with_iface (iface, TRUE);
nlh = new_nl_handle ();
nlh = nm_netlink_get_default_handle ();
if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_PTP_DEFAULT)))
{
int err = 0;
iface_to_rtnl_index (iface, nlh, addr);
rtnl_addr_set_ifindex (addr, nm_device_get_index (active_device));
if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
rtnl_addr_put (addr);
@@ -471,7 +358,7 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
struct rtnl_link * old;
guint32 mtu;
old = iface_to_rtnl_link (iface, nlh);
old = nm_netlink_index_to_rtnl_link (nm_device_get_index (active_device));
mtu = nm_ip4_config_get_mtu (config);
if (mtu == 0)
mtu = 1412; /* Default to 1412 (vpnc) */
@@ -482,9 +369,6 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
rtnl_link_put (request);
}
nl_close (nlh);
nl_handle_destroy (nlh);
sleep (1);
nm_system_device_flush_routes_with_iface (iface);
@@ -557,15 +441,12 @@ gboolean nm_system_device_set_up_down (NMDevice *dev, gboolean up)
gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up)
{
gboolean success = FALSE;
struct nl_handle * nlh = NULL;
guint32 index;
struct rtnl_link * request = NULL;
struct rtnl_link * old = NULL;
g_return_val_if_fail (iface != NULL, FALSE);
if (!(nlh = new_nl_handle ()))
return FALSE;
if (!(request = rtnl_link_alloc ()))
goto out;
@@ -574,19 +455,18 @@ gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up
else
rtnl_link_unset_flags (request, IFF_UP);
old = iface_to_rtnl_link (iface, nlh);
if (old)
index = nm_netlink_iface_to_index (iface);
old = nm_netlink_index_to_rtnl_link (index);
if (old) {
struct nl_handle * nlh = nm_netlink_get_default_handle ();
rtnl_link_change (nlh, old, request, 0);
}
rtnl_link_put (old);
rtnl_link_put (request);
success = TRUE;
out:
nl_close (nlh);
nl_handle_destroy (nlh);
return success;
}
@@ -608,27 +488,22 @@ void nm_system_set_mtu (NMDevice *dev)
if (!mtu)
return;
nlh = new_nl_handle ();
if (!nlh)
return;
request = rtnl_link_alloc ();
if (!request)
goto out_nl_close;
return;
iface = nm_device_get_iface (dev);
old = iface_to_rtnl_link (iface, nlh);
old = nm_netlink_index_to_rtnl_link (nm_device_get_index (dev));
if (!old)
goto out_request;
nm_info ("Setting MTU of interface '%s' to %ld", iface, mtu);
nm_info ("Setting MTU of interface '%s' to %ld",
nm_device_get_iface (dev),
mtu);
rtnl_link_set_mtu (request, mtu);
nlh = nm_netlink_get_default_handle ();
rtnl_link_change (nlh, old, request, 0);
rtnl_link_put (old);
out_request:
rtnl_link_put (request);
out_nl_close:
nl_close (nlh);
nl_handle_destroy (nlh);
}

View File

@@ -36,9 +36,6 @@ struct NMData;
void nm_system_init (void);
gboolean nm_system_device_has_active_routes (NMDevice *dev);
int nm_system_get_rtnl_index_from_iface (const char *iface);
char * nm_system_get_iface_from_rtnl_index (int rtnl_index);
void nm_system_device_flush_routes (NMDevice *dev);
void nm_system_device_flush_routes_with_iface (const char *iface);

View File

@@ -154,7 +154,7 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
UserKeyInfo *info;
NMAccessPoint * ap;
gint32 attempt = 1;
char * dev_path;
const char * dev_path;
const char * net_path;
const GByteArray * ssid;
@@ -185,7 +185,7 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
goto out;
}
dev_path = nm_dbus_get_object_path_for_device (dev);
dev_path = nm_device_get_dbus_path (dev);
net_path = nm_ap_get_dbus_path (ap);
if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) {
char buf[IW_ESSID_MAX_SIZE + 1];
@@ -215,7 +215,6 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
} else {
nm_warning ("bad object path data");
}
g_free (dev_path);
/* FIXME: figure out how to deal with a failure here, otherwise
* we just hang in the activation process and nothing happens

View File

@@ -313,18 +313,18 @@ real_get_generic_capabilities (NMDevice *dev)
if (iw_get_range_info (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), &range) < 0)
goto out;
if (range.we_version_compiled < 16)
{
nm_warning ("%s: driver's Wireless Extensions version (%d) is too old. Can't use device.",
if (range.we_version_compiled < 16) {
nm_warning ("%s: driver's Wireless Extensions version (%d) is too old.",
iface, range.we_version_compiled);
}
else
goto out;
} else {
caps |= NM_DEVICE_CAP_NM_SUPPORTED;
}
/* Card's that don't scan aren't supported */
memset (&wrq, 0, sizeof (struct iwreq));
err = iw_set_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), SIOCSIWSCAN, &wrq);
if (!((err == -1) && (errno == EOPNOTSUPP)))
if ((err == -1) && (errno == EOPNOTSUPP))
caps = NM_DEVICE_CAP_NONE;
out:
@@ -3174,7 +3174,7 @@ nm_info ("%s(): clearing activation AP", __func__);
NMDevice80211Wireless *
nm_device_802_11_wireless_new (const char *iface,
nm_device_802_11_wireless_new (int index,
const char *udi,
const char *driver,
gboolean test_dev,
@@ -3182,17 +3182,19 @@ nm_device_802_11_wireless_new (const char *iface,
{
GObject *obj;
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (index >= 0, NULL);
g_return_val_if_fail (udi != NULL, NULL);
g_return_val_if_fail (driver != NULL, NULL);
g_return_val_if_fail (app_data != NULL, NULL);
obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS,
NM_DEVICE_INTERFACE_UDI, udi,
NM_DEVICE_INTERFACE_IFACE, iface,
NM_DEVICE_INTERFACE_INDEX, index,
NM_DEVICE_INTERFACE_DRIVER, driver,
NM_DEVICE_INTERFACE_APP_DATA, app_data,
NULL);
if (obj == NULL)
return NULL;
g_signal_connect (obj, "state-changed",
G_CALLBACK (state_changed_cb),

View File

@@ -77,7 +77,7 @@ struct _NMDevice80211WirelessClass
GType nm_device_802_11_wireless_get_type (void);
NMDevice80211Wireless *nm_device_802_11_wireless_new (const char *iface,
NMDevice80211Wireless *nm_device_802_11_wireless_new (int index,
const char *udi,
const char *driver,
gboolean test_dev,

View File

@@ -103,26 +103,26 @@ nm_device_802_3_ethernet_init (NMDevice8023Ethernet * self)
static void
nm_device_802_3_ethernet_link_activated (NMNetlinkMonitor *monitor,
const char *iface,
int index,
gpointer user_data)
{
NMDevice *dev = NM_DEVICE (user_data);
/* Make sure signal is for us */
if (!strcmp (nm_device_get_iface (dev), iface))
if (nm_device_get_index (dev) == index)
nm_device_set_active_link (dev, TRUE);
}
static void
nm_device_802_3_ethernet_link_deactivated (NMNetlinkMonitor *monitor,
const char *iface,
int index,
gpointer user_data)
{
NMDevice *dev = NM_DEVICE (user_data);
/* Make sure signal is for us */
if (!strcmp (nm_device_get_iface (dev), iface))
if (nm_device_get_index (dev) == index)
nm_device_set_active_link (dev, FALSE);
}
@@ -237,7 +237,7 @@ real_bring_down (NMDevice *dev)
NMDevice8023Ethernet *
nm_device_802_3_ethernet_new (const char *iface,
nm_device_802_3_ethernet_new (int index,
const char *udi,
const char *driver,
gboolean test_dev,
@@ -245,17 +245,19 @@ nm_device_802_3_ethernet_new (const char *iface,
{
GObject *obj;
g_return_val_if_fail (iface != NULL, NULL);
g_return_val_if_fail (index >= 0, NULL);
g_return_val_if_fail (udi != NULL, NULL);
g_return_val_if_fail (driver != NULL, NULL);
g_return_val_if_fail (app_data != NULL, NULL);
obj = g_object_new (NM_TYPE_DEVICE_802_3_ETHERNET,
NM_DEVICE_INTERFACE_UDI, udi,
NM_DEVICE_INTERFACE_IFACE, iface,
NM_DEVICE_INTERFACE_INDEX, index,
NM_DEVICE_INTERFACE_DRIVER, driver,
NM_DEVICE_INTERFACE_APP_DATA, app_data,
NULL);
if (obj == NULL)
return NULL;
return NM_DEVICE_802_3_ETHERNET (obj);
}

View File

@@ -52,7 +52,7 @@ typedef struct {
GType nm_device_802_3_ethernet_get_type (void);
NMDevice8023Ethernet *nm_device_802_3_ethernet_new (const char *iface,
NMDevice8023Ethernet *nm_device_802_3_ethernet_new (int index,
const char *udi,
const char *driver,
gboolean test_dev,

View File

@@ -28,13 +28,21 @@ nm_device_interface_init (gpointer g_iface)
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_uint (NM_DEVICE_INTERFACE_INDEX,
"Index",
"Index",
0, G_MAXUINT32, 0, /* FIXME */
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_interface_install_property
(g_iface,
g_param_spec_string (NM_DEVICE_INTERFACE_IFACE,
"Interface",
"Interface",
NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
G_PARAM_READABLE));
g_object_interface_install_property
(g_iface,

View File

@@ -14,6 +14,7 @@
#define NM_DEVICE_INTERFACE_UDI "udi"
#define NM_DEVICE_INTERFACE_IFACE "interface"
#define NM_DEVICE_INTERFACE_INDEX "index"
#define NM_DEVICE_INTERFACE_DRIVER "driver"
#define NM_DEVICE_INTERFACE_CAPABILITIES "capabilities"
#define NM_DEVICE_INTERFACE_IP4_ADDRESS "ip4_address"
@@ -26,6 +27,7 @@ typedef enum {
NM_DEVICE_INTERFACE_PROP_FIRST = 0x1000,
NM_DEVICE_INTERFACE_PROP_UDI = NM_DEVICE_INTERFACE_PROP_FIRST,
NM_DEVICE_INTERFACE_PROP_INDEX,
NM_DEVICE_INTERFACE_PROP_IFACE,
NM_DEVICE_INTERFACE_PROP_DRIVER,
NM_DEVICE_INTERFACE_PROP_CAPABILITIES,

View File

@@ -37,6 +37,7 @@
#include "nm-dbus-nmi.h"
#include "nm-utils.h"
#include "autoip.h"
#include "nm-netlink.h"
#define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config"
@@ -52,11 +53,14 @@ G_DEFINE_TYPE_EXTENDED (NMDevice, nm_device, G_TYPE_OBJECT,
struct _NMDevicePrivate
{
gboolean dispose_has_run;
gboolean initialized;
NMDeviceState state;
char * dbus_path;
char * udi;
char * iface;
int index; /* Should always stay the same over lifetime of device */
char * iface; /* may change, could be renamed by user */
NMDeviceType type;
guint32 capabilities;
char * driver;
@@ -105,8 +109,10 @@ nm_device_init (NMDevice * self)
{
self->priv = NM_DEVICE_GET_PRIVATE (self);
self->priv->dispose_has_run = FALSE;
self->priv->initialized = FALSE;
self->priv->udi = NULL;
self->priv->iface = NULL;
self->priv->index = G_MAXUINT32;
self->priv->type = DEVICE_TYPE_UNKNOWN;
self->priv->capabilities = NM_DEVICE_CAP_NONE;
self->priv->driver = NULL;
@@ -134,45 +140,66 @@ constructor (GType type,
NMDevice *dev;
NMDevicePrivate *priv;
NMDBusManager *manager;
char *path;
object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
n_construct_params,
construct_params);
if (!object)
return NULL;
dev = NM_DEVICE (object);
priv = NM_DEVICE_GET_PRIVATE (dev);
if (priv->index == G_MAXUINT32) {
nm_warning ("Interface index is a required constructor property.");
goto error;
}
priv->iface = nm_netlink_index_to_iface (priv->index);
if (priv->iface == NULL) {
nm_warning ("(%d): Couldn't get interface name for device, ignoring.",
nm_device_get_index (dev));
goto error;
}
priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev);
if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED))
{
g_object_unref (G_OBJECT (dev));
return NULL;
if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) {
nm_warning ("(%s): Device unsupported, ignoring.",
nm_device_get_iface (dev));
goto error;
}
/* Grab IP config data for this device from the system configuration files */
priv->system_config_data = nm_system_device_get_system_config (dev, priv->app_data);
/* Allow distributions to flag devices as disabled */
if (nm_system_device_get_disabled (dev))
{
g_object_unref (G_OBJECT (dev));
return NULL;
if (nm_system_device_get_disabled (dev)) {
nm_warning ("(%s): Device otherwise managed, ignoring.",
nm_device_get_iface (dev));
goto error;
}
nm_print_device_capabilities (dev);
manager = nm_dbus_manager_get ();
priv->dbus_path = g_strdup_printf ("%s/%d",
NM_DBUS_PATH_DEVICE,
nm_device_get_index (dev));
if (priv->dbus_path == NULL) {
nm_warning ("(%s): Not enough memory to initialize device.",
nm_device_get_iface (dev));
goto error;
}
path = nm_dbus_get_object_path_for_device (dev);
dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (manager),
path, object);
g_free (path);
nm_device_get_dbus_path (dev),
object);
priv->initialized = TRUE;
return object;
error:
g_object_unref (dev);
return NULL;
}
@@ -214,9 +241,14 @@ real_get_generic_capabilities (NMDevice *dev)
}
/*
* Get/set functions for UDI
*/
const char *
nm_device_get_dbus_path (NMDevice *self)
{
g_return_val_if_fail (self != NULL, NULL);
return self->priv->dbus_path;
}
const char *
nm_device_get_udi (NMDevice *self)
{
@@ -225,6 +257,14 @@ nm_device_get_udi (NMDevice *self)
return self->priv->udi;
}
guint32
nm_device_get_index (NMDevice *self)
{
g_return_val_if_fail (self != NULL, G_MAXUINT32);
return self->priv->index;
}
/*
* Get/set functions for iface
*/
@@ -1119,7 +1159,7 @@ dhcp_state_changed (NMDHCPManager *dhcp_manager,
} else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
if (nm_device_get_use_dhcp (device)) {
/* dhclient quit and therefore can't renew our lease, kill the conneciton */
nm_device_deactivate (device);
nm_device_deactivate (NM_DEVICE_INTERFACE (device));
}
}
break;
@@ -1365,9 +1405,15 @@ nm_device_dispose (GObject *object)
{
NMDevice *self = NM_DEVICE (object);
if (self->priv->dispose_has_run)
/* If dispose did already run, return. */
if (self->priv->dispose_has_run) {
/* If dispose already ran, return. */
return;
}
if (!self->priv->initialized) {
/* Don't tear down stuff that might not yet be set up */
goto out;
}
/* Make sure dispose does not run twice. */
self->priv->dispose_has_run = TRUE;
@@ -1397,6 +1443,7 @@ nm_device_dispose (GObject *object)
nm_device_set_use_dhcp (self, FALSE);
out:
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
}
@@ -1424,8 +1471,8 @@ set_property (GObject *object, guint prop_id,
/* construct-only */
priv->udi = g_strdup (g_value_get_string (value));
break;
case NM_DEVICE_INTERFACE_PROP_IFACE:
priv->iface = g_strdup (g_value_get_string (value));
case NM_DEVICE_INTERFACE_PROP_INDEX:
priv->index = g_value_get_uint (value);
break;
case NM_DEVICE_INTERFACE_PROP_DRIVER:
priv->driver = g_strdup (g_value_get_string (value));
@@ -1455,6 +1502,9 @@ get_property (GObject *object, guint prop_id,
case NM_DEVICE_INTERFACE_PROP_UDI:
g_value_set_string (value, priv->udi);
break;
case NM_DEVICE_INTERFACE_PROP_INDEX:
g_value_set_uint (value, priv->index);
break;
case NM_DEVICE_INTERFACE_PROP_IFACE:
g_value_set_string (value, priv->iface);
break;
@@ -1516,6 +1566,10 @@ nm_device_class_init (NMDeviceClass *klass)
NM_DEVICE_INTERFACE_PROP_UDI,
NM_DEVICE_INTERFACE_UDI);
g_object_class_override_property (object_class,
NM_DEVICE_INTERFACE_PROP_INDEX,
NM_DEVICE_INTERFACE_INDEX);
g_object_class_override_property (object_class,
NM_DEVICE_INTERFACE_PROP_IFACE,
NM_DEVICE_INTERFACE_IFACE);

View File

@@ -110,10 +110,10 @@ struct _NMDeviceClass
GType nm_device_get_type (void);
const char * nm_device_get_dbus_path (NMDevice *dev);
const char * nm_device_get_udi (NMDevice *dev);
guint32 nm_device_get_index (NMDevice *dev);
const char * nm_device_get_iface (NMDevice *dev);
const char * nm_device_get_driver (NMDevice *dev);
NMDeviceType nm_device_get_device_type (NMDevice *dev);

View File

@@ -48,25 +48,22 @@ get_creator (NMHalManager *manager, const char *udi)
/* Common helpers for built-in device creators */
static char *
get_device_interface_from_hal (LibHalContext *ctx, const char *udi)
static int
get_device_index_from_hal (LibHalContext *ctx, const char *udi)
{
char *iface = NULL;
int idx = -1;
if (libhal_device_property_exists (ctx, udi, "net.interface", NULL) &&
if (libhal_device_property_exists (ctx, udi, "net.linux.ifindex", NULL) &&
libhal_device_property_exists (ctx, udi, "info.category", NULL)) {
char *category = libhal_device_get_property_string (ctx, udi, "info.category", NULL);
if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211"))) {
char *temp = libhal_device_get_property_string (ctx, udi, "net.interface", NULL);
iface = g_strdup (temp);
libhal_free_string (temp);
idx = libhal_device_get_property_int (ctx, udi, "net.linux.ifindex", NULL);
}
libhal_free_string (category);
}
return iface;
return idx;
}
static char *
@@ -94,7 +91,7 @@ is_wired_device (NMHalManager *manager, const char *udi)
char *category;
gboolean is_wired = FALSE;
if (libhal_device_property_exists (manager->hal_ctx, udi, "net.interface", NULL) &&
if (libhal_device_property_exists (manager->hal_ctx, udi, "net.linux.ifindex", NULL) &&
libhal_device_property_exists (manager->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (manager->hal_ctx, udi, "info.category", NULL);
@@ -111,14 +108,17 @@ NMDevice *
wired_device_creator (NMHalManager *manager, const char *udi)
{
NMDevice *device;
char *iface;
int idx;
char *driver;
iface = get_device_interface_from_hal (manager->hal_ctx, udi);
driver = nm_get_device_driver_name (manager->hal_ctx, udi);
device = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, manager->nm_data);
idx = get_device_index_from_hal (manager->hal_ctx, udi);
if (idx < 0) {
nm_warning ("Couldn't get interface index for %s, ignoring.", udi);
return NULL;
}
g_free (iface);
driver = nm_get_device_driver_name (manager->hal_ctx, udi);
device = (NMDevice *) nm_device_802_3_ethernet_new (idx, udi, driver, FALSE, manager->nm_data);
g_free (driver);
return device;
@@ -132,7 +132,7 @@ is_wireless_device (NMHalManager *manager, const char *udi)
char *category;
gboolean is_wireless = FALSE;
if (libhal_device_property_exists (manager->hal_ctx, udi, "net.interface", NULL) &&
if (libhal_device_property_exists (manager->hal_ctx, udi, "net.linux.ifindex", NULL) &&
libhal_device_property_exists (manager->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (manager->hal_ctx, udi, "info.category", NULL);
@@ -149,14 +149,17 @@ NMDevice *
wireless_device_creator (NMHalManager *manager, const char *udi)
{
NMDevice *device;
char *iface;
int idx;
char *driver;
iface = get_device_interface_from_hal (manager->hal_ctx, udi);
driver = nm_get_device_driver_name (manager->hal_ctx, udi);
device = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, manager->nm_data);
idx = get_device_index_from_hal (manager->hal_ctx, udi);
if (idx < 0) {
nm_warning ("Couldn't get interface index for %s, ignoring.", udi);
return NULL;
}
g_free (iface);
driver = nm_get_device_driver_name (manager->hal_ctx, udi);
device = (NMDevice *) nm_device_802_11_wireless_new (idx, udi, driver, FALSE, manager->nm_data);
g_free (driver);
return device;

View File

@@ -209,7 +209,7 @@ nm_manager_new (void)
NM_DBUS_PATH,
object);
return (NMManager *) object;
return NM_MANAGER (object);
}
static void
@@ -350,7 +350,7 @@ impl_manager_get_devices (NMManager *manager, GPtrArray **devices, GError **err)
*devices = g_ptr_array_sized_new (g_slist_length (priv->devices));
for (iter = priv->devices; iter; iter = iter->next)
g_ptr_array_add (*devices, nm_dbus_get_object_path_for_device (NM_DEVICE (iter->data)));
g_ptr_array_add (*devices, nm_device_get_dbus_path (NM_DEVICE (iter->data)));
return TRUE;
}
@@ -372,6 +372,24 @@ nm_manager_get_device_by_iface (NMManager *manager, const char *iface)
return NULL;
}
NMDevice *
nm_manager_get_device_by_index (NMManager *manager, int idx)
{
GSList *iter;
g_return_val_if_fail (NM_IS_MANAGER (manager), NULL);
for (iter = NM_MANAGER_GET_PRIVATE (manager)->devices; iter; iter = iter->next) {
NMDevice *device = NM_DEVICE (iter->data);
if (nm_device_get_index (device) == idx)
return device;
}
return NULL;
}
NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi)
{

View File

@@ -42,6 +42,7 @@ void nm_manager_add_device (NMManager *manager, NMDevice *device);
void nm_manager_remove_device (NMManager *manager, NMDevice *device);
GSList *nm_manager_get_devices (NMManager *manager);
NMDevice *nm_manager_get_device_by_iface (NMManager *manager, const char *iface);
NMDevice *nm_manager_get_device_by_index (NMManager *manager, int idx);
NMDevice *nm_manager_get_device_by_udi (NMManager *manager, const char *udi);
NMDevice *nm_manager_get_active_device (NMManager *manager);

View File

@@ -1,5 +1,4 @@
VOID:OBJECT
VOID:STRING,POINTER,INT
VOID:POINTER
VOID:STRING,STRING,STRING
VOID:UINT,UINT

View File

@@ -121,7 +121,7 @@ nm_netlink_monitor_class_init (NMNetlinkMonitorClass *monitor_class)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMNetlinkMonitorClass, interface_connected),
NULL, NULL, g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
G_TYPE_NONE, 1, G_TYPE_INT);
signals[INTERFACE_DISCONNECTED] =
g_signal_new ("interface-disconnected",
@@ -129,7 +129,7 @@ nm_netlink_monitor_class_init (NMNetlinkMonitorClass *monitor_class)
G_SIGNAL_RUN_LAST,
G_STRUCT_OFFSET (NMNetlinkMonitorClass, interface_disconnected),
NULL, NULL, g_cclosure_marshal_VOID__STRING,
G_TYPE_NONE, 1, G_TYPE_STRING);
G_TYPE_NONE, 1, G_TYPE_INT);
signals[ERROR] =
g_signal_new ("error",
@@ -692,25 +692,19 @@ nm_netlink_monitor_event_handler (GIOChannel *channel,
int data_len = RTA_PAYLOAD (attribute);
if (attribute->rta_type == IFLA_IFNAME) {
char * iface = g_malloc0 (data_len + 1);
memcpy (iface, RTA_DATA (attribute), data_len);
if (strlen (iface))
{
/* The !! weirdness is to cannonicalize the value to 0 or 1. */
gboolean is_connected = !!((gboolean) (interface_info->ifi_flags & IFF_RUNNING));
if (is_connected) {
g_signal_emit (G_OBJECT (monitor),
signals[INTERFACE_CONNECTED],
0, iface);
0, interface_info->ifi_index);
} else {
g_signal_emit (G_OBJECT (monitor),
signals[INTERFACE_DISCONNECTED],
0, iface);
0, interface_info->ifi_index);
}
}
g_free (iface);
}
}
}
g_free (received_bytes);

View File

@@ -53,8 +53,8 @@ typedef struct {
GObjectClass parent_class;
/* Signals */
void (*interface_connected) (NMNetlinkMonitor *monitor, const char *iface);
void (*interface_disconnected) (NMNetlinkMonitor *monitor, const char *iface);
void (*interface_connected) (NMNetlinkMonitor *monitor, int index);
void (*interface_disconnected) (NMNetlinkMonitor *monitor, int index);
void (*error) (NMNetlinkMonitor *monitor,
GError *error);

109
src/nm-netlink.c Normal file
View File

@@ -0,0 +1,109 @@
/* NetworkManager -- Network link manager
*
* 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
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#include "nm-netlink.h"
#include "nm-utils.h"
#include <glib.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 ();
g_assert (nlh);
if (!link_cache)
link_cache = rtnl_link_alloc_cache (nlh);
g_assert (link_cache);
nl_cache_update (nlh, link_cache);
return link_cache;
}
struct nl_handle *
nm_netlink_get_default_handle (void)
{
if (def_nl_handle)
return def_nl_handle;
def_nl_handle = nl_handle_alloc_nondefault (NL_CB_VERBOSE);
g_assert (def_nl_handle);
nl_handle_set_pid (def_nl_handle, (pthread_self () << 16 | getpid ()));
if (nl_connect (def_nl_handle, NETLINK_ROUTE) < 0) {
nm_error ("couldn't connect to netlink: %s", nl_geterror ());
nl_handle_destroy (def_nl_handle);
return NULL;
}
return def_nl_handle;
}
int
nm_netlink_iface_to_index (const char *iface)
{
struct nl_cache * cache;
struct nl_handle * nlh;
int i;
g_return_val_if_fail (iface != NULL, -1);
cache = get_link_cache ();
g_assert (cache);
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;
buf = g_malloc0 (MAX_IFACE_LEN);
if (buf == NULL) {
nm_warning ("Not enough memory to allocate interface name buffer.");
return NULL;
}
cache = get_link_cache ();
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)
{
return rtnl_link_get (get_link_cache (), idx);
}

36
src/nm-netlink.h Normal file
View File

@@ -0,0 +1,36 @@
/* NetworkManager -- Network link manager
*
* 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
* 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*
* (C) Copyright 2007 Red Hat, Inc.
*/
#ifndef NM_NETLINK_H
#define NM_NETLINK_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 */