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> 2007-08-26 Dan Williams <dcbw@redhat.com>
* src/nm-netlink-monitor.h * src/nm-netlink-monitor.h

View File

@@ -72,7 +72,9 @@ NetworkManager_SOURCES = \
nm-marshal-main.c \ nm-marshal-main.c \
kernel-types.h \ kernel-types.h \
wpa.c \ wpa.c \
wpa.h wpa.h \
nm-netlink.c \
nm-netlink.h
nm-marshal.h: Makefile.am nm-marshal.list nm-marshal.h: Makefile.am nm-marshal.list
$(GLIB_GENMARSHAL) --prefix=nm_marshal $(srcdir)/nm-marshal.list --header > \ $(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."); "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 */ /* 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); 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_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); DBusMessage * nm_dbus_new_invalid_args_error (DBusMessage *replyto, const char *namespace);

View File

@@ -45,6 +45,7 @@
#include "nm-device.h" #include "nm-device.h"
#include "NetworkManagerUtils.h" #include "NetworkManagerUtils.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "nm-netlink.h"
#include <netlink/route/addr.h> #include <netlink/route/addr.h>
#include <netlink/netlink.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 * 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_device_flush_routes (dev);
nm_system_flush_arp_cache (); 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))) 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) 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()); nm_warning ("(%s) error %d returned from rtnl_addr_add():\n%s", nm_device_get_iface (dev), err, nl_geterror());
rtnl_addr_put (addr); rtnl_addr_put (addr);
@@ -329,9 +219,6 @@ gboolean nm_system_device_set_from_ip4_config (NMDevice *dev)
else else
nm_warning ("couldn't create rtnl address!\n"); nm_warning ("couldn't create rtnl address!\n");
nl_close (nlh);
nl_handle_destroy (nlh);
sleep (1); sleep (1);
nm_system_device_set_ip4_route (dev, nm_ip4_config_get_gateway (config), 0, 0, nm_ip4_config_get_mss (config)); 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); 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))) if ((addr = nm_ip4_config_to_rtnl_addr (config, NM_RTNL_ADDR_PTP_DEFAULT)))
{ {
int err = 0; 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) if ((err = rtnl_addr_add (nlh, addr, 0)) < 0)
nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror()); nm_warning ("error %d returned from rtnl_addr_add():\n%s", err, nl_geterror());
rtnl_addr_put (addr); rtnl_addr_put (addr);
@@ -471,7 +358,7 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
struct rtnl_link * old; struct rtnl_link * old;
guint32 mtu; 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); mtu = nm_ip4_config_get_mtu (config);
if (mtu == 0) if (mtu == 0)
mtu = 1412; /* Default to 1412 (vpnc) */ mtu = 1412; /* Default to 1412 (vpnc) */
@@ -482,9 +369,6 @@ nm_system_vpn_device_set_from_ip4_config (NMNamedManager *named,
rtnl_link_put (request); rtnl_link_put (request);
} }
nl_close (nlh);
nl_handle_destroy (nlh);
sleep (1); sleep (1);
nm_system_device_flush_routes_with_iface (iface); 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 nm_system_device_set_up_down_with_iface (const char *iface, gboolean up)
{ {
gboolean success = FALSE; gboolean success = FALSE;
struct nl_handle * nlh = NULL; guint32 index;
struct rtnl_link * request = NULL; struct rtnl_link * request = NULL;
struct rtnl_link * old = NULL; struct rtnl_link * old = NULL;
g_return_val_if_fail (iface != NULL, FALSE); g_return_val_if_fail (iface != NULL, FALSE);
if (!(nlh = new_nl_handle ()))
return FALSE;
if (!(request = rtnl_link_alloc ())) if (!(request = rtnl_link_alloc ()))
goto out; goto out;
@@ -574,19 +455,18 @@ gboolean nm_system_device_set_up_down_with_iface (const char *iface, gboolean up
else else
rtnl_link_unset_flags (request, IFF_UP); rtnl_link_unset_flags (request, IFF_UP);
old = iface_to_rtnl_link (iface, nlh); index = nm_netlink_iface_to_index (iface);
if (old) 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_change (nlh, old, request, 0);
}
rtnl_link_put (old); rtnl_link_put (old);
rtnl_link_put (request); rtnl_link_put (request);
success = TRUE; success = TRUE;
out: out:
nl_close (nlh);
nl_handle_destroy (nlh);
return success; return success;
} }
@@ -608,27 +488,22 @@ void nm_system_set_mtu (NMDevice *dev)
if (!mtu) if (!mtu)
return; return;
nlh = new_nl_handle ();
if (!nlh)
return;
request = rtnl_link_alloc (); request = rtnl_link_alloc ();
if (!request) if (!request)
goto out_nl_close; return;
iface = nm_device_get_iface (dev); old = nm_netlink_index_to_rtnl_link (nm_device_get_index (dev));
old = iface_to_rtnl_link (iface, nlh);
if (!old) if (!old)
goto out_request; 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); rtnl_link_set_mtu (request, mtu);
nlh = nm_netlink_get_default_handle ();
rtnl_link_change (nlh, old, request, 0); rtnl_link_change (nlh, old, request, 0);
rtnl_link_put (old); rtnl_link_put (old);
out_request: out_request:
rtnl_link_put (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); void nm_system_init (void);
gboolean nm_system_device_has_active_routes (NMDevice *dev); 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 (NMDevice *dev);
void nm_system_device_flush_routes_with_iface (const char *iface); 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; UserKeyInfo *info;
NMAccessPoint * ap; NMAccessPoint * ap;
gint32 attempt = 1; gint32 attempt = 1;
char * dev_path; const char * dev_path;
const char * net_path; const char * net_path;
const GByteArray * ssid; const GByteArray * ssid;
@@ -185,7 +185,7 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
goto out; 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); net_path = nm_ap_get_dbus_path (ap);
if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) { if (dev_path && strlen (dev_path) && net_path && strlen (net_path)) {
char buf[IW_ESSID_MAX_SIZE + 1]; char buf[IW_ESSID_MAX_SIZE + 1];
@@ -215,7 +215,6 @@ nm_dbus_get_user_key_for_network (NMDevice *dev,
} else { } else {
nm_warning ("bad object path data"); nm_warning ("bad object path data");
} }
g_free (dev_path);
/* FIXME: figure out how to deal with a failure here, otherwise /* FIXME: figure out how to deal with a failure here, otherwise
* we just hang in the activation process and nothing happens * 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) if (iw_get_range_info (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), &range) < 0)
goto out; goto out;
if (range.we_version_compiled < 16) if (range.we_version_compiled < 16) {
{ nm_warning ("%s: driver's Wireless Extensions version (%d) is too old.",
nm_warning ("%s: driver's Wireless Extensions version (%d) is too old. Can't use device.",
iface, range.we_version_compiled); iface, range.we_version_compiled);
} goto out;
else } else {
caps |= NM_DEVICE_CAP_NM_SUPPORTED; caps |= NM_DEVICE_CAP_NM_SUPPORTED;
}
/* Card's that don't scan aren't supported */ /* Card's that don't scan aren't supported */
memset (&wrq, 0, sizeof (struct iwreq)); memset (&wrq, 0, sizeof (struct iwreq));
err = iw_set_ext (nm_dev_sock_get_fd (sk), nm_device_get_iface (dev), SIOCSIWSCAN, &wrq); 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; caps = NM_DEVICE_CAP_NONE;
out: out:
@@ -3174,7 +3174,7 @@ nm_info ("%s(): clearing activation AP", __func__);
NMDevice80211Wireless * NMDevice80211Wireless *
nm_device_802_11_wireless_new (const char *iface, nm_device_802_11_wireless_new (int index,
const char *udi, const char *udi,
const char *driver, const char *driver,
gboolean test_dev, gboolean test_dev,
@@ -3182,17 +3182,19 @@ nm_device_802_11_wireless_new (const char *iface,
{ {
GObject *obj; 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 (udi != NULL, NULL);
g_return_val_if_fail (driver != NULL, NULL); g_return_val_if_fail (driver != NULL, NULL);
g_return_val_if_fail (app_data != NULL, NULL); g_return_val_if_fail (app_data != NULL, NULL);
obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS, obj = g_object_new (NM_TYPE_DEVICE_802_11_WIRELESS,
NM_DEVICE_INTERFACE_UDI, udi, NM_DEVICE_INTERFACE_UDI, udi,
NM_DEVICE_INTERFACE_IFACE, iface, NM_DEVICE_INTERFACE_INDEX, index,
NM_DEVICE_INTERFACE_DRIVER, driver, NM_DEVICE_INTERFACE_DRIVER, driver,
NM_DEVICE_INTERFACE_APP_DATA, app_data, NM_DEVICE_INTERFACE_APP_DATA, app_data,
NULL); NULL);
if (obj == NULL)
return NULL;
g_signal_connect (obj, "state-changed", g_signal_connect (obj, "state-changed",
G_CALLBACK (state_changed_cb), G_CALLBACK (state_changed_cb),

View File

@@ -77,7 +77,7 @@ struct _NMDevice80211WirelessClass
GType nm_device_802_11_wireless_get_type (void); 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 *udi,
const char *driver, const char *driver,
gboolean test_dev, gboolean test_dev,

View File

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

View File

@@ -52,7 +52,7 @@ typedef struct {
GType nm_device_802_3_ethernet_get_type (void); 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 *udi,
const char *driver, const char *driver,
gboolean test_dev, gboolean test_dev,

View File

@@ -28,13 +28,21 @@ nm_device_interface_init (gpointer g_iface)
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); 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_object_interface_install_property
(g_iface, (g_iface,
g_param_spec_string (NM_DEVICE_INTERFACE_IFACE, g_param_spec_string (NM_DEVICE_INTERFACE_IFACE,
"Interface", "Interface",
"Interface", "Interface",
NULL, NULL,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY)); G_PARAM_READABLE));
g_object_interface_install_property g_object_interface_install_property
(g_iface, (g_iface,

View File

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

View File

@@ -37,6 +37,7 @@
#include "nm-dbus-nmi.h" #include "nm-dbus-nmi.h"
#include "nm-utils.h" #include "nm-utils.h"
#include "autoip.h" #include "autoip.h"
#include "nm-netlink.h"
#define NM_ACT_REQUEST_IP4_CONFIG "nm-act-request-ip4-config" #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 struct _NMDevicePrivate
{ {
gboolean dispose_has_run; gboolean dispose_has_run;
gboolean initialized;
NMDeviceState state; NMDeviceState state;
char * dbus_path;
char * udi; 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; NMDeviceType type;
guint32 capabilities; guint32 capabilities;
char * driver; char * driver;
@@ -105,8 +109,10 @@ nm_device_init (NMDevice * self)
{ {
self->priv = NM_DEVICE_GET_PRIVATE (self); self->priv = NM_DEVICE_GET_PRIVATE (self);
self->priv->dispose_has_run = FALSE; self->priv->dispose_has_run = FALSE;
self->priv->initialized = FALSE;
self->priv->udi = NULL; self->priv->udi = NULL;
self->priv->iface = NULL; self->priv->iface = NULL;
self->priv->index = G_MAXUINT32;
self->priv->type = DEVICE_TYPE_UNKNOWN; self->priv->type = DEVICE_TYPE_UNKNOWN;
self->priv->capabilities = NM_DEVICE_CAP_NONE; self->priv->capabilities = NM_DEVICE_CAP_NONE;
self->priv->driver = NULL; self->priv->driver = NULL;
@@ -134,45 +140,66 @@ constructor (GType type,
NMDevice *dev; NMDevice *dev;
NMDevicePrivate *priv; NMDevicePrivate *priv;
NMDBusManager *manager; NMDBusManager *manager;
char *path;
object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type, object = G_OBJECT_CLASS (nm_device_parent_class)->constructor (type,
n_construct_params, n_construct_params,
construct_params); construct_params);
if (!object) if (!object)
return NULL; return NULL;
dev = NM_DEVICE (object); dev = NM_DEVICE (object);
priv = NM_DEVICE_GET_PRIVATE (dev); 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); priv->capabilities |= NM_DEVICE_GET_CLASS (dev)->get_generic_capabilities (dev);
if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) if (!(priv->capabilities & NM_DEVICE_CAP_NM_SUPPORTED)) {
{ nm_warning ("(%s): Device unsupported, ignoring.",
g_object_unref (G_OBJECT (dev)); nm_device_get_iface (dev));
return NULL; goto error;
} }
/* Grab IP config data for this device from the system configuration files */ /* 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); priv->system_config_data = nm_system_device_get_system_config (dev, priv->app_data);
/* Allow distributions to flag devices as disabled */ /* Allow distributions to flag devices as disabled */
if (nm_system_device_get_disabled (dev)) if (nm_system_device_get_disabled (dev)) {
{ nm_warning ("(%s): Device otherwise managed, ignoring.",
g_object_unref (G_OBJECT (dev)); nm_device_get_iface (dev));
return NULL; goto error;
} }
nm_print_device_capabilities (dev); nm_print_device_capabilities (dev);
manager = nm_dbus_manager_get (); 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), dbus_g_connection_register_g_object (nm_dbus_manager_get_connection (manager),
path, object); nm_device_get_dbus_path (dev),
g_free (path); object);
priv->initialized = TRUE;
return object; return object;
error:
g_object_unref (dev);
return NULL;
} }
@@ -214,9 +241,14 @@ real_get_generic_capabilities (NMDevice *dev)
} }
/* const char *
* Get/set functions for UDI nm_device_get_dbus_path (NMDevice *self)
*/ {
g_return_val_if_fail (self != NULL, NULL);
return self->priv->dbus_path;
}
const char * const char *
nm_device_get_udi (NMDevice *self) nm_device_get_udi (NMDevice *self)
{ {
@@ -225,6 +257,14 @@ nm_device_get_udi (NMDevice *self)
return self->priv->udi; 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 * 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) { } else if (nm_device_get_state (device) == NM_DEVICE_STATE_ACTIVATED) {
if (nm_device_get_use_dhcp (device)) { if (nm_device_get_use_dhcp (device)) {
/* dhclient quit and therefore can't renew our lease, kill the conneciton */ /* dhclient quit and therefore can't renew our lease, kill the conneciton */
nm_device_deactivate (device); nm_device_deactivate (NM_DEVICE_INTERFACE (device));
} }
} }
break; break;
@@ -1365,9 +1405,15 @@ nm_device_dispose (GObject *object)
{ {
NMDevice *self = NM_DEVICE (object); NMDevice *self = NM_DEVICE (object);
if (self->priv->dispose_has_run) if (self->priv->dispose_has_run) {
/* If dispose did already run, return. */ /* If dispose already ran, return. */
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. */ /* Make sure dispose does not run twice. */
self->priv->dispose_has_run = TRUE; self->priv->dispose_has_run = TRUE;
@@ -1397,6 +1443,7 @@ nm_device_dispose (GObject *object)
nm_device_set_use_dhcp (self, FALSE); nm_device_set_use_dhcp (self, FALSE);
out:
G_OBJECT_CLASS (nm_device_parent_class)->dispose (object); G_OBJECT_CLASS (nm_device_parent_class)->dispose (object);
} }
@@ -1424,8 +1471,8 @@ set_property (GObject *object, guint prop_id,
/* construct-only */ /* construct-only */
priv->udi = g_strdup (g_value_get_string (value)); priv->udi = g_strdup (g_value_get_string (value));
break; break;
case NM_DEVICE_INTERFACE_PROP_IFACE: case NM_DEVICE_INTERFACE_PROP_INDEX:
priv->iface = g_strdup (g_value_get_string (value)); priv->index = g_value_get_uint (value);
break; break;
case NM_DEVICE_INTERFACE_PROP_DRIVER: case NM_DEVICE_INTERFACE_PROP_DRIVER:
priv->driver = g_strdup (g_value_get_string (value)); 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: case NM_DEVICE_INTERFACE_PROP_UDI:
g_value_set_string (value, priv->udi); g_value_set_string (value, priv->udi);
break; break;
case NM_DEVICE_INTERFACE_PROP_INDEX:
g_value_set_uint (value, priv->index);
break;
case NM_DEVICE_INTERFACE_PROP_IFACE: case NM_DEVICE_INTERFACE_PROP_IFACE:
g_value_set_string (value, priv->iface); g_value_set_string (value, priv->iface);
break; break;
@@ -1516,6 +1566,10 @@ nm_device_class_init (NMDeviceClass *klass)
NM_DEVICE_INTERFACE_PROP_UDI, NM_DEVICE_INTERFACE_PROP_UDI,
NM_DEVICE_INTERFACE_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, g_object_class_override_property (object_class,
NM_DEVICE_INTERFACE_PROP_IFACE, NM_DEVICE_INTERFACE_PROP_IFACE,
NM_DEVICE_INTERFACE_IFACE); NM_DEVICE_INTERFACE_IFACE);

View File

@@ -110,10 +110,10 @@ struct _NMDeviceClass
GType nm_device_get_type (void); GType nm_device_get_type (void);
const char * nm_device_get_dbus_path (NMDevice *dev);
const char * nm_device_get_udi (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_iface (NMDevice *dev);
const char * nm_device_get_driver (NMDevice *dev); const char * nm_device_get_driver (NMDevice *dev);
NMDeviceType nm_device_get_device_type (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 */ /* Common helpers for built-in device creators */
static char * static int
get_device_interface_from_hal (LibHalContext *ctx, const char *udi) 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)) { libhal_device_property_exists (ctx, udi, "info.category", NULL)) {
char *category = libhal_device_get_property_string (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"))) { if (category && (!strcmp (category, "net.80203") || !strcmp (category, "net.80211"))) {
char *temp = libhal_device_get_property_string (ctx, udi, "net.interface", NULL); idx = libhal_device_get_property_int (ctx, udi, "net.linux.ifindex", NULL);
iface = g_strdup (temp);
libhal_free_string (temp);
} }
libhal_free_string (category); libhal_free_string (category);
} }
return iface; return idx;
} }
static char * static char *
@@ -94,7 +91,7 @@ is_wired_device (NMHalManager *manager, const char *udi)
char *category; char *category;
gboolean is_wired = FALSE; 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)) { libhal_device_property_exists (manager->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (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) wired_device_creator (NMHalManager *manager, const char *udi)
{ {
NMDevice *device; NMDevice *device;
char *iface; int idx;
char *driver; char *driver;
iface = get_device_interface_from_hal (manager->hal_ctx, udi); idx = get_device_index_from_hal (manager->hal_ctx, udi);
driver = nm_get_device_driver_name (manager->hal_ctx, udi); if (idx < 0) {
device = (NMDevice *) nm_device_802_3_ethernet_new (iface, udi, driver, FALSE, manager->nm_data); 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); g_free (driver);
return device; return device;
@@ -132,7 +132,7 @@ is_wireless_device (NMHalManager *manager, const char *udi)
char *category; char *category;
gboolean is_wireless = FALSE; 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)) { libhal_device_property_exists (manager->hal_ctx, udi, "info.category", NULL)) {
category = libhal_device_get_property_string (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) wireless_device_creator (NMHalManager *manager, const char *udi)
{ {
NMDevice *device; NMDevice *device;
char *iface; int idx;
char *driver; char *driver;
iface = get_device_interface_from_hal (manager->hal_ctx, udi); idx = get_device_index_from_hal (manager->hal_ctx, udi);
driver = nm_get_device_driver_name (manager->hal_ctx, udi); if (idx < 0) {
device = (NMDevice *) nm_device_802_11_wireless_new (iface, udi, driver, FALSE, manager->nm_data); 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); g_free (driver);
return device; return device;

View File

@@ -209,7 +209,7 @@ nm_manager_new (void)
NM_DBUS_PATH, NM_DBUS_PATH,
object); object);
return (NMManager *) object; return NM_MANAGER (object);
} }
static void 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)); *devices = g_ptr_array_sized_new (g_slist_length (priv->devices));
for (iter = priv->devices; iter; iter = iter->next) 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; return TRUE;
} }
@@ -372,6 +372,24 @@ nm_manager_get_device_by_iface (NMManager *manager, const char *iface)
return NULL; 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 * NMDevice *
nm_manager_get_device_by_udi (NMManager *manager, const char *udi) 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); void nm_manager_remove_device (NMManager *manager, NMDevice *device);
GSList *nm_manager_get_devices (NMManager *manager); 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_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_device_by_udi (NMManager *manager, const char *udi);
NMDevice *nm_manager_get_active_device (NMManager *manager); NMDevice *nm_manager_get_active_device (NMManager *manager);

View File

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

View File

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

View File

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