diff --git a/src/Makefile.am b/src/Makefile.am index 80336ab06..5d2db6e36 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -141,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 \ diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 4f8336d9b..8f16066fa 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -1,9 +1,5 @@ /* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */ /* NetworkManager -- Network link manager - * - * Timothee Lecomte - * - * Heavily based on NetworkManagerRedhat.c by Dan Williams * * 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 */ #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 diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 0ce694dcf..50905c3af 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -27,7 +27,6 @@ #include "nm-ip6-manager.h" #include "nm-netlink-monitor.h" -#include "nm-netlink.h" #include "NetworkManagerUtils.h" #include "nm-marshal.h" #include "nm-logging.h" diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 00942a3d3..202584b24 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -45,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" diff --git a/src/nm-device.c b/src/nm-device.c index 1ee751032..db0ad914a 100644 --- a/src/nm-device.c +++ b/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" diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c index 24b463ce3..bfcbab7e7 100644 --- a/src/nm-netlink-monitor.c +++ b/src/nm-netlink-monitor.c @@ -25,7 +25,7 @@ * Copyright (C) 2004 Novell, Inc. */ -/* for struct ucred */ +/* for struct ucred and LIBNL_NEEDS_ADDR_CACHING_WORKAROUND */ #include #include @@ -38,16 +38,15 @@ #include #include #include -#include +#include +#include +#include #include #include -#include "NetworkManager.h" -#include "nm-system.h" #include "nm-netlink-monitor.h" #include "nm-logging.h" -#include "nm-netlink.h" #define EVENT_CONDITIONS ((GIOCondition) (G_IO_IN | G_IO_PRI)) #define ERROR_CONDITIONS ((GIOCondition) (G_IO_ERR | G_IO_NVAL)) @@ -60,7 +59,7 @@ typedef struct { struct nl_handle *nlh; struct nl_cb * nlh_cb; - struct nl_cache * nlh_link_cache; + struct nl_cache * link_cache; GIOChannel * io_channel; guint event_id; @@ -104,8 +103,10 @@ link_msg_handler (struct nl_object *obj, void *arg) } /* Ensure it's a link object */ - if (nl_object_match_filter(obj, OBJ_CAST (filter)) == 0) - goto out; + if (nl_object_match_filter(obj, OBJ_CAST (filter)) == 0) { + rtnl_link_put (filter); + return; + } link_obj = (struct rtnl_link *) obj; flags = rtnl_link_get_flags (link_obj); @@ -121,7 +122,6 @@ link_msg_handler (struct nl_object *obj, void *arg) else g_signal_emit (self, signals[CARRIER_OFF], 0, ifidx); -out: rtnl_link_put (filter); } @@ -227,6 +227,9 @@ nm_netlink_monitor_open_connection (NMNetlinkMonitor *self, GError **error) GError *channel_error = NULL; GIOFlags channel_flags; int fd; +#ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND + struct nl_cache *addr_cache; +#endif g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); @@ -265,11 +268,23 @@ nm_netlink_monitor_open_connection (NMNetlinkMonitor *self, GError **error) goto error; } +#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 (priv->nlh); + nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80; + nl_cache_free (addr_cache); +#endif + /* Subscribe to the LINK group for internal carrier signals */ if (!nm_netlink_monitor_subscribe (self, RTNLGRP_LINK, error)) goto error; - if ((priv->nlh_link_cache = rtnl_link_alloc_cache (priv->nlh)) == NULL) { + if ((priv->link_cache = rtnl_link_alloc_cache (priv->nlh)) == NULL) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_LINK_CACHE, _("unable to allocate netlink link cache for monitoring link status: %s"), @@ -277,7 +292,7 @@ nm_netlink_monitor_open_connection (NMNetlinkMonitor *self, GError **error) goto error; } - nl_cache_mngt_provide (priv->nlh_link_cache); + nl_cache_mngt_provide (priv->link_cache); fd = nl_socket_get_fd (priv->nlh); priv->io_channel = g_io_channel_unix_new (fd); @@ -303,9 +318,9 @@ error: if (priv->io_channel) nm_netlink_monitor_close_connection (self); - if (priv->nlh_link_cache) { - nl_cache_free (priv->nlh_link_cache); - priv->nlh_link_cache = NULL; + if (priv->link_cache) { + nl_cache_free (priv->link_cache); + priv->link_cache = NULL; } if (priv->nlh) { @@ -475,10 +490,10 @@ deferred_emit_carrier_state (gpointer user_data) /* Update the link cache with latest state, and if there are no errors * emit the link states for all the interfaces in the cache. */ - if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) { + if (nl_cache_refill (priv->nlh, priv->link_cache)) { nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror ()); } else - nl_cache_foreach_filter (priv->nlh_link_cache, NULL, link_msg_handler, self); + nl_cache_foreach_filter (priv->link_cache, NULL, link_msg_handler, self); return FALSE; } @@ -534,7 +549,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); /* Update the link cache with the latest information */ - if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) { + if (nl_cache_refill (priv->nlh, priv->link_cache)) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, @@ -547,7 +562,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, * otherwise some kernels (or maybe libnl?) only send a few of the * interfaces in the refill request. */ - if (nl_cache_refill (priv->nlh, priv->nlh_link_cache)) { + if (nl_cache_refill (priv->nlh, priv->link_cache)) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, @@ -572,7 +587,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, info.self = self; info.filter = filter; info.error = NULL; - nl_cache_foreach_filter (priv->nlh_link_cache, NULL, get_flags_sync_cb, &info); + nl_cache_foreach_filter (priv->link_cache, NULL, get_flags_sync_cb, &info); rtnl_link_put (filter); @@ -590,6 +605,85 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, /***************************************************************/ +struct nl_handle * +nm_netlink_get_default_handle (void) +{ + NMNetlinkMonitor *self; + struct nl_handle *nlh; + + self = nm_netlink_monitor_get (); + nlh = NM_NETLINK_MONITOR_GET_PRIVATE (self)->nlh; + g_object_unref (self); + + return nlh; +} + +int +nm_netlink_iface_to_index (const char *iface) +{ + NMNetlinkMonitor *self; + NMNetlinkMonitorPrivate *priv; + int idx; + + g_return_val_if_fail (iface != NULL, -1); + + self = nm_netlink_monitor_get (); + priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); + + nl_cache_update (priv->nlh, priv->link_cache); + idx = rtnl_link_name2i (priv->link_cache, iface); + g_object_unref (self); + + return idx; +} + +#define MAX_IFACE_LEN 33 +char * +nm_netlink_index_to_iface (int idx) +{ + NMNetlinkMonitor *self; + NMNetlinkMonitorPrivate *priv; + char *buf = NULL; + + g_return_val_if_fail (idx >= 0, NULL); + + self = nm_netlink_monitor_get (); + priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); + + buf = g_malloc0 (MAX_IFACE_LEN); + g_assert (buf); + + nl_cache_update (priv->nlh, priv->link_cache); + if (!rtnl_link_i2name (priv->link_cache, idx, buf, MAX_IFACE_LEN - 1)) { + g_free (buf); + buf = NULL; + } + + g_object_unref (self); + return buf; +} + +struct rtnl_link * +nm_netlink_index_to_rtnl_link (int idx) +{ + NMNetlinkMonitor *self; + NMNetlinkMonitorPrivate *priv; + struct rtnl_link *ret = NULL; + + g_return_val_if_fail (idx >= 0, NULL); + + self = nm_netlink_monitor_get (); + priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); + + nl_cache_update (priv->nlh, priv->link_cache); + ret = rtnl_link_get (priv->link_cache, idx); + g_object_unref (self); + + return ret; +} + +/***************************************************************/ + NMNetlinkMonitor * nm_netlink_monitor_get (void) { @@ -622,9 +716,9 @@ finalize (GObject *object) if (priv->io_channel) nm_netlink_monitor_close_connection (NM_NETLINK_MONITOR (object)); - if (priv->nlh_link_cache) { - nl_cache_free (priv->nlh_link_cache); - priv->nlh_link_cache = NULL; + if (priv->link_cache) { + nl_cache_free (priv->link_cache); + priv->link_cache = NULL; } if (priv->nlh) { diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h index a2b26e6b3..8b57a312d 100644 --- a/src/nm-netlink-monitor.h +++ b/src/nm-netlink-monitor.h @@ -26,6 +26,7 @@ #include #include #include +#include #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)) @@ -89,4 +90,10 @@ gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor guint32 *ifflags, GError **error); +/* 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 */ diff --git a/src/nm-netlink.c b/src/nm-netlink.c deleted file mode 100644 index 15eb6c1c3..000000000 --- a/src/nm-netlink.c +++ /dev/null @@ -1,150 +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 -#include -#include -#include -#include -#include - -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); -} - diff --git a/src/nm-netlink.h b/src/nm-netlink.h deleted file mode 100644 index b77cbf566..000000000 --- a/src/nm-netlink.h +++ /dev/null @@ -1,33 +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 -#include - -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 */ diff --git a/src/nm-system.c b/src/nm-system.c index bd5f57f51..0d38ea6cf 100644 --- a/src/nm-system.c +++ b/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 diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index a594df59b..a714e991e 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -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"