From 88cd34feef843ef5f47e5e82b942aa58d806954b Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 12:50:54 -0500 Subject: core: remove unused includes --- src/NetworkManagerUtils.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/NetworkManagerUtils.c b/src/NetworkManagerUtils.c index f96f2aadb1..451de6d003 100644 --- a/src/NetworkManagerUtils.c +++ b/src/NetworkManagerUtils.c @@ -26,6 +26,7 @@ #include #include #include +#include #include "NetworkManagerUtils.h" #include "nm-utils.h" @@ -43,9 +44,6 @@ #include "nm-setting-wireless-security.h" #include "nm-manager-auth.h" -#include -#include - /* * nm_ethernet_address_is_valid * -- cgit v1.2.3 From d2d1f2e9e0ac5b27d93d466460aeea4f86fcd42d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 13:37:29 -0500 Subject: core: use interface indexes more --- src/backends/NetworkManagerGeneric.c | 4 +- src/modem-manager/nm-modem.c | 12 ++-- src/nm-device-ethernet.c | 4 +- src/nm-device-olpc-mesh.c | 4 +- src/nm-device-wifi.c | 6 +- src/nm-device.c | 9 ++- src/nm-system.c | 123 ++++++++++++----------------------- src/nm-system.h | 15 ++--- src/vpn-manager/nm-vpn-connection.c | 19 ++++-- src/wimax/nm-device-wimax.c | 4 +- 10 files changed, 82 insertions(+), 118 deletions(-) diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 8f16066fa3..90a41bba97 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -57,8 +57,6 @@ void nm_generic_enable_loopback (void) int iface_idx = -1; int err; - nm_system_device_set_up_down_with_iface ("lo", TRUE, NULL); - nlh = nm_netlink_get_default_handle (); if (!nlh) return; @@ -67,6 +65,8 @@ void nm_generic_enable_loopback (void) if (iface_idx < 0) return; + nm_system_iface_set_up (iface_idx, TRUE, NULL); + addr = rtnl_addr_alloc (); if (!addr) return; diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 33f10789ce..3a27a17ff7 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -629,7 +629,7 @@ static void real_deactivate (NMModem *self, NMDevice *device) { NMModemPrivate *priv; - const char *iface; + int ifindex; g_return_if_fail (self != NULL); g_return_if_fail (NM_IS_MODEM (self)); @@ -668,11 +668,11 @@ real_deactivate (NMModem *self, NMDevice *device) break; case MM_MODEM_IP_METHOD_STATIC: case MM_MODEM_IP_METHOD_DHCP: - iface = nm_device_get_ip_iface (device); + ifindex = nm_device_get_ip_ifindex (device); /* FIXME: use AF_UNSPEC here when we have IPv6 support */ - nm_system_device_flush_routes_with_iface (iface, AF_INET); - nm_system_device_flush_addresses_with_iface (iface); - nm_system_device_set_up_down_with_iface (iface, FALSE, NULL); + nm_system_iface_flush_routes (ifindex, AF_INET); + nm_system_iface_flush_addresses (ifindex, AF_UNSPEC); + nm_system_iface_set_up (ifindex, FALSE, NULL); break; default: nm_log_err (LOGD_MB, "unknown IP method %d", priv->ip_method); @@ -781,7 +781,7 @@ nm_modem_hw_bring_up (NMModem *self, NMDevice *device, gboolean *no_firmware) state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); if (priv->pending_ip4_config || _state_is_active (state)) - return nm_system_device_set_up_down (device, TRUE, no_firmware); + return nm_system_iface_set_up (nm_device_get_ip_ifindex (device), TRUE, no_firmware); } return TRUE; diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 35b7367050..1e5ea0fbfb 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -552,13 +552,13 @@ real_hw_is_up (NMDevice *device) static gboolean real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) { - return nm_system_device_set_up_down (dev, TRUE, no_firmware); + return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); } static void real_hw_take_down (NMDevice *dev) { - nm_system_device_set_up_down (dev, FALSE, NULL); + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); } NMDevice * diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 8832234427..2125db4102 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -277,13 +277,13 @@ real_hw_is_up (NMDevice *device) static gboolean real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) { - return nm_system_device_set_up_down (dev, TRUE, no_firmware); + return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); } static void real_hw_take_down (NMDevice *dev) { - nm_system_device_set_up_down (dev, FALSE, NULL); + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); } static gboolean diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index 278d9a0631..b70a575983 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1142,13 +1142,13 @@ real_hw_bring_up (NMDevice *device, gboolean *no_firmware) if (!NM_DEVICE_WIFI_GET_PRIVATE (device)->enabled) return FALSE; - return nm_system_device_set_up_down (device, TRUE, no_firmware); + return nm_system_iface_set_up (nm_device_get_ip_ifindex (device), TRUE, no_firmware); } static void -real_hw_take_down (NMDevice *dev) +real_hw_take_down (NMDevice *device) { - nm_system_device_set_up_down (dev, FALSE, NULL); + nm_system_iface_set_up (nm_device_get_ip_ifindex (device), FALSE, NULL); } static gboolean diff --git a/src/nm-device.c b/src/nm-device.c index 1301197acf..04727b85aa 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -1600,7 +1600,7 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) /* Make sure the interface is up before trying to do anything with it */ if (!nm_system_device_is_up_with_iface (ip_iface)) - nm_system_device_set_up_down_with_iface (ip_iface, TRUE, NULL); + nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL); req = nm_device_get_act_request (self); connection = nm_act_request_get_connection (req); @@ -2820,6 +2820,7 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) NMDevicePrivate *priv = NM_DEVICE_GET_PRIVATE (self); NMDeviceStateReason ignored = NM_DEVICE_STATE_REASON_NONE; gboolean tried_ipv6 = FALSE; + int ifindex, family; g_return_if_fail (self != NULL); @@ -2857,8 +2858,10 @@ nm_device_deactivate (NMDeviceInterface *device, NMDeviceStateReason reason) clear_act_request (self); /* Take out any entries in the routing table and any IP address the device had. */ - nm_system_device_flush_routes (self, tried_ipv6 ? AF_UNSPEC : AF_INET); - nm_system_device_flush_addresses (self, tried_ipv6 ? AF_UNSPEC : AF_INET); + ifindex = nm_device_get_ip_ifindex (self); + family = tried_ipv6 ? AF_UNSPEC : AF_INET; + nm_system_iface_flush_routes (ifindex, family); + nm_system_iface_flush_addresses (ifindex, family); nm_device_update_ip4_address (self); /* Clean up nameservers and addresses */ diff --git a/src/nm-system.c b/src/nm-system.c index 88db65964a..017e57abe0 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -659,46 +659,39 @@ nm_system_apply_ip6_config (const char *iface, return TRUE; } -/* - * nm_system_device_set_up_down +/** + * nm_system_iface_set_up: + * @ifindex: interface index + * @up: %TRUE to bring interface up, or %FALSE to take it down + * @no_firmware: on return, %TRUE if the operation may have failed due to + * missing firmware * - * Mark the device as up or down. + * Bring the interface up or take it down. * - */ -gboolean -nm_system_device_set_up_down (NMDevice *dev, - gboolean up, - gboolean *no_firmware) -{ - g_return_val_if_fail (dev != NULL, FALSE); - - return nm_system_device_set_up_down_with_iface (nm_device_get_ip_iface (dev), up, no_firmware); -} - + * Returns: %TRUE on success, %FALSE on failure + **/ gboolean -nm_system_device_set_up_down_with_iface (const char *iface, - gboolean up, - gboolean *no_firmware) +nm_system_iface_set_up (int ifindex, + gboolean up, + gboolean *no_firmware) { struct rtnl_link *request = NULL, *old = NULL; struct nl_handle *nlh; gboolean success = FALSE; - guint32 idx; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); if (no_firmware) g_return_val_if_fail (*no_firmware == FALSE, FALSE); if (!(request = rtnl_link_alloc ())) - goto out; + return FALSE; if (up) rtnl_link_set_flags (request, IFF_UP); else rtnl_link_unset_flags (request, IFF_UP); - idx = nm_netlink_iface_to_index (iface); - old = nm_netlink_index_to_rtnl_link (idx); + old = nm_netlink_index_to_rtnl_link (ifindex); if (old) { nlh = nm_netlink_get_default_handle (); if (nlh) { @@ -711,8 +704,6 @@ nm_system_device_set_up_down_with_iface (const char *iface, rtnl_link_put (old); rtnl_link_put (request); - -out: return success; } @@ -1187,39 +1178,21 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g return success; } -static void flush_addresses (const char *iface, int family) -{ - int iface_idx; - - g_return_if_fail (iface != NULL); - iface_idx = nm_netlink_iface_to_index (iface); - if (iface_idx >= 0) - sync_addresses (iface, iface_idx, family, NULL, 0); -} - /* - * nm_system_device_flush_addresses + * nm_system_iface_flush_addresses * * Flush all network addresses associated with a network device * */ -void nm_system_device_flush_addresses (NMDevice *dev, int family) +gboolean +nm_system_iface_flush_addresses (int ifindex, int family) { - g_return_if_fail (dev != NULL); - - flush_addresses (nm_device_get_ip_iface (dev), family); -} + const char *iface; + g_return_val_if_fail (ifindex > 0, FALSE); -/* - * nm_system_device_flush_addresses_with_iface - * - * Flush all network addresses associated with a network device - * - */ -void nm_system_device_flush_addresses_with_iface (const char *iface) -{ - flush_addresses (iface, AF_UNSPEC); + iface = nm_netlink_index_to_iface (ifindex); + return iface ? sync_addresses (iface, ifindex, family, NULL, 0) : FALSE; } @@ -1335,20 +1308,29 @@ check_one_route (struct nl_object *object, void *user_data) } } -static void flush_routes (int ifindex, const char *iface, int family) +/** + * nm_system_iface_flush_routes: + * @ifindex: interface index + * @family: address family, i.e. AF_INET, AF_INET6, or AF_UNSPEC + * + * Flush all network addresses associated with a network device. + * + * Returns: %TRUE on success, %FALSE on failure + **/ +gboolean +nm_system_iface_flush_routes (int ifindex, int family) { RouteCheckData check_data; guint32 log_level = LOGD_IP4 | LOGD_IP6; const char *sf = "UNSPEC"; + const char *iface; - g_return_if_fail (iface != NULL); + g_return_val_if_fail (ifindex > 0, FALSE); - if (ifindex < 0) { - ifindex = nm_netlink_iface_to_index (iface); - if (ifindex < 0) { - nm_log_dbg (LOGD_DEVICE, "(%s) failed to lookup interface index", iface); - return; - } + iface = nm_netlink_index_to_iface (ifindex); + if (iface < 0) { + nm_log_warn (LOGD_DEVICE, "(%d) failed to lookup interface name", ifindex); + return FALSE; } if (family == AF_INET) { @@ -1366,33 +1348,8 @@ static void flush_routes (int ifindex, const char *iface, int family) check_data.iface_idx = ifindex; check_data.family = family; foreach_route (check_one_route, &check_data); -} -/* - * nm_system_device_flush_routes - * - * Flush all network addresses associated with a network device - * - */ -void nm_system_device_flush_routes (NMDevice *dev, int family) -{ - g_return_if_fail (dev != NULL); - - flush_routes (nm_device_get_ip_ifindex (dev), - nm_device_get_ip_iface (dev), - family); -} - -/* - * nm_system_device_flush_routes_with_iface - * - * Flush all routes associated with a network device. 'family' is an - * address family, either AF_INET, AF_INET6, or AF_UNSPEC. - * - */ -void nm_system_device_flush_routes_with_iface (const char *iface, int family) -{ - flush_routes (-1, iface, family); + return TRUE; } typedef struct { diff --git a/src/nm-system.h b/src/nm-system.h index 094f40efb1..02e8d0e920 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -35,8 +35,7 @@ * implemented in the backend files in backends/ directory */ -void nm_system_device_flush_routes (NMDevice *dev, int family); -void nm_system_device_flush_routes_with_iface (const char *iface, int family); +gboolean nm_system_iface_flush_routes (int ifindex, int family); gboolean nm_system_replace_default_ip4_route (const char *iface, guint32 gw, @@ -55,8 +54,7 @@ gboolean nm_system_replace_default_ip4_route_vpn (const char *iface, struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config); -void nm_system_device_flush_addresses (NMDevice *dev, int family); -void nm_system_device_flush_addresses_with_iface (const char *iface); +gboolean nm_system_iface_flush_addresses (int ifindex, int family); void nm_system_enable_loopback (void); void nm_system_update_dns (void); @@ -81,12 +79,9 @@ gboolean nm_system_apply_ip6_config (const char *iface, int priority, NMIP6ConfigCompareFlags flags); -gboolean nm_system_device_set_up_down (NMDevice *dev, - gboolean up, - gboolean *no_firmware); -gboolean nm_system_device_set_up_down_with_iface (const char *iface, - gboolean up, - gboolean *no_firmware); +gboolean nm_system_iface_set_up (int ifindex, + gboolean up, + gboolean *no_firmware); gboolean nm_system_device_is_up (NMDevice *device); gboolean nm_system_device_is_up_with_iface (const char *iface); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 067b2dce3e..452498850f 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -86,6 +86,7 @@ typedef struct { NMIP4Config *ip4_config; guint32 ip4_internal_gw; char *ip_iface; + int ip_ifindex; char *banner; struct rtnl_route *gw_route; @@ -424,6 +425,13 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, goto error; } + /* Grab the interface index for address/routing operations */ + priv->ip_ifindex = nm_netlink_iface_to_index (priv->ip_iface); + if (!priv->ip_ifindex) { + nm_log_err (LOGD_VPN, "(%s): failed to look up VPN interface index", priv->ip_iface); + goto error; + } + addr = nm_ip4_address_new (); nm_ip4_address_set_prefix (addr, 24); /* default to class C */ @@ -529,7 +537,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, s_ip4 = NM_SETTING_IP4_CONFIG (nm_connection_get_setting (priv->connection, NM_TYPE_SETTING_IP4_CONFIG)); nm_utils_merge_ip4_config (config, s_ip4); - nm_system_device_set_up_down_with_iface (priv->ip_iface, TRUE, NULL); + nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL); if (nm_system_apply_ip4_config (priv->ip_iface, config, 0, NM_IP4_COMPARE_FLAG_ALL)) { NMDnsManager *dns_mgr; @@ -940,11 +948,11 @@ vpn_cleanup (NMVPNConnection *connection) { NMVPNConnectionPrivate *priv = NM_VPN_CONNECTION_GET_PRIVATE (connection); - if (priv->ip_iface) { - nm_system_device_set_up_down_with_iface (priv->ip_iface, FALSE, NULL); + if (priv->ip_ifindex) { + nm_system_iface_set_up (priv->ip_ifindex, FALSE, NULL); /* FIXME: use AF_UNSPEC here when we have IPv6 support */ - nm_system_device_flush_routes_with_iface (priv->ip_iface, AF_INET); - nm_system_device_flush_addresses_with_iface (priv->ip_iface); + nm_system_iface_flush_routes (priv->ip_ifindex, AF_INET); + nm_system_iface_flush_addresses (priv->ip_ifindex, AF_UNSPEC); } if (priv->ip4_config) { @@ -982,6 +990,7 @@ vpn_cleanup (NMVPNConnection *connection) g_free (priv->ip_iface); priv->ip_iface = NULL; + priv->ip_ifindex = 0; /* Clear out connection secrets to ensure that the settings service * gets asked for them next time the connection is activated. diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index 9dff503d81..cc38cc3ce1 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -401,13 +401,13 @@ real_hw_bring_up (NMDevice *dev, gboolean *no_firmware) if (!priv->enabled || !priv->wimaxd_enabled) return FALSE; - return nm_system_device_set_up_down (dev, TRUE, no_firmware); + return nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), TRUE, no_firmware); } static void real_hw_take_down (NMDevice *dev) { - nm_system_device_set_up_down (dev, FALSE, NULL); + nm_system_iface_set_up (nm_device_get_ip_ifindex (dev), FALSE, NULL); } static void -- cgit v1.2.3 From c742cc83fd4ab39963539f7610278c80fd712132 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 13:49:49 -0500 Subject: core: convert up/down check to netlink and use interface index not iface --- src/modem-manager/nm-modem.c | 2 +- src/nm-device-ethernet.c | 2 +- src/nm-device-olpc-mesh.c | 2 +- src/nm-device-wifi.c | 2 +- src/nm-device.c | 11 +++++------ src/nm-system.c | 42 ++++++++++++++++-------------------------- src/nm-system.h | 3 +-- src/wimax/nm-device-wimax.c | 2 +- 8 files changed, 27 insertions(+), 39 deletions(-) diff --git a/src/modem-manager/nm-modem.c b/src/modem-manager/nm-modem.c index 3a27a17ff7..00e46a130c 100644 --- a/src/modem-manager/nm-modem.c +++ b/src/modem-manager/nm-modem.c @@ -764,7 +764,7 @@ nm_modem_hw_is_up (NMModem *self, NMDevice *device) state = nm_device_interface_get_state (NM_DEVICE_INTERFACE (device)); if (priv->pending_ip4_config || _state_is_active (state)) - return nm_system_device_is_up (device); + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); } return TRUE; diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 1e5ea0fbfb..743e510bd3 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -546,7 +546,7 @@ real_take_down (NMDevice *dev) static gboolean real_hw_is_up (NMDevice *device) { - return nm_system_device_is_up (device); + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); } static gboolean diff --git a/src/nm-device-olpc-mesh.c b/src/nm-device-olpc-mesh.c index 2125db4102..ae14279b2d 100644 --- a/src/nm-device-olpc-mesh.c +++ b/src/nm-device-olpc-mesh.c @@ -271,7 +271,7 @@ error: static gboolean real_hw_is_up (NMDevice *device) { - return nm_system_device_is_up (device); + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); } static gboolean diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index b70a575983..a0466379d9 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1133,7 +1133,7 @@ out: static gboolean real_hw_is_up (NMDevice *device) { - return nm_system_device_is_up (device); + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); } static gboolean diff --git a/src/nm-device.c b/src/nm-device.c index 04727b85aa..496ec95ffe 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -1591,16 +1591,15 @@ real_act_stage3_ip4_config_start (NMDevice *self, NMDeviceStateReason *reason) NMSettingIP4Config *s_ip4; NMActRequest *req; NMActStageReturn ret = NM_ACT_STAGE_RETURN_SUCCESS; - const char *ip_iface, *method = NULL; + const char *method = NULL; + int ifindex; g_return_val_if_fail (reason != NULL, NM_ACT_STAGE_RETURN_FAILURE); - /* Use the IP interface (not the control interface) for IP stuff */ - ip_iface = nm_device_get_ip_iface (self); - /* Make sure the interface is up before trying to do anything with it */ - if (!nm_system_device_is_up_with_iface (ip_iface)) - nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL); + ifindex = nm_device_get_ip_ifindex (self); + if (!nm_system_iface_is_up (ifindex)) + nm_system_iface_set_up (ifindex, TRUE, NULL); req = nm_device_get_act_request (self); connection = nm_act_request_get_connection (req); diff --git a/src/nm-system.c b/src/nm-system.c index 017e57abe0..d3a5eb8a38 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -708,40 +708,30 @@ nm_system_iface_set_up (int ifindex, } gboolean -nm_system_device_is_up (NMDevice *device) +nm_system_iface_is_up (int ifindex) { - g_return_val_if_fail (device != NULL, FALSE); - - return nm_system_device_is_up_with_iface (nm_device_get_ip_iface (device)); -} + const char *iface; + struct rtnl_link *l; + guint32 flags; -gboolean -nm_system_device_is_up_with_iface (const char *iface) -{ - struct ifreq ifr; - int fd; - gboolean up = FALSE; + g_return_val_if_fail (ifindex > 0, FALSE); - fd = socket (PF_INET, SOCK_DGRAM, 0); - if (fd < 0) { - nm_log_err (LOGD_HW, "couldn't open control socket."); + iface = nm_netlink_index_to_iface (ifindex); + if (iface == NULL) { + nm_log_err (LOGD_HW, "failed to get interface name for index %d", ifindex); return FALSE; } - /* Get device's flags */ - memset (&ifr, 0, sizeof (ifr)); - strncpy (ifr.ifr_name, iface, IFNAMSIZ); - if (ioctl (fd, SIOCGIFFLAGS, &ifr) < 0) { - if (errno != ENODEV) { - nm_log_err (LOGD_HW, "(%s): could not get flags: errno %d", - iface, errno); - } - } else { - up = !!(ifr.ifr_flags & IFF_UP); + l = nm_netlink_index_to_rtnl_link (ifindex); + if (l == NULL) { + nm_log_err (LOGD_HW, "(%s): failed to get interface link object", iface); + return FALSE; } - close (fd); - return up; + flags = rtnl_link_get_flags (l); + rtnl_link_put (l); + + return flags & IFF_UP; } gboolean diff --git a/src/nm-system.h b/src/nm-system.h index 02e8d0e920..9ed5d63aa7 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -83,8 +83,7 @@ gboolean nm_system_iface_set_up (int ifindex, gboolean up, gboolean *no_firmware); -gboolean nm_system_device_is_up (NMDevice *device); -gboolean nm_system_device_is_up_with_iface (const char *iface); +gboolean nm_system_iface_is_up (int ifindex); gboolean nm_system_device_set_mtu (const char *iface, guint32 mtu); gboolean nm_system_device_set_mac (const char *iface, const struct ether_addr *mac); diff --git a/src/wimax/nm-device-wimax.c b/src/wimax/nm-device-wimax.c index cc38cc3ce1..dc770476ca 100644 --- a/src/wimax/nm-device-wimax.c +++ b/src/wimax/nm-device-wimax.c @@ -390,7 +390,7 @@ real_take_down (NMDevice *device) static gboolean real_hw_is_up (NMDevice *device) { - return nm_system_device_is_up (device); + return nm_system_iface_is_up (nm_device_get_ip_ifindex (device)); } static gboolean -- cgit v1.2.3 From efb5735ad1ec7dc4d98da0a3eb1db9438e950bd1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 14:09:16 -0500 Subject: core: more conversion to ifindex instead of iface --- src/nm-device-ethernet.c | 2 +- src/nm-device-wifi.c | 2 +- src/nm-device.c | 7 +- src/nm-system.c | 136 ++++++++++++++++++++++-------------- src/nm-system.h | 7 +- src/vpn-manager/nm-vpn-connection.c | 4 +- 6 files changed, 98 insertions(+), 60 deletions(-) diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 743e510bd3..4de0d76b98 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -677,7 +677,7 @@ _set_hw_addr (NMDeviceEthernet *self, const guint8 *addr, const char *detail) /* Can't change MAC address while device is up */ real_hw_take_down (dev); - success = nm_system_device_set_mac (iface, (struct ether_addr *) addr); + success = nm_system_iface_set_mac (nm_device_get_ip_ifindex (dev), (struct ether_addr *) addr); if (success) { /* MAC address succesfully changed; update the current MAC to match */ _update_hw_addr (self, addr); diff --git a/src/nm-device-wifi.c b/src/nm-device-wifi.c index a0466379d9..6fac0d03a9 100644 --- a/src/nm-device-wifi.c +++ b/src/nm-device-wifi.c @@ -1209,7 +1209,7 @@ _set_hw_addr (NMDeviceWifi *self, const guint8 *addr, const char *detail) /* Can't change MAC address while device is up */ real_hw_take_down (dev); - success = nm_system_device_set_mac (iface, (struct ether_addr *) addr); + success = nm_system_iface_set_mac (nm_device_get_ip_ifindex (dev), (struct ether_addr *) addr); if (success) { /* MAC address succesfully changed; update the current MAC to match */ _update_hw_addr (self, addr); diff --git a/src/nm-device.c b/src/nm-device.c index 496ec95ffe..4a932a91f4 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3011,6 +3011,7 @@ nm_device_set_ip4_config (NMDevice *self, gboolean success = TRUE; NMIP4ConfigCompareFlags diff = NM_IP4_COMPARE_FLAG_ALL; NMDnsManager *dns_mgr; + int ip_ifindex; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (reason != NULL, FALSE); @@ -3041,8 +3042,10 @@ nm_device_set_ip4_config (NMDevice *self, /* Don't touch the device's actual IP config if the connection is * assumed when NM starts. */ - if (!assumed) - success = nm_system_apply_ip4_config (ip_iface, new_config, nm_device_get_priority (self), diff); + if (!assumed) { + ip_ifindex = nm_device_get_ip_ifindex (self); + success = nm_system_apply_ip4_config (ip_ifindex, new_config, nm_device_get_priority (self), diff); + } if (success || assumed) { /* Export over D-Bus */ diff --git a/src/nm-system.c b/src/nm-system.c index d3a5eb8a38..78c069a404 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -105,7 +105,7 @@ create_route (int iface_idx, int mss) } static struct rtnl_route * -nm_system_device_set_ip4_route (const char *iface, +nm_system_device_set_ip4_route (int ifindex, guint32 ip4_dest, guint32 ip4_prefix, guint32 ip4_gateway, @@ -116,15 +116,18 @@ nm_system_device_set_ip4_route (const char *iface, struct rtnl_route *route; struct nl_addr *dest_addr; struct nl_addr *gw_addr = NULL; - int err, iface_idx; + int err; + const char *iface; + + g_return_val_if_fail (ifindex > 0, NULL); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, NULL); - iface_idx = nm_netlink_iface_to_index (iface); - g_return_val_if_fail (iface_idx >= 0, NULL); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, NULL); - route = create_route (iface_idx, mss); + route = create_route (ifindex, mss); g_return_val_if_fail (route != NULL, NULL); /* Destination */ @@ -158,7 +161,7 @@ nm_system_device_set_ip4_route (const char *iface, /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; - route2 = create_route (iface_idx, mss); + route2 = create_route (ifindex, mss); if (route2) { /* Add route to gateway over bridge */ rtnl_route_set_dst (route2, gw_addr); @@ -188,8 +191,10 @@ nm_system_device_set_ip4_route (const char *iface, } static gboolean -sync_addresses (const char *iface, int ifindex, int family, - struct rtnl_addr **addrs, int num_addrs) +sync_addresses (int ifindex, + int family, + struct rtnl_addr **addrs, + int num_addrs) { struct nl_handle *nlh; struct nl_cache *addr_cache; @@ -199,6 +204,10 @@ sync_addresses (const char *iface, int ifindex, int family, int i, err; guint32 log_domain = (family == AF_INET) ? LOGD_IP4 : LOGD_IP6; char buf[INET6_ADDRSTRLEN + 1]; + const char *iface; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); log_domain |= LOGD_DEVICE; @@ -361,7 +370,7 @@ add_ip4_addresses (NMIP4Config *config, const char *iface) rtnl_addr_set_ifindex (addrs[i], iface_idx); } - return sync_addresses (iface, iface_idx, AF_INET, addrs, num_addrs); + return sync_addresses (iface_idx, AF_INET, addrs, num_addrs); } struct rtnl_route * @@ -406,10 +415,10 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_c * parent device. */ if (ip4_dest_in_same_subnet (parent_config, vpn_gw, parent_prefix)) { - route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device), + route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device), vpn_gw, 32, 0, 0, nm_ip4_config_get_mss (parent_config)); } else { - route = nm_system_device_set_ip4_route (nm_device_get_ip_iface (parent_device), + route = nm_system_device_set_ip4_route (nm_device_get_ip_ifindex (parent_device), vpn_gw, 32, parent_gw, 0, nm_ip4_config_get_mss (parent_config)); } @@ -423,16 +432,20 @@ nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_c * */ gboolean -nm_system_apply_ip4_config (const char *iface, +nm_system_apply_ip4_config (int ifindex, NMIP4Config *config, int priority, NMIP4ConfigCompareFlags flags) { + const char *iface; int i; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (config != NULL, FALSE); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + if (flags & NM_IP4_COMPARE_FLAG_ADDRESSES) { if (!add_ip4_addresses (config, iface)) return FALSE; @@ -459,7 +472,7 @@ nm_system_apply_ip4_config (const char *iface, && nm_ip4_route_get_dest (route) == 0) continue; - tmp = nm_system_device_set_ip4_route (iface, + tmp = nm_system_device_set_ip4_route (ifindex, nm_ip4_route_get_dest (route), nm_ip4_route_get_prefix (route), nm_ip4_route_get_next_hop (route), @@ -471,7 +484,7 @@ nm_system_apply_ip4_config (const char *iface, if (flags & NM_IP4_COMPARE_FLAG_MTU) { if (nm_ip4_config_get_mtu (config)) - nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config)); + nm_system_iface_set_mtu (ifindex, nm_ip4_config_get_mtu (config)); } if (priority > 0) @@ -595,7 +608,7 @@ add_ip6_addresses (NMIP6Config *config, const char *iface) rtnl_addr_set_ifindex (addrs[i], iface_idx); } - return sync_addresses (iface, iface_idx, AF_INET6, addrs, num_addrs); + return sync_addresses (iface_idx, AF_INET6, addrs, num_addrs); } /* @@ -707,6 +720,13 @@ nm_system_iface_set_up (int ifindex, return success; } +/** + * nm_system_iface_is_up: + * @ifindex: interface index + * + * Returns: %TRUE if the interface is up, %FALSE if it was down or the check + * failed. + **/ gboolean nm_system_iface_is_up (int ifindex) { @@ -717,10 +737,7 @@ nm_system_iface_is_up (int ifindex) g_return_val_if_fail (ifindex > 0, FALSE); iface = nm_netlink_index_to_iface (ifindex); - if (iface == NULL) { - nm_log_err (LOGD_HW, "failed to get interface name for index %d", ifindex); - return FALSE; - } + g_return_val_if_fail (iface != NULL, FALSE); l = nm_netlink_index_to_rtnl_link (ifindex); if (l == NULL) { @@ -734,72 +751,96 @@ nm_system_iface_is_up (int ifindex) return flags & IFF_UP; } +/** + * nm_system_iface_set_mtu: + * @ifindex: interface index + * @mtu: the new MTU + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ gboolean -nm_system_device_set_mtu (const char *iface, guint32 mtu) +nm_system_iface_set_mtu (int ifindex, guint32 mtu) { struct rtnl_link *old; struct rtnl_link *new; gboolean success = FALSE; struct nl_handle *nlh; - int iface_idx; + const char *iface; + int err; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (mtu > 0, FALSE); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + new = rtnl_link_alloc (); if (!new) return FALSE; - iface_idx = nm_netlink_iface_to_index (iface); - old = nm_netlink_index_to_rtnl_link (iface_idx); + old = nm_netlink_index_to_rtnl_link (ifindex); if (old) { rtnl_link_set_mtu (new, mtu); nlh = nm_netlink_get_default_handle (); if (nlh) { - rtnl_link_change (nlh, old, new, 0); - success = TRUE; + err = rtnl_link_change (nlh, old, new, 0); + if (err == 0) + success = TRUE; + else + nm_log_warn (LOGD_HW, "(%s): failed to change interface MTU", iface); } rtnl_link_put (old); } - rtnl_link_put (new); + return success; } +/** + * nm_system_iface_set_mac: + * @ifindex: interface index + * @mac: new MAC address + * + * Attempts to change the interface's MAC address to the requested value, + * ie MAC spoofing or cloning. + * + * Returns: %TRUE if the request succeeded, %FALSE if it failed. + **/ gboolean -nm_system_device_set_mac (const char *iface, const struct ether_addr *mac) +nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac) { - struct rtnl_link *old; - struct rtnl_link *new; + struct rtnl_link *old, *new; gboolean success = FALSE; struct nl_handle *nlh; - int iface_idx; + const char *iface; struct nl_addr *addr = NULL; + int err; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (mac != NULL, FALSE); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + new = rtnl_link_alloc (); if (!new) return FALSE; - iface_idx = nm_netlink_iface_to_index (iface); - old = nm_netlink_index_to_rtnl_link (iface_idx); + old = nm_netlink_index_to_rtnl_link (ifindex); if (old) { addr = nl_addr_build (AF_LLC, (void *) mac, ETH_ALEN); if (!addr) { - char *mac_str; - mac_str = g_strdup_printf ("%02X:%02X:%02X:%02X:%02X:%02X", mac->ether_addr_octet[0], mac->ether_addr_octet[1], mac->ether_addr_octet[2], - mac->ether_addr_octet[3], mac->ether_addr_octet[4], mac->ether_addr_octet[5]); - nm_log_err (LOGD_DEVICE, "(%s): could not allocate memory for MAC address (%s)", iface, mac_str); - g_free (mac_str); + nm_log_err (LOGD_HW, "(%s): failed to allocate memory for MAC address change", iface); return FALSE; } rtnl_link_set_addr (new, addr); nlh = nm_netlink_get_default_handle (); if (nlh) { - rtnl_link_change (nlh, old, new, 0); - success = TRUE; + err = rtnl_link_change (nlh, old, new, 0); + if (err == 0) + success = TRUE; + else + nm_log_warn (LOGD_HW, "(%s): failed to change interface MAC address", iface); } rtnl_link_put (old); } @@ -1177,12 +1218,8 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g gboolean nm_system_iface_flush_addresses (int ifindex, int family) { - const char *iface; - g_return_val_if_fail (ifindex > 0, FALSE); - - iface = nm_netlink_index_to_iface (ifindex); - return iface ? sync_addresses (iface, ifindex, family, NULL, 0) : FALSE; + return sync_addresses (ifindex, family, NULL, 0); } @@ -1318,10 +1355,7 @@ nm_system_iface_flush_routes (int ifindex, int family) g_return_val_if_fail (ifindex > 0, FALSE); iface = nm_netlink_index_to_iface (ifindex); - if (iface < 0) { - nm_log_warn (LOGD_DEVICE, "(%d) failed to lookup interface name", ifindex); - return FALSE; - } + g_return_val_if_fail (iface != NULL, FALSE); if (family == AF_INET) { log_level = LOGD_IP4; diff --git a/src/nm-system.h b/src/nm-system.h index 9ed5d63aa7..f5f7ea22a9 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -59,7 +59,7 @@ gboolean nm_system_iface_flush_addresses (int ifindex, int family void nm_system_enable_loopback (void); void nm_system_update_dns (void); -gboolean nm_system_apply_ip4_config (const char *iface, +gboolean nm_system_apply_ip4_config (int ifindex, NMIP4Config *config, int priority, NMIP4ConfigCompareFlags flags); @@ -85,7 +85,8 @@ gboolean nm_system_iface_set_up (int ifindex, gboolean nm_system_iface_is_up (int ifindex); -gboolean nm_system_device_set_mtu (const char *iface, guint32 mtu); -gboolean nm_system_device_set_mac (const char *iface, const struct ether_addr *mac); +gboolean nm_system_iface_set_mtu (int ifindex, guint32 mtu); + +gboolean nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac); #endif diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 452498850f..a7fb879e10 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -539,7 +539,7 @@ nm_vpn_connection_ip4_config_get (DBusGProxy *proxy, nm_system_iface_set_up (priv->ip_ifindex, TRUE, NULL); - if (nm_system_apply_ip4_config (priv->ip_iface, config, 0, NM_IP4_COMPARE_FLAG_ALL)) { + if (nm_system_apply_ip4_config (priv->ip_ifindex, config, 0, NM_IP4_COMPARE_FLAG_ALL)) { NMDnsManager *dns_mgr; /* Add any explicit route to the VPN gateway through the parent device */ @@ -971,7 +971,7 @@ vpn_cleanup (NMVPNConnection *connection) /* Reset routes and addresses of the currently active device */ parent_config = nm_device_get_ip4_config (priv->parent_dev); if (parent_config) { - if (!nm_system_apply_ip4_config (nm_device_get_ip_iface (priv->parent_dev), + if (!nm_system_apply_ip4_config (nm_device_get_ip_ifindex (priv->parent_dev), nm_device_get_ip4_config (priv->parent_dev), nm_device_get_priority (priv->parent_dev), NM_IP4_COMPARE_FLAG_ADDRESSES | NM_IP4_COMPARE_FLAG_ROUTES)) { -- cgit v1.2.3 From 2fabdbff15247e8725e33c08acf6d5aecdbeba2a Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 14:24:18 -0500 Subject: core: finish conversion of nm-system functions to ifindex not iface name --- src/nm-device.c | 4 +- src/nm-policy.c | 16 +++-- src/nm-system.c | 132 +++++++++++++++++++----------------- src/nm-system.h | 10 +-- src/vpn-manager/nm-vpn-connection.c | 8 +++ src/vpn-manager/nm-vpn-connection.h | 1 + 6 files changed, 98 insertions(+), 73 deletions(-) diff --git a/src/nm-device.c b/src/nm-device.c index 4a932a91f4..6a2db4804b 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -3117,12 +3117,14 @@ nm_device_set_ip6_config (NMDevice *self, gboolean success = TRUE; NMIP6ConfigCompareFlags diff = NM_IP6_COMPARE_FLAG_ALL; NMDnsManager *dns_mgr; + int ip_ifindex; g_return_val_if_fail (NM_IS_DEVICE (self), FALSE); g_return_val_if_fail (reason != NULL, FALSE); priv = NM_DEVICE_GET_PRIVATE (self); ip_iface = nm_device_get_ip_iface (self); + ip_ifindex = nm_device_get_ip_ifindex (self); old_config = priv->ip6_config; @@ -3148,7 +3150,7 @@ nm_device_set_ip6_config (NMDevice *self, * assumed when NM starts. */ if (!assumed) - success = nm_system_apply_ip6_config (ip_iface, new_config, nm_device_get_priority (self), diff); + success = nm_system_apply_ip6_config (ip_ifindex, new_config, nm_device_get_priority (self), diff); if (success || assumed) { /* Export over D-Bus */ diff --git a/src/nm-policy.c b/src/nm-policy.c index 20729fdc94..56c79f3d38 100644 --- a/src/nm-policy.c +++ b/src/nm-policy.c @@ -425,6 +425,7 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) NMConnection *connection = NULL; NMSettingConnection *s_con = NULL; const char *connection_id; + int ip_ifindex = 0; best = get_best_ip4_device (policy->manager, &best_req); if (!best) @@ -461,17 +462,18 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) NMDevice *parent; ip_iface = nm_vpn_connection_get_ip_iface (candidate); + ip_ifindex = nm_vpn_connection_get_ip_ifindex (candidate); connection = nm_vpn_connection_get_connection (candidate); addr = nm_ip4_config_get_address (ip4_config, 0); parent = nm_vpn_connection_get_parent_device (candidate); parent_ip4 = nm_device_get_ip4_config (parent); - nm_system_replace_default_ip4_route_vpn (ip_iface, + nm_system_replace_default_ip4_route_vpn (ip_ifindex, nm_ip4_address_get_gateway (addr), nm_vpn_connection_get_ip4_internal_gateway (candidate), nm_ip4_config_get_mss (ip4_config), - nm_device_get_ip_iface (parent), + nm_device_get_ip_ifindex (parent), nm_ip4_config_get_mss (parent_ip4)); dns_type = NM_DNS_IP_CONFIG_TYPE_VPN; @@ -483,12 +485,14 @@ update_ip4_routing_and_dns (NMPolicy *policy, gboolean force_update) if (!ip_iface || !ip4_config) { connection = nm_act_request_get_connection (best_req); ip_iface = nm_device_get_ip_iface (best); + ip_ifindex = nm_device_get_ip_ifindex (best); ip4_config = nm_device_get_ip4_config (best); g_assert (ip4_config); addr = nm_ip4_config_get_address (ip4_config, 0); - nm_system_replace_default_ip4_route (ip_iface, nm_ip4_address_get_gateway (addr), nm_ip4_config_get_mss (ip4_config)); - + nm_system_replace_default_ip4_route (ip_ifindex, + nm_ip4_address_get_gateway (addr), + nm_ip4_config_get_mss (ip4_config)); dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; } @@ -551,6 +555,7 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) NMIP6Config *ip6_config = NULL; NMIP6Address *addr; const char *ip_iface = NULL; + int ip_ifindex = -1; NMConnection *connection = NULL; NMSettingConnection *s_con = NULL; const char *connection_id; @@ -608,11 +613,12 @@ update_ip6_routing_and_dns (NMPolicy *policy, gboolean force_update) if (!ip_iface || !ip6_config) { connection = nm_act_request_get_connection (best_req); ip_iface = nm_device_get_ip_iface (best); + ip_ifindex = nm_device_get_ip_ifindex (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)); + nm_system_replace_default_ip6_route (ip_ifindex, nm_ip6_address_get_gateway (addr)); dns_type = NM_DNS_IP_CONFIG_TYPE_BEST_DEVICE; } diff --git a/src/nm-system.c b/src/nm-system.c index 78c069a404..144d0c4ee8 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -58,9 +58,9 @@ #include #include -static void nm_system_device_set_priority (const char *iface, - NMIP4Config *config, - int priority); +static void nm_system_device_set_priority (int ifindex, + NMIP4Config *config, + int priority); static gboolean ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix) @@ -488,7 +488,7 @@ nm_system_apply_ip4_config (int ifindex, } if (priority > 0) - nm_system_device_set_priority (iface, config, priority); + nm_system_device_set_priority (ifindex, config, priority); return TRUE; } @@ -618,16 +618,20 @@ add_ip6_addresses (NMIP6Config *config, const char *iface) * */ gboolean -nm_system_apply_ip6_config (const char *iface, +nm_system_apply_ip6_config (int ifindex, NMIP6Config *config, int priority, NMIP6ConfigCompareFlags flags) { + const char *iface; int i; - g_return_val_if_fail (iface != NULL, FALSE); + g_return_val_if_fail (ifindex > 0, FALSE); g_return_val_if_fail (config != NULL, FALSE); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + if (flags & NM_IP6_COMPARE_FLAG_ADDRESSES) { if (!add_ip6_addresses (config, iface)) return FALSE; @@ -635,8 +639,6 @@ nm_system_apply_ip6_config (const char *iface, } if (flags & NM_IP6_COMPARE_FLAG_ROUTES) { - int ifindex = nm_netlink_iface_to_index (iface); - for (i = 0; i < nm_ip6_config_get_num_routes (config); i++) { NMIP6Route *route = nm_ip6_config_get_route (config, i); int err; @@ -850,20 +852,20 @@ nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac) } static struct rtnl_route * -add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss) +add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) { struct nl_handle *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; - int iface_idx, err; + const char *iface; + int err; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); 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) @@ -871,7 +873,7 @@ add_ip4_route_to_gateway (const char *iface, guint32 gw, guint32 mss) rtnl_route_set_family (route, AF_INET); rtnl_route_set_table (route, RT_TABLE_MAIN); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); rtnl_route_set_scope (route, RT_SCOPE_LINK); gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw)); @@ -903,31 +905,27 @@ error: } static int -replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) +replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *route = NULL; struct nl_handle *nlh; struct nl_addr *dst_addr = NULL; guint32 dst = 0; struct nl_addr *gw_addr = NULL; - int iface_idx, err = -1; + int err = -1; - g_return_val_if_fail (iface != NULL, -ENODEV); + g_return_val_if_fail (ifindex > 0, -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_INET); rtnl_route_set_table (route, RT_TABLE_MAIN); rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - rtnl_route_set_oif (route, iface_idx); + rtnl_route_set_oif (route, ifindex); /* Build up the destination address */ dst_addr = nl_addr_build (AF_INET, &dst, sizeof (dst)); @@ -972,22 +970,26 @@ out: * */ gboolean -nm_system_replace_default_ip4_route_vpn (const char *iface, +nm_system_replace_default_ip4_route_vpn (int ifindex, guint32 ext_gw, guint32 int_gw, guint32 mss, - const char *parent_iface, + int parent_ifindex, guint32 parent_mss) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; int err; + const char *iface; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip4_route (iface, int_gw, mss); + err = replace_default_ip4_route (ifindex, int_gw, mss); if (err == 0) { return TRUE; } else if (err != -ESRCH) { @@ -998,12 +1000,12 @@ nm_system_replace_default_ip4_route_vpn (const char *iface, } /* Try adding a direct route to the gateway first */ - gw_route = add_ip4_route_to_gateway (parent_iface, ext_gw, parent_mss); + gw_route = add_ip4_route_to_gateway (parent_ifindex, ext_gw, parent_mss); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip4_route (iface, int_gw, mss); + err = replace_default_ip4_route (ifindex, int_gw, mss); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP4, @@ -1023,17 +1025,21 @@ nm_system_replace_default_ip4_route_vpn (const char *iface, * */ gboolean -nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) +nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; + const char *iface; int err; + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip4_route (iface, gw, mss); + err = replace_default_ip4_route (ifindex, gw, mss); if (err == 0) { return TRUE; } else if (err != -ESRCH) { @@ -1044,12 +1050,12 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) } /* Try adding a direct route to the gateway first */ - gw_route = add_ip4_route_to_gateway (iface, gw, mss); + gw_route = add_ip4_route_to_gateway (ifindex, gw, mss); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip4_route (iface, gw, mss); + err = replace_default_ip4_route (ifindex, gw, mss); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP4, @@ -1063,20 +1069,20 @@ nm_system_replace_default_ip4_route (const char *iface, guint32 gw, guint32 mss) } static struct rtnl_route * -add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw) +add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) { struct nl_handle *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; - int iface_idx, err; + const char *iface; + int err; + + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, NULL); 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) @@ -1084,7 +1090,7 @@ add_ip6_route_to_gateway (const char *iface, const struct in6_addr *gw) 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_oif (route, ifindex); rtnl_route_set_scope (route, RT_SCOPE_LINK); gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw)); @@ -1111,29 +1117,29 @@ error: } static int -replace_default_ip6_route (const char *iface, const struct in6_addr *gw) +replace_default_ip6_route (int ifindex, 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; + const char *iface; + int err = -1; + + g_return_val_if_fail (ifindex > 0, FALSE); - g_return_val_if_fail (iface != NULL, -ENODEV); + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); 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); + rtnl_route_set_oif (route, ifindex); if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) { /* Build up the gateway address */ @@ -1170,20 +1176,24 @@ out: * */ gboolean -nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *gw) +nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *gw_route = NULL; struct nl_handle *nlh; gboolean success = FALSE; + const char *iface; int err; + iface = nm_netlink_index_to_iface (ifindex); + g_return_val_if_fail (iface != NULL, FALSE); + nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip6_route (iface, gw); - if (err == 0) { + err = replace_default_ip6_route (ifindex, gw); + if (err == 0) return TRUE; - } else if (err != -ESRCH) { + if (err != -ESRCH) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 default route: %d", iface, err); @@ -1191,12 +1201,12 @@ nm_system_replace_default_ip6_route (const char *iface, const struct in6_addr *g } /* Try adding a direct route to the gateway first */ - gw_route = add_ip6_route_to_gateway (iface, gw); + gw_route = add_ip6_route_to_gateway (ifindex, gw); if (!gw_route) return FALSE; /* Try adding the original route again */ - err = replace_default_ip6_route (iface, gw); + err = replace_default_ip6_route (ifindex, gw); if (err != 0) { rtnl_route_del (nlh, gw_route, 0); nm_log_err (LOGD_DEVICE | LOGD_IP6, @@ -1379,7 +1389,7 @@ nm_system_iface_flush_routes (int ifindex, int family) typedef struct { struct rtnl_route *route; NMIP4Config *config; - int iface; + int ifindex; } SetPriorityInfo; static void @@ -1393,7 +1403,7 @@ find_route (struct nl_object *object, gpointer user_data) int i; if (info->route || - rtnl_route_get_oif (route) != info->iface || + rtnl_route_get_oif (route) != info->ifindex || rtnl_route_get_scope (route) != RT_SCOPE_LINK) return; @@ -1420,21 +1430,19 @@ find_route (struct nl_object *object, gpointer user_data) } static void -nm_system_device_set_priority (const char *iface, - NMIP4Config *config, - int priority) +nm_system_device_set_priority (int ifindex, + NMIP4Config *config, + int priority) { SetPriorityInfo info; + struct nl_handle *nlh; info.route = NULL; info.config = config; - info.iface = nm_netlink_iface_to_index (iface); - g_return_if_fail (info.iface >= 0); + info.ifindex = ifindex; foreach_route (find_route, &info); if (info.route) { - struct nl_handle *nlh; - nlh = nm_netlink_get_default_handle (); rtnl_route_del (nlh, info.route, 0); diff --git a/src/nm-system.h b/src/nm-system.h index f5f7ea22a9..ae4e7d91f8 100644 --- a/src/nm-system.h +++ b/src/nm-system.h @@ -37,18 +37,18 @@ gboolean nm_system_iface_flush_routes (int ifindex, int family); -gboolean nm_system_replace_default_ip4_route (const char *iface, +gboolean nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss); -gboolean nm_system_replace_default_ip6_route (const char *iface, +gboolean nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw); -gboolean nm_system_replace_default_ip4_route_vpn (const char *iface, +gboolean nm_system_replace_default_ip4_route_vpn (int ifindex, guint32 ext_gw, guint32 int_gw, guint32 mss, - const char *parent_iface, + int parent_ifindex, guint32 parent_mss); struct rtnl_route *nm_system_add_ip4_vpn_gateway_route (NMDevice *parent_device, NMIP4Config *vpn_config); @@ -74,7 +74,7 @@ int nm_system_set_ip6_route (int ifindex, int table, struct rtnl_route **out_route); -gboolean nm_system_apply_ip6_config (const char *iface, +gboolean nm_system_apply_ip6_config (int ifindex, NMIP6Config *config, int priority, NMIP6ConfigCompareFlags flags); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index a7fb879e10..3520f292d2 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -773,6 +773,14 @@ nm_vpn_connection_get_ip_iface (NMVPNConnection *connection) return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_iface; } +int +nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection) +{ + g_return_val_if_fail (NM_IS_VPN_CONNECTION (connection), -1); + + return NM_VPN_CONNECTION_GET_PRIVATE (connection)->ip_ifindex; +} + NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection) { diff --git a/src/vpn-manager/nm-vpn-connection.h b/src/vpn-manager/nm-vpn-connection.h index ee8eb5b6ea..daf9483c6b 100644 --- a/src/vpn-manager/nm-vpn-connection.h +++ b/src/vpn-manager/nm-vpn-connection.h @@ -72,6 +72,7 @@ void nm_vpn_connection_disconnect (NMVPNConnection *connect NMVPNConnectionStateReason reason); NMIP4Config * nm_vpn_connection_get_ip4_config (NMVPNConnection *connection); const char * nm_vpn_connection_get_ip_iface (NMVPNConnection *connection); +int nm_vpn_connection_get_ip_ifindex (NMVPNConnection *connection); NMDevice * nm_vpn_connection_get_parent_device (NMVPNConnection *connection); guint32 nm_vpn_connection_get_ip4_internal_gateway (NMVPNConnection *connection); -- cgit v1.2.3 From 3a86b5ae34fe754e02fa7fed000dde9775c5da45 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 15:28:35 -0500 Subject: core: move address checking functionality into separate file Start to consolidate netlink stuff so we can eventually keep all the API changes for libnl1 vs. libnl3 in fewer places. --- src/Makefile.am | 2 + src/nm-device-ethernet.c | 88 +++++++---------------------------- src/nm-netlink-utils.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++ src/nm-netlink-utils.h | 31 ++++++++++++ 4 files changed, 169 insertions(+), 71 deletions(-) create mode 100644 src/nm-netlink-utils.c create mode 100644 src/nm-netlink-utils.h diff --git a/src/Makefile.am b/src/Makefile.am index 94e1a8c0c1..11529a7b96 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -159,6 +159,8 @@ NetworkManager_SOURCES = \ nm-manager-auth.h \ nm-netlink-monitor.c \ nm-netlink-monitor.h \ + nm-netlink-utils.c \ + nm-netlink-utils.h \ nm-activation-request.c \ nm-activation-request.h \ nm-properties-changed-signal.c \ diff --git a/src/nm-device-ethernet.c b/src/nm-device-ethernet.c index 4de0d76b98..8556c5bd5c 100644 --- a/src/nm-device-ethernet.c +++ b/src/nm-device-ethernet.c @@ -59,6 +59,7 @@ #include "nm-logging.h" #include "nm-properties-changed-signal.h" #include "nm-dhcp-manager.h" +#include "nm-netlink-utils.h" #include "nm-device-ethernet-glue.h" @@ -1796,73 +1797,19 @@ wired_match_config (NMDevice *self, NMConnection *connection) return TRUE; } -typedef struct { - int ifindex; - NMIP4Address *addr; - gboolean found; -} AddrData; - -static void -check_one_address (struct nl_object *object, void *user_data) -{ - AddrData *data = user_data; - struct rtnl_addr *addr = (struct rtnl_addr *) object; - struct nl_addr *local; - struct in_addr tmp; - - if (rtnl_addr_get_ifindex (addr) != data->ifindex) - return; - if (rtnl_addr_get_family (addr) != AF_INET) - return; - - if (nm_ip4_address_get_prefix (data->addr) != rtnl_addr_get_prefixlen (addr)) - return; - - local = rtnl_addr_get_local (addr); - if (nl_addr_get_family (local) != AF_INET) - return; - if (nl_addr_get_len (local) != sizeof (struct in_addr)) - return; - if (!nl_addr_get_binary_addr (local)) - return; - - memcpy (&tmp, nl_addr_get_binary_addr (local), nl_addr_get_len (local)); - if (tmp.s_addr != nm_ip4_address_get_address (data->addr)) - return; - - /* Yay, found it */ - data->found = TRUE; -} - static gboolean ip4_match_config (NMDevice *self, NMConnection *connection) { NMSettingIP4Config *s_ip4; - struct nl_handle *nlh = NULL; - struct nl_cache *addr_cache = NULL; int i, num; GSList *leases, *iter; NMDHCPManager *dhcp_mgr; const char *method; - int ifindex; - AddrData check_data; - - ifindex = nm_device_get_ifindex (self); - s_ip4 = (NMSettingIP4Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP4_CONFIG); + s_ip4 = nm_connection_get_setting_ip4_config (connection); if (!s_ip4) return FALSE; - /* Read all the device's IP addresses */ - nlh = nm_netlink_get_default_handle (); - if (!nlh) - return FALSE; - - addr_cache = rtnl_addr_alloc_cache (nlh); - if (!addr_cache) - return FALSE; - nl_cache_mngt_provide (addr_cache); - /* Get any saved leases that apply to this connection */ dhcp_mgr = nm_dhcp_manager_get (); leases = nm_dhcp_manager_get_lease_config (dhcp_mgr, @@ -1876,15 +1823,14 @@ ip4_match_config (NMDevice *self, NMConnection *connection) /* Find at least one lease's address on the device */ for (iter = leases; iter; iter = g_slist_next (iter)) { - NMIP4Config *addr = iter->data; - - memset (&check_data, 0, sizeof (check_data)); - check_data.ifindex = ifindex; - check_data.found = FALSE; - check_data.addr = nm_ip4_config_get_address (addr, 0); - - nl_cache_foreach (addr_cache, check_one_address, &check_data); - if (check_data.found) { + NMIP4Config *ip4_config = iter->data; + NMIP4Address *addr = nm_ip4_config_get_address (ip4_config, 0); + struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; + + if (addr && nm_netlink_find_address (nm_device_get_ip_ifindex (self), + AF_INET, + &tmp, + nm_ip4_address_get_prefix (addr))) { found = TRUE; /* Yay, device has same address as a lease */ break; } @@ -1908,16 +1854,16 @@ ip4_match_config (NMDevice *self, NMConnection *connection) /* Everything below for static addressing */ - /* Find all IP4 addresses of this connection in the device's address list */ + /* Find all IP4 addresses of this connection on the device */ num = nm_setting_ip4_config_get_num_addresses (s_ip4); for (i = 0; i < num; i++) { - memset (&check_data, 0, sizeof (check_data)); - check_data.ifindex = ifindex; - check_data.found = FALSE; - check_data.addr = nm_setting_ip4_config_get_address (s_ip4, i); + NMIP4Address *addr = nm_setting_ip4_config_get_address (s_ip4, i); + struct in_addr tmp = { .s_addr = nm_ip4_address_get_address (addr) }; - nl_cache_foreach (addr_cache, check_one_address, &check_data); - if (!check_data.found) + if (!nm_netlink_find_address (nm_device_get_ip_ifindex (self), + AF_INET, + &tmp, + nm_ip4_address_get_prefix (addr))) return FALSE; } diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c new file mode 100644 index 0000000000..a0e998315b --- /dev/null +++ b/src/nm-netlink-utils.c @@ -0,0 +1,119 @@ +/* -*- 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) 2011 Red Hat, Inc. + */ + +#include "nm-netlink-utils.h" +#include "nm-netlink-monitor.h" + +#include +#include +#include +#include + +typedef struct { + int ifindex; + int family; + void *addr; + int addrlen; + int prefix; + gboolean found; +} FindAddrInfo; + +static void +find_one_address (struct nl_object *object, void *user_data) +{ + FindAddrInfo *info = user_data; + struct rtnl_addr *addr = (struct rtnl_addr *) object; + struct nl_addr *local; + void *binaddr; + + if (info->found) + return; + + if (rtnl_addr_get_ifindex (addr) != info->ifindex) + return; + if (rtnl_addr_get_family (addr) != info->family) + return; + + if (rtnl_addr_get_prefixlen (addr) != info->prefix) + return; + + local = rtnl_addr_get_local (addr); + if (nl_addr_get_family (local) != info->family) + return; + if (nl_addr_get_len (local) != info->addrlen) + return; + binaddr = nl_addr_get_binary_addr (local); + if (binaddr) { + if (memcmp (binaddr, info->addr, info->addrlen) == 0) + info->found = TRUE; /* Yay, found it */ + } +} + +/** + * nm_netlink_find_address: + * @ifindex: interface index + * @family: address family, either AF_INET or AF_INET6 + * @addr: binary address, either struct in_addr* or struct in6_addr* + * @prefix: prefix length + * + * Searches for a matching address on the given interface. + * + * Returns: %TRUE if the given address was found on the interface, %FALSE if it + * was not found or an error occurred. + **/ +gboolean +nm_netlink_find_address (int ifindex, + int family, + void *addr, /* struct in_addr or struct in6_addr */ + int prefix) +{ + struct nl_handle *nlh = NULL; + struct nl_cache *cache = NULL; + FindAddrInfo info; + + g_return_val_if_fail (ifindex > 0, FALSE); + g_return_val_if_fail (family == AF_INET || family == AF_INET6, FALSE); + g_return_val_if_fail (addr != NULL, FALSE); + g_return_val_if_fail (prefix >= 0, FALSE); + + memset (&info, 0, sizeof (info)); + info.ifindex = ifindex; + info.family = family; + info.prefix = prefix; + info.addr = addr; + if (family == AF_INET) + info.addrlen = sizeof (struct in_addr); + else if (family == AF_INET6) + info.addrlen = sizeof (struct in6_addr); + else + g_assert_not_reached (); + + nlh = nm_netlink_get_default_handle (); + if (nlh) { + cache = rtnl_addr_alloc_cache (nlh); + if (cache) { + nl_cache_mngt_provide (cache); + nl_cache_foreach (cache, find_one_address, &info); + nl_cache_free (cache); + } + } + return info.found; +} + diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h new file mode 100644 index 0000000000..0e74470b6a --- /dev/null +++ b/src/nm-netlink-utils.h @@ -0,0 +1,31 @@ +/* -*- 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) 2011 Red Hat, Inc. + */ + +#ifndef NM_NETLINK_UTILS_H +#define NM_NETLINK_UTILS_H + +#include + +gboolean nm_netlink_find_address (int ifindex, + int family, + void *addr, /* struct in_addr or struct in6_addr */ + int prefix_); + +#endif /* NM_NETLINK_MONITOR_H */ -- cgit v1.2.3 From 8b075fcdf224dc8ca4ef65cbd387be655bf0e19c Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 16:12:44 -0500 Subject: core: move route deletion to nm-netlink-utils.c --- src/nm-netlink-utils.c | 19 +++++++++++++++++++ src/nm-netlink-utils.h | 4 ++++ src/nm-system.c | 27 ++++++++++----------------- src/vpn-manager/nm-vpn-connection.c | 3 ++- 4 files changed, 35 insertions(+), 18 deletions(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index a0e998315b..3e855b42df 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -117,3 +117,22 @@ nm_netlink_find_address (int ifindex, return info.found; } +/** + * nm_netlink_route_delete: + * @route: the route to delete + * + * Returns: %TRUE if the request was successful, %FALSE if it failed + **/ +gboolean +nm_netlink_route_delete (struct rtnl_route *route) +{ + struct nl_handle *nlh; + int err; + + g_return_val_if_fail (route != NULL, FALSE); + + nlh = nm_netlink_get_default_handle (); + err = rtnl_route_del (nlh, route, 0); + return err == 0 ? TRUE : FALSE; +} + diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index 0e74470b6a..b85b98ad62 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -22,10 +22,14 @@ #define NM_NETLINK_UTILS_H #include +#include +#include gboolean nm_netlink_find_address (int ifindex, int family, void *addr, /* struct in_addr or struct in6_addr */ int prefix_); +gboolean nm_netlink_route_delete (struct rtnl_route *route); + #endif /* NM_NETLINK_MONITOR_H */ diff --git a/src/nm-system.c b/src/nm-system.c index 144d0c4ee8..032990aad3 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -48,9 +48,7 @@ #include "nm-utils.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 +#include "nm-netlink-utils.h" #include #include @@ -170,7 +168,7 @@ nm_system_device_set_ip4_route (int ifindex, /* Try adding the route again */ err = rtnl_route_add (nlh, route, 0); if (err) - rtnl_route_del (nlh, route2, 0); + nm_netlink_route_delete (route2); } rtnl_route_put (route2); } @@ -564,7 +562,7 @@ nm_system_set_ip6_route (int ifindex, /* Try adding the route again */ err = rtnl_route_add (nlh, route, 0); if (err) - rtnl_route_del (nlh, route2, 0); + nm_netlink_route_delete (route2); } rtnl_route_put (route2); } @@ -1007,7 +1005,7 @@ nm_system_replace_default_ip4_route_vpn (int ifindex, /* Try adding the original route again */ err = replace_default_ip4_route (ifindex, int_gw, mss); if (err != 0) { - rtnl_route_del (nlh, gw_route, 0); + nm_netlink_route_delete (gw_route); nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 default route (pass #2): %d", iface, err); @@ -1057,7 +1055,7 @@ nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) /* Try adding the original route again */ err = replace_default_ip4_route (ifindex, gw, mss); if (err != 0) { - rtnl_route_del (nlh, gw_route, 0); + nm_netlink_route_delete (gw_route); nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 default route (pass #2): %d", iface, err); @@ -1208,7 +1206,7 @@ nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) /* Try adding the original route again */ err = replace_default_ip6_route (ifindex, gw); if (err != 0) { - rtnl_route_del (nlh, gw_route, 0); + nm_netlink_route_delete (gw_route); nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 default route (pass #2): %d", iface, err); @@ -1298,7 +1296,6 @@ check_one_route (struct nl_object *object, void *user_data) { RouteCheckData *data = (RouteCheckData *) user_data; struct rtnl_route *route = (struct rtnl_route *) object; - int err; guint32 log_level = LOGD_IP4 | LOGD_IP6; if (nm_logging_level_enabled (LOGL_DEBUG)) @@ -1337,12 +1334,8 @@ check_one_route (struct nl_object *object, void *user_data) log_level = LOGD_IP6; nm_log_dbg (log_level, " deleting route"); - err = rtnl_route_del (nm_netlink_get_default_handle (), route, 0); - if (err < 0 && (err != -ERANGE)) { - nm_log_err (LOGD_DEVICE, - "(%s): error %d returned from rtnl_route_del(): %s", - data->iface, err, nl_geterror ()); - } + if (!nm_netlink_route_delete (route)) + nm_log_err (LOGD_DEVICE, "(%s): failed to delete route", data->iface); } /** @@ -1443,9 +1436,9 @@ nm_system_device_set_priority (int ifindex, foreach_route (find_route, &info); if (info.route) { - nlh = nm_netlink_get_default_handle (); - rtnl_route_del (nlh, info.route, 0); + nm_netlink_route_delete (info.route); + nlh = nm_netlink_get_default_handle (); rtnl_route_set_prio (info.route, priority); rtnl_route_add (nlh, info.route, 0); rtnl_route_put (info.route); diff --git a/src/vpn-manager/nm-vpn-connection.c b/src/vpn-manager/nm-vpn-connection.c index 3520f292d2..75ba645128 100644 --- a/src/vpn-manager/nm-vpn-connection.c +++ b/src/vpn-manager/nm-vpn-connection.c @@ -46,6 +46,7 @@ #include "NetworkManagerUtils.h" #include "nm-dns-manager.h" #include "nm-netlink-monitor.h" +#include "nm-netlink-utils.h" #include "nm-glib-compat.h" #include "settings/nm-settings-connection.h" @@ -974,7 +975,7 @@ vpn_cleanup (NMVPNConnection *connection) /* Remove any previously added VPN gateway host route */ if (priv->gw_route) - rtnl_route_del (nm_netlink_get_default_handle (), priv->gw_route, 0); + nm_netlink_route_delete (priv->gw_route); /* Reset routes and addresses of the currently active device */ parent_config = nm_device_get_ip4_config (priv->parent_dev); -- cgit v1.2.3 From 7461e33ce1bf8c4593b03522e9e269e7fef3e67d Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 16:17:10 -0500 Subject: core: move route logging to nm-netlink-utils.c --- src/nm-netlink-utils.c | 53 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/nm-netlink-utils.h | 2 ++ src/nm-system.c | 42 +-------------------------------------- 3 files changed, 56 insertions(+), 41 deletions(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index 3e855b42df..6431225821 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -18,9 +18,11 @@ * Copyright (C) 2011 Red Hat, Inc. */ +#include "logging/nm-logging.h" #include "nm-netlink-utils.h" #include "nm-netlink-monitor.h" +#include #include #include #include @@ -136,3 +138,54 @@ nm_netlink_route_delete (struct rtnl_route *route) return err == 0 ? TRUE : FALSE; } + +/** + * nm_netlink_dump_route: + * @route: the route to dump + * + * Logs the details of a route. + **/ +void +nm_netlink_dump_route (struct rtnl_route *route) +{ + char buf6[INET6_ADDRSTRLEN]; + char buf4[INET_ADDRSTRLEN]; + struct nl_addr *nl; + struct in6_addr *addr6 = NULL; + struct in_addr *addr4 = NULL; + int prefixlen = 0; + const char *sf = "UNSPEC"; + int family = rtnl_route_get_family (route); + guint32 log_level = LOGD_IP4 | LOGD_IP6; + + memset (buf6, 0, sizeof (buf6)); + memset (buf4, 0, sizeof (buf4)); + nl = rtnl_route_get_dst (route); + if (nl) { + if (nl_addr_get_family (nl) == AF_INET) { + addr4 = nl_addr_get_binary_addr (nl); + if (addr4) + inet_ntop (AF_INET, addr4, &buf4[0], sizeof (buf4)); + } else if (nl_addr_get_family (nl) == AF_INET6) { + addr6 = nl_addr_get_binary_addr (nl); + if (addr6) + inet_ntop (AF_INET6, addr6, &buf6[0], sizeof (buf6)); + } + prefixlen = nl_addr_get_prefixlen (nl); + } + + if (family == AF_INET) { + sf = "INET"; + log_level = LOGD_IP4; + } else if (family == AF_INET6) { + sf = "INET6"; + log_level = LOGD_IP6; + } + + nm_log_dbg (log_level, " route idx %d family %s (%d) addr %s/%d", + rtnl_route_get_oif (route), + sf, family, + strlen (buf4) ? buf4 : (strlen (buf6) ? buf6 : ""), + prefixlen); +} + diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index b85b98ad62..87531740ec 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -32,4 +32,6 @@ gboolean nm_netlink_find_address (int ifindex, gboolean nm_netlink_route_delete (struct rtnl_route *route); +void nm_netlink_dump_route (struct rtnl_route *route); + #endif /* NM_NETLINK_MONITOR_H */ diff --git a/src/nm-system.c b/src/nm-system.c index 032990aad3..a1dd691046 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -1245,46 +1245,6 @@ foreach_route (void (*callback)(struct nl_object *, gpointer), nl_cache_free (route_cache); } -static void -dump_route (struct rtnl_route *route) -{ - char buf6[INET6_ADDRSTRLEN]; - char buf4[INET_ADDRSTRLEN]; - struct nl_addr *nl; - struct in6_addr *addr6 = NULL; - struct in_addr *addr4 = NULL; - int prefixlen = 0; - const char *sf = "UNSPEC"; - int family = rtnl_route_get_family (route); - - memset (buf6, 0, sizeof (buf6)); - memset (buf4, 0, sizeof (buf4)); - nl = rtnl_route_get_dst (route); - if (nl) { - if (nl_addr_get_family (nl) == AF_INET) { - addr4 = nl_addr_get_binary_addr (nl); - if (addr4) - inet_ntop (AF_INET, addr4, &buf4[0], sizeof (buf4)); - } else if (nl_addr_get_family (nl) == AF_INET6) { - addr6 = nl_addr_get_binary_addr (nl); - if (addr6) - inet_ntop (AF_INET6, addr6, &buf6[0], sizeof (buf6)); - } - prefixlen = nl_addr_get_prefixlen (nl); - } - - if (family == AF_INET) - sf = "INET"; - else if (family == AF_INET6) - sf = "INET6"; - - nm_log_dbg (LOGD_IP4 | LOGD_IP6, " route idx %d family %s (%d) addr %s/%d", - rtnl_route_get_oif (route), - sf, family, - strlen (buf4) ? buf4 : (strlen (buf6) ? buf6 : ""), - prefixlen); -} - typedef struct { const char *iface; int iface_idx; @@ -1299,7 +1259,7 @@ check_one_route (struct nl_object *object, void *user_data) guint32 log_level = LOGD_IP4 | LOGD_IP6; if (nm_logging_level_enabled (LOGL_DEBUG)) - dump_route (route); + nm_netlink_dump_route (route); /* Delete all routes from this interface */ if (rtnl_route_get_oif (route) != data->iface_idx) -- cgit v1.2.3 From abb89a7d2a4b893059a286f8faa0797f510912d5 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 17:08:53 -0500 Subject: core: move route iteration to nm-netlink-utils.c --- src/nm-netlink-utils.c | 113 ++++++++++++++++++++++++++++++++++--- src/nm-netlink-utils.h | 25 ++++++++- src/nm-system.c | 147 +++++++++++++------------------------------------ 3 files changed, 167 insertions(+), 118 deletions(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index 6431225821..67339581ea 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -139,14 +139,8 @@ nm_netlink_route_delete (struct rtnl_route *route) } -/** - * nm_netlink_dump_route: - * @route: the route to dump - * - * Logs the details of a route. - **/ -void -nm_netlink_dump_route (struct rtnl_route *route) +static void +dump_route (struct rtnl_route *route) { char buf6[INET6_ADDRSTRLEN]; char buf4[INET_ADDRSTRLEN]; @@ -189,3 +183,106 @@ nm_netlink_dump_route (struct rtnl_route *route) prefixlen); } + +typedef struct { + int ifindex; + int family; + int scope; + gboolean ignore_inet6_ll_mc; + const char *iface; + NlRouteForeachFunc callback; + gpointer user_data; + struct rtnl_route *out_route; +} ForeachRouteInfo; + +static void +foreach_route_cb (struct nl_object *object, void *user_data) +{ + ForeachRouteInfo *info = user_data; + struct rtnl_route *route = (struct rtnl_route *) object; + struct nl_addr *dst; + + if (info->out_route) + return; + + if (nm_logging_level_enabled (LOGL_DEBUG)) + dump_route (route); + + if ( info->ifindex >= 0 + && rtnl_route_get_oif (route) != info->ifindex) + return; + + if ( info->scope != RT_SCOPE_UNIVERSE + && rtnl_route_get_scope (route) != info->scope) + return; + + if ( info->family != AF_UNSPEC + && rtnl_route_get_family (route) != info->family) + return; + + dst = rtnl_route_get_dst (route); + + /* Check for IPv6 LL and MC routes that might need to be ignored */ + if ( (info->family == AF_INET6 || info->family == AF_UNSPEC) + && (rtnl_route_get_family (route) == AF_INET6)) { + struct in6_addr *addr = NULL; + + if (dst) + addr = nl_addr_get_binary_addr (dst); + if (addr) { + if ( IN6_IS_ADDR_LINKLOCAL (addr) + || IN6_IS_ADDR_MC_LINKLOCAL (addr) + || (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (dst) == 8))) + return; + } + } + + info->out_route = info->callback (route, dst, info->iface, info->user_data); + if (info->out_route) { + /* Ref the route so it sticks around after the cache is cleared */ + rtnl_route_get (info->out_route); + } +} + +/** + * nm_netlink_foreach_route: + * @ifindex: the interface index to filter routes for + * @family: the address family to filter routes for + * @scope: route scope, eg RT_SCOPE_LINK + * @ignore_inet6_ll_mc: if %TRUE ignore IPv6 link-local and multi-cast routes + * @callback: function called when a route matches the filter + * @user_data: data passed to @callback + * + * Filters each route in the routing table against the given @ifindex and + * @family (if given) and calls @callback for each matching route. + * + * Returns: a route if @callback returned one; the caller must dispose of the + * route using rtnl_route_put() when it is no longer required. + **/ +struct rtnl_route * +nm_netlink_foreach_route (int ifindex, + int family, + int scope, + gboolean ignore_inet6_ll_mc, + NlRouteForeachFunc callback, + gpointer user_data) +{ + struct nl_cache *cache; + ForeachRouteInfo info; + + memset (&info, 0, sizeof (info)); + info.ifindex = ifindex; + info.family = family; + info.scope = scope; + info.ignore_inet6_ll_mc = ignore_inet6_ll_mc; + info.callback = callback; + info.user_data = user_data; + info.iface = nm_netlink_index_to_iface (ifindex); + + cache = rtnl_route_alloc_cache (nm_netlink_get_default_handle ()); + g_return_val_if_fail (cache != NULL, NULL); + nl_cache_foreach (cache, foreach_route_cb, &info); + nl_cache_free (cache); + return info.out_route; +} + diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index 87531740ec..63cec4119e 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -32,6 +32,29 @@ gboolean nm_netlink_find_address (int ifindex, gboolean nm_netlink_route_delete (struct rtnl_route *route); -void nm_netlink_dump_route (struct rtnl_route *route); +/** + * NlRouteForeachFunc: + * @route: the route being processed + * @dst: the route's destination address + * @iface: the interface name of the index passed to nm_netlink_foreach_route() + * @in_family: the address family passed to nm_netlink_foreach_route() + * @user_data: the user data pointer passed to nm_netlink_foreach_route() + * + * Returns: a route to return to the caller of nm_netlink_foreach_route() which + * terminates routing table iteration, or NULL to continue iterating the + * routing table. + **/ +typedef struct rtnl_route * (*NlRouteForeachFunc) (struct rtnl_route *route, + struct nl_addr *dst, + const char *iface, + gpointer user_data); + +struct rtnl_route * nm_netlink_foreach_route (int ifindex, + int family, + int scope, + gboolean ignore_inet6_ll_mc, + NlRouteForeachFunc callback, + gpointer user_data); #endif /* NM_NETLINK_MONITOR_H */ + diff --git a/src/nm-system.c b/src/nm-system.c index a1dd691046..f64f13ba61 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -1231,71 +1231,19 @@ nm_system_iface_flush_addresses (int ifindex, int family) } -static void -foreach_route (void (*callback)(struct nl_object *, gpointer), - gpointer user_data) -{ - struct nl_handle *nlh; - struct nl_cache *route_cache; - - nlh = nm_netlink_get_default_handle (); - route_cache = rtnl_route_alloc_cache (nlh); - g_assert (route_cache); - nl_cache_foreach (route_cache, callback, user_data); - nl_cache_free (route_cache); -} - -typedef struct { - const char *iface; - int iface_idx; - int family; -} RouteCheckData; - -static void -check_one_route (struct nl_object *object, void *user_data) +static struct rtnl_route * +delete_one_route (struct rtnl_route *route, + struct nl_addr *dst, + const char *iface, + gpointer user_data) { - RouteCheckData *data = (RouteCheckData *) user_data; - struct rtnl_route *route = (struct rtnl_route *) object; - guint32 log_level = LOGD_IP4 | LOGD_IP6; + guint32 log_level = GPOINTER_TO_UINT (user_data); - if (nm_logging_level_enabled (LOGL_DEBUG)) - nm_netlink_dump_route (route); - - /* Delete all routes from this interface */ - if (rtnl_route_get_oif (route) != data->iface_idx) - return; - if (data->family && rtnl_route_get_family (route) != data->family) - return; - - /* We don't want to flush IPv6 link-local routes that may exist on the - * the interface since the LL address and routes should normally stay - * assigned all the time. - */ - if ( (data->family == AF_INET6 || data->family == AF_UNSPEC) - && (rtnl_route_get_family (route) == AF_INET6)) { - struct nl_addr *nl; - struct in6_addr *addr = NULL; - - nl = rtnl_route_get_dst (route); - if (nl) - addr = nl_addr_get_binary_addr (nl); - - if (addr) { - if ( IN6_IS_ADDR_LINKLOCAL (addr) - || IN6_IS_ADDR_MC_LINKLOCAL (addr) - || (IN6_IS_ADDR_MULTICAST (addr) && (nl_addr_get_prefixlen (nl) == 8))) - return; - } - } - - if (data->family == AF_INET) - log_level = LOGD_IP4; - else if (data->family == AF_INET6) - log_level = LOGD_IP6; nm_log_dbg (log_level, " deleting route"); - if (!nm_netlink_route_delete (route)) - nm_log_err (LOGD_DEVICE, "(%s): failed to delete route", data->iface); + nm_log_err (LOGD_DEVICE, "(%s): failed to delete route", iface); + + return NULL; } /** @@ -1310,7 +1258,6 @@ check_one_route (struct nl_object *object, void *user_data) gboolean nm_system_iface_flush_routes (int ifindex, int family) { - RouteCheckData check_data; guint32 log_level = LOGD_IP4 | LOGD_IP6; const char *sf = "UNSPEC"; const char *iface; @@ -1330,56 +1277,43 @@ nm_system_iface_flush_routes (int ifindex, int family) nm_log_dbg (log_level, "(%s): flushing routes ifindex %d family %s (%d)", iface, ifindex, sf, family); - memset (&check_data, 0, sizeof (check_data)); - check_data.iface = iface; - check_data.iface_idx = ifindex; - check_data.family = family; - foreach_route (check_one_route, &check_data); - + /* We don't want to flush IPv6 link-local routes that may exist on the + * the interface since the LL address and routes should normally stay + * assigned all the time. + */ + nm_netlink_foreach_route (ifindex, family, RT_SCOPE_UNIVERSE, TRUE, delete_one_route, GUINT_TO_POINTER (log_level)); return TRUE; } -typedef struct { - struct rtnl_route *route; - NMIP4Config *config; - int ifindex; -} SetPriorityInfo; - -static void -find_route (struct nl_object *object, gpointer user_data) +static struct rtnl_route * +find_route (struct rtnl_route *route, + struct nl_addr *dst, + const char *iface, + gpointer user_data) { - struct rtnl_route *route = (struct rtnl_route *) object; - SetPriorityInfo *info = (SetPriorityInfo *) user_data; - struct nl_addr *dst; + NMIP4Config *config = user_data; struct in_addr *dst_addr; int num; int i; - if (info->route || - rtnl_route_get_oif (route) != info->ifindex || - rtnl_route_get_scope (route) != RT_SCOPE_LINK) - return; - - dst = rtnl_route_get_dst (route); - if (nl_addr_get_family (dst) != AF_INET) - return; + if (dst && (nl_addr_get_family (dst) != AF_INET)) + return NULL; + /* Find the first route that handles a subnet of at least one of the + * device's IPv4 addresses. + */ dst_addr = nl_addr_get_binary_addr (dst); - num = nm_ip4_config_get_num_addresses (info->config); + num = nm_ip4_config_get_num_addresses (config); for (i = 0; i < num; i++) { - NMIP4Address *addr = nm_ip4_config_get_address (info->config, i); + NMIP4Address *addr = nm_ip4_config_get_address (config, i); guint32 prefix = nm_ip4_address_get_prefix (addr); guint32 address = nm_ip4_address_get_address (addr); - if (prefix == nl_addr_get_prefixlen (dst) && - (address & nm_utils_ip4_prefix_to_netmask (prefix)) == dst_addr->s_addr) { - - /* Ref the route so it sticks around after the cache is cleared */ - rtnl_route_get (route); - info->route = route; - break; - } + if ( prefix == nl_addr_get_prefixlen (dst) + && (address & nm_utils_ip4_prefix_to_netmask (prefix)) == dst_addr->s_addr) + return route; } + return NULL; } static void @@ -1387,20 +1321,15 @@ nm_system_device_set_priority (int ifindex, NMIP4Config *config, int priority) { - SetPriorityInfo info; struct nl_handle *nlh; + struct rtnl_route *found; - info.route = NULL; - info.config = config; - info.ifindex = ifindex; - - foreach_route (find_route, &info); - if (info.route) { - nm_netlink_route_delete (info.route); - + found = nm_netlink_foreach_route (ifindex, AF_INET, RT_SCOPE_LINK, FALSE, find_route, config); + if (found) { nlh = nm_netlink_get_default_handle (); - rtnl_route_set_prio (info.route, priority); - rtnl_route_add (nlh, info.route, 0); - rtnl_route_put (info.route); + nm_netlink_route_delete (found); + rtnl_route_set_prio (found, priority); + rtnl_route_add (nlh, found, 0); + rtnl_route_put (found); } } -- cgit v1.2.3 From 11c2824ef1bffe57a44402e10de601284bd977a9 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 17:15:40 -0500 Subject: core: remove dead libnl code --- src/nm-system.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/nm-system.c b/src/nm-system.c index f64f13ba61..3995fab5bb 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -1026,7 +1026,6 @@ gboolean nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *gw_route = NULL; - struct nl_handle *nlh; gboolean success = FALSE; const char *iface; int err; @@ -1034,9 +1033,6 @@ nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) iface = nm_netlink_index_to_iface (ifindex); g_return_val_if_fail (iface != NULL, FALSE); - nlh = nm_netlink_get_default_handle (); - g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip4_route (ifindex, gw, mss); if (err == 0) { return TRUE; @@ -1177,7 +1173,6 @@ gboolean nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *gw_route = NULL; - struct nl_handle *nlh; gboolean success = FALSE; const char *iface; int err; @@ -1185,9 +1180,6 @@ nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) iface = nm_netlink_index_to_iface (ifindex); g_return_val_if_fail (iface != NULL, FALSE); - nlh = nm_netlink_get_default_handle (); - g_return_val_if_fail (nlh != NULL, FALSE); - err = replace_default_ip6_route (ifindex, gw); if (err == 0) return TRUE; -- cgit v1.2.3 From 73ddc1e3072cfc7a9ff21dc719c8bb17a89203ce Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Fri, 22 Jul 2011 18:08:18 -0500 Subject: core: move route creation to nm-netlink-utils.c --- src/nm-netlink-utils.c | 42 ++++++++++++++++++++ src/nm-netlink-utils.h | 13 +++++++ src/nm-system.c | 103 ++++++++++++++----------------------------------- 3 files changed, 83 insertions(+), 75 deletions(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index 67339581ea..ef7ebed7ba 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -119,6 +119,48 @@ nm_netlink_find_address (int ifindex, return info.found; } +struct rtnl_route * +nm_netlink_route_new (int ifindex, + int family, + int mss, + ...) +{ + va_list var_args; + struct rtnl_route *route; + NmNlProp prop = NMNL_PROP_INVALID; + int value; + + route = rtnl_route_alloc (); + g_return_val_if_fail (route != NULL, NULL); + + if (ifindex >= 0) + rtnl_route_set_oif (route, ifindex); + if (family != AF_UNSPEC) + rtnl_route_set_family (route, family); + if (mss > 0) + rtnl_route_set_metric (route, RTAX_ADVMSS, mss); + + va_start (var_args, mss); + prop = va_arg (var_args, NmNlProp); + while (prop != NMNL_PROP_INVALID) { + value = va_arg (var_args, int); + + if (prop == NMNL_PROP_PROT && value != RTPROT_UNSPEC) + rtnl_route_set_protocol (route, value); + else if (prop == NMNL_PROP_TABLE && value != RT_TABLE_UNSPEC) + rtnl_route_set_table (route, value); + else if (prop == NMNL_PROP_SCOPE && value != RT_SCOPE_NOWHERE) + rtnl_route_set_scope (route, value); + else if (prop == NMNL_PROP_PRIO && value > 0) + rtnl_route_set_prio (route, value); + + prop = va_arg (var_args, NmNlProp); + } + va_end (var_args); + + return route; +} + /** * nm_netlink_route_delete: * @route: the route to delete diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index 63cec4119e..bcee6e3d10 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -30,6 +30,19 @@ gboolean nm_netlink_find_address (int ifindex, void *addr, /* struct in_addr or struct in6_addr */ int prefix_); +typedef enum { + NMNL_PROP_INVALID = 0, + NMNL_PROP_PROT, + NMNL_PROP_SCOPE, + NMNL_PROP_TABLE, + NMNL_PROP_PRIO, +} NmNlProp; + +struct rtnl_route * nm_netlink_route_new (int ifindex, + int family, + int mss, + ...) __attribute__((__sentinel__)); + gboolean nm_netlink_route_delete (struct rtnl_route *route); /** diff --git a/src/nm-system.c b/src/nm-system.c index 3995fab5bb..21cd8ce972 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -84,24 +84,6 @@ ip4_dest_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 dest_prefix) return FALSE; } -static struct rtnl_route * -create_route (int iface_idx, int mss) -{ - struct rtnl_route *route; - - route = rtnl_route_alloc (); - if (route) { - rtnl_route_set_oif (route, iface_idx); - - if (mss && rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0) { - nm_log_warn (LOGD_DEVICE, "could not set mss"); - } - } else - nm_log_err (LOGD_DEVICE, "could not allocate route"); - - return route; -} - static struct rtnl_route * nm_system_device_set_ip4_route (int ifindex, guint32 ip4_dest, @@ -125,7 +107,9 @@ nm_system_device_set_ip4_route (int ifindex, iface = nm_netlink_index_to_iface (ifindex); g_return_val_if_fail (iface != NULL, NULL); - route = create_route (ifindex, mss); + route = nm_netlink_route_new (ifindex, AF_INET, mss, + NMNL_PROP_PRIO, metric, + NULL); g_return_val_if_fail (route != NULL, NULL); /* Destination */ @@ -149,17 +133,13 @@ nm_system_device_set_ip4_route (int ifindex, } } - /* Metric */ - if (metric) - rtnl_route_set_prio (route, metric); - /* Add the route */ err = rtnl_route_add (nlh, route, 0); if (err == -ESRCH && ip4_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; - route2 = create_route (ifindex, mss); + route2 = nm_netlink_route_new (ifindex, AF_INET, mss, NULL); if (route2) { /* Add route to gateway over bridge */ rtnl_route_set_dst (route2, gw_addr); @@ -513,7 +493,11 @@ nm_system_set_ip6_route (int ifindex, nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, -1); - route = create_route (ifindex, mss); + route = nm_netlink_route_new (ifindex, AF_INET6, mss, + NMNL_PROP_PROT, protocol, + NMNL_PROP_PRIO, metric, + NMNL_PROP_TABLE, table, + NULL); g_return_val_if_fail (route != NULL, -1); /* Destination */ @@ -537,23 +521,13 @@ nm_system_set_ip6_route (int ifindex, } } - /* Metric */ - if (metric) - rtnl_route_set_prio (route, metric); - - if (protocol) - rtnl_route_set_protocol (route, protocol); - - if (table) - rtnl_route_set_table (route, table); - /* Add the route */ err = rtnl_route_add (nlh, route, 0); if (err == -ESRCH && ip6_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; - route2 = create_route (ifindex, mss); + route2 = nm_netlink_route_new (ifindex, AF_INET6, mss, NULL); if (route2) { /* Add route to gateway over bridge */ rtnl_route_set_dst (route2, gw_addr); @@ -865,14 +839,11 @@ add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) g_return_val_if_fail (nlh != NULL, 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_INET); - rtnl_route_set_table (route, RT_TABLE_MAIN); - rtnl_route_set_oif (route, ifindex); - rtnl_route_set_scope (route, RT_SCOPE_LINK); + route = nm_netlink_route_new (ifindex, AF_INET, mss, + NMNL_PROP_SCOPE, RT_SCOPE_LINK, + NMNL_PROP_TABLE, RT_TABLE_MAIN, + NULL); + g_return_val_if_fail (route != NULL, NULL); gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw)); if (!gw_addr) @@ -881,11 +852,6 @@ add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) rtnl_route_set_dst (route, gw_addr); nl_addr_put (gw_addr); - if (mss) { - if (rtnl_route_set_metric (route, RTAX_ADVMSS, mss) < 0) - goto error; - } - /* Add direct route to the gateway */ err = rtnl_route_add (nlh, route, 0); if (err) { @@ -917,14 +883,12 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, -ENOMEM); - route = rtnl_route_alloc(); + route = nm_netlink_route_new (ifindex, AF_INET, mss, + NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE, + NMNL_PROP_TABLE, RT_TABLE_MAIN, + NULL); g_return_val_if_fail (route != NULL, -ENOMEM); - rtnl_route_set_family (route, AF_INET); - rtnl_route_set_table (route, RT_TABLE_MAIN); - rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - rtnl_route_set_oif (route, ifindex); - /* Build up the destination address */ dst_addr = nl_addr_build (AF_INET, &dst, sizeof (dst)); if (!dst_addr) { @@ -943,12 +907,6 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) nl_addr_set_prefixlen (gw_addr, 0); rtnl_route_set_gateway (route, gw_addr); - if (mss > 0) { - err = rtnl_route_set_metric (route, RTAX_ADVMSS, mss); - if (err < 0) - goto out; - } - /* Add the new default route */ err = rtnl_route_add (nlh, route, NLM_F_REPLACE); @@ -1078,14 +1036,11 @@ add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) g_return_val_if_fail (nlh != NULL, 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, ifindex); - rtnl_route_set_scope (route, RT_SCOPE_LINK); + route = nm_netlink_route_new (ifindex, AF_INET6, 0, + NMNL_PROP_SCOPE, RT_SCOPE_LINK, + NMNL_PROP_TABLE, RT_TABLE_MAIN, + NULL); + g_return_val_if_fail (route != NULL, NULL); gw_addr = nl_addr_build (AF_INET, (void *) gw, sizeof (*gw)); if (!gw_addr) @@ -1127,14 +1082,12 @@ replace_default_ip6_route (int ifindex, const struct in6_addr *gw) nlh = nm_netlink_get_default_handle (); g_return_val_if_fail (nlh != NULL, -ENOMEM); - route = rtnl_route_alloc(); + route = nm_netlink_route_new (ifindex, AF_INET6, 0, + NMNL_PROP_SCOPE, RT_SCOPE_UNIVERSE, + NMNL_PROP_TABLE, RT_TABLE_MAIN, + NULL); 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, ifindex); - if (gw && !IN6_IS_ADDR_UNSPECIFIED (gw)) { /* Build up the gateway address */ gw_addr = nl_addr_build (AF_INET6, (void *) gw, sizeof (*gw)); -- cgit v1.2.3 From a6c65568313183c5b56b36934e07a1d675d4217b Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 29 Jul 2011 11:38:46 +0100 Subject: core: add libnl-2 support with libnl-1 compatibility --- configure.ac | 30 ++++++- src/Makefile.am | 2 + src/backends/NetworkManagerGeneric.c | 6 +- src/ip6-manager/nm-ip6-manager.c | 14 +-- src/nm-device.c | 6 +- src/nm-netlink-compat.c | 92 ++++++++++++++++++++ src/nm-netlink-compat.h | 162 +++++++++++++++++++++++++++++++++++ src/nm-netlink-monitor.c | 77 +++++++++-------- src/nm-netlink-monitor.h | 4 +- src/nm-netlink-utils.c | 21 +++-- src/nm-system.c | 50 ++++++----- 11 files changed, 387 insertions(+), 77 deletions(-) create mode 100644 src/nm-netlink-compat.c create mode 100644 src/nm-netlink-compat.h diff --git a/configure.ac b/configure.ac index 2a33ebd9cb..608765b616 100644 --- a/configure.ac +++ b/configure.ac @@ -312,10 +312,34 @@ else fi AC_DEFINE_UNQUOTED(NO_CONSOLEKIT, $no_ck, [Define to disable use of ConsoleKit]) -PKG_CHECK_MODULES(LIBNL, libnl-1 >= 1.0-pre8) +have_libnl="no" +PKG_CHECK_MODULES(LIBNL1, libnl-1 >= 1.0-pre8, [have_libnl1=yes], [have_libnl1=no]) +if (test "${have_libnl1}" = "yes"); then + AC_DEFINE(HAVE_LIBNL1, 1, [Define if you require libnl-1 legacy support]) + LIBNL_CFLAGS="$LIBNL1_CFLAGS" + LIBNL_LIBS="$LIBNL1_LIBS" + libnl_version="1" + have_libnl="yes" +fi + +PKG_CHECK_MODULES(LIBNL2, libnl-2.0, [have_libnl2=yes], [have_libnl2=no]) +if (test "${have_libnl2}" = "yes"); then + AC_DEFINE(HAVE_LIBNL2, 1, [Define if you require specific libnl-2 support]) + LIBNL_CFLAGS="$LIBNL2_CFLAGS" + LIBNL_LIBS="$LIBNL2_LIBS" + libnl_version="2" + have_libnl="yes" +fi + +if (test "${have_libnl}" = "no"); then + AC_MSG_ERROR([libnl development header are required]) +fi AC_SUBST(LIBNL_CFLAGS) AC_SUBST(LIBNL_LIBS) -NM_LIBNL_CHECK + +if (test "${libnl_version}" = "1"); then + NM_LIBNL_CHECK +fi PKG_CHECK_MODULES(UUID, uuid) AC_SUBST(UUID_CFLAGS) @@ -737,6 +761,8 @@ else echo PPP support: no fi +echo libnl version: ${libnl_version} + echo echo Building documentation: ${with_docs} echo Building tests: ${with_tests} diff --git a/src/Makefile.am b/src/Makefile.am index 11529a7b96..c8caefb0f1 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -161,6 +161,8 @@ NetworkManager_SOURCES = \ nm-netlink-monitor.h \ nm-netlink-utils.c \ nm-netlink-utils.h \ + nm-netlink-compat.h \ + nm-netlink-compat.c \ nm-activation-request.c \ nm-activation-request.h \ nm-properties-changed-signal.c \ diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 90a41bba97..2ef8583c03 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -34,7 +34,9 @@ #include "nm-system.h" #include "NetworkManagerUtils.h" #include "nm-logging.h" +#include "nm-netlink-compat.h" #include "nm-netlink-monitor.h" +#include "nm-netlink-utils.h" /* Because of a bug in libnl, rtnl.h should be included before route.h */ #include @@ -50,7 +52,7 @@ */ void nm_generic_enable_loopback (void) { - struct nl_handle * nlh = NULL; + struct nl_sock * nlh = NULL; struct rtnl_addr * addr = NULL; struct nl_addr * nl_addr = NULL; guint32 binaddr = 0; @@ -92,7 +94,7 @@ void nm_generic_enable_loopback (void) if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) { if (err != -EEXIST) { - nm_log_warn (LOGD_CORE, "error %d returned from rtnl_addr_add():\n%s", err, nl_geterror()); + nm_log_warn (LOGD_CORE, "error %d returned from rtnl_addr_add():\n%s", err, nl_geterror(err)); } } out: diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 4a5dee587d..60045234ca 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -27,6 +27,8 @@ #include "nm-ip6-manager.h" #include "nm-netlink-monitor.h" +#include "nm-netlink-utils.h" +#include "nm-netlink-compat.h" #include "NetworkManagerUtils.h" #include "nm-marshal.h" #include "nm-logging.h" @@ -44,7 +46,7 @@ typedef struct { NMNetlinkMonitor *monitor; GHashTable *devices; - struct nl_handle *nlh; + struct nl_sock *nlh; struct nl_cache *addr_cache, *route_cache; guint netlink_id; @@ -553,7 +555,7 @@ process_addr (NMIP6Manager *manager, struct nl_msg *msg) } old_size = nl_cache_nitems (priv->addr_cache); - nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL); + nl_cache_include (priv->addr_cache, (struct nl_object *)rtnladdr, NULL, NULL); rtnl_addr_put (rtnladdr); /* The kernel will re-notify us of automatically-added addresses @@ -593,7 +595,7 @@ process_route (NMIP6Manager *manager, struct nl_msg *msg) } old_size = nl_cache_nitems (priv->route_cache); - nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL); + nl_cache_include (priv->route_cache, (struct nl_object *)rtnlroute, NULL, NULL); rtnl_route_put (rtnlroute); /* As above in process_addr */ @@ -1248,7 +1250,7 @@ nm_ip6_manager_get_ip6_config (NMIP6Manager *manager, int ifindex) nm_ip6_route_set_dest (ip6route, dest); nm_ip6_route_set_prefix (ip6route, rtnl_route_get_dst_len (rtnlroute)); nm_ip6_route_set_next_hop (ip6route, gateway); - metric = rtnl_route_get_metric (rtnlroute, 1); + rtnl_route_get_metric(rtnlroute, 1, &metric); if (metric != UINT_MAX) nm_ip6_route_set_metric (ip6route, metric); nm_ip6_config_take_route (config, ip6route); @@ -1344,8 +1346,8 @@ nm_ip6_manager_init (NMIP6Manager *manager) 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); + rtnl_addr_alloc_cache(priv->nlh, &priv->addr_cache); + rtnl_route_alloc_cache (priv->nlh, NETLINK_ROUTE, NL_AUTO_PROVIDE, &priv->route_cache); } static void diff --git a/src/nm-device.c b/src/nm-device.c index 6a2db4804b..fbb0b06144 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -47,6 +47,8 @@ #include "nm-utils.h" #include "nm-logging.h" #include "nm-netlink-monitor.h" +#include "nm-netlink-utils.h" +#include "nm-netlink-compat.h" #include "nm-setting-ip4-config.h" #include "nm-setting-ip6-config.h" #include "nm-setting-connection.h" @@ -1679,10 +1681,10 @@ dhcp6_start (NMDevice *self, */ err = nm_system_set_ip6_route (priv->ip_iface ? priv->ip_ifindex : priv->ifindex, &dest, 8, NULL, 256, 0, RTPROT_BOOT, RT_TABLE_LOCAL, NULL); - if (err && (nl_get_errno () != EEXIST)) { + if (err && (err != -NLE_EXIST)) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to add IPv6 multicast route: %s", - priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror ()); + priv->ip_iface ? priv->ip_iface : priv->iface, nl_geterror (err)); } s_ip6 = (NMSettingIP6Config *) nm_connection_get_setting (connection, NM_TYPE_SETTING_IP6_CONFIG); diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c new file mode 100644 index 0000000000..38bbf88ddb --- /dev/null +++ b/src/nm-netlink-compat.c @@ -0,0 +1,92 @@ +/* -*- 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) 2011 Caixa Magica Software. + */ + +#include +#include + +#include "nm-netlink-compat.h" + +#ifndef HAVE_LIBNL1 +struct rtnl_nexthop * nm_netlink_get_nh(struct rtnl_route * route) { + int hops; + + hops = rtnl_route_get_nnexthops (route); + g_return_val_if_fail(hops > 0, NULL); + + return rtnl_route_nexthop_n (route, 0); +} + +int rtnl_route_get_oif(struct rtnl_route * route) { + struct rtnl_nexthop * nh; + nh = nm_netlink_get_nh(route); + g_return_val_if_fail(nh, -NLE_OBJ_NOTFOUND); + return rtnl_route_nh_get_ifindex (nh); +} + +int rtnl_route_set_oif(struct rtnl_route * route, int ifindex) { + struct rtnl_nexthop * nh; + + nh = rtnl_route_nh_alloc(); + rtnl_route_nh_set_ifindex(nh, ifindex); + rtnl_route_add_nexthop(route, nh); + + return 0; +} + +struct nl_addr * rtnl_route_get_gateway(struct rtnl_route * route) { + struct rtnl_nexthop * nh; + + nh = nm_netlink_get_nh(route); + g_return_val_if_fail(nh, NULL); + return rtnl_route_nh_get_gateway(nh); +} + +int rtnl_route_set_gateway(struct rtnl_route * route, struct nl_addr * gw_addr) { + struct rtnl_nexthop * nh; + + nh = nm_netlink_get_nh(route); + g_return_val_if_fail(nh, -NLE_OBJ_NOTFOUND); + + rtnl_route_nh_set_gateway(nh, gw_addr); + return 0; +} + +int rtnl_route_get_dst_len(struct rtnl_route * rtnlroute) { + struct nl_addr * dst; + + dst = rtnl_route_get_dst(rtnlroute); + return nl_addr_get_prefixlen(dst); +} +#endif + +#ifdef HAVE_LIBNL1 +int nl_compat_error(int err) { + err = abs(err); + + if(err==EEXIST) + err = NLE_EXIST; + else if(err==ENOENT) + err = NLE_OBJ_NOTFOUND; + else if(err==ERANGE) + err = NLE_RANGE; + + return -err; +} +#endif diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h new file mode 100644 index 0000000000..6101b307a4 --- /dev/null +++ b/src/nm-netlink-compat.h @@ -0,0 +1,162 @@ +/* -*- 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) 2011 Caixa Magica Software. + */ +#ifndef NM_NETLINK_COMPAT_H +#define NM_NETLINK_COMPAT_H + +#include + +#include +#include +#include +#include +#include + + +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +/* libnl-1 API compatibility for libnl-2/3*/ +#ifndef HAVE_LIBNL1 + +struct rtnl_nexthop * nm_netlink_get_nh(struct rtnl_route *); +int rtnl_route_get_oif(struct rtnl_route *); +int rtnl_route_set_oif(struct rtnl_route *, int); +int rtnl_route_set_gateway(struct rtnl_route *, struct nl_addr *); +int rtnl_route_get_dst_len(struct rtnl_route *); +struct nl_addr * rtnl_route_get_gateway(struct rtnl_route *); +#endif + + +/* libnl-1.0 compat functions */ +#ifdef HAVE_LIBNL1 + +#define nl_sock nl_handle + +/* libnl-1.0 functions with similar prototypes */ +#define nl_socket_alloc nl_handle_alloc +#define nl_socket_alloc_cb nl_handle_alloc_cb +#define nl_socket_free nl_handle_destroy +#define nl_socket_set_passcred nl_set_passcred +#define nl_socket_disable_seq_check nl_disable_sequence_check +#define rtnl_route_set_priority rtnl_route_set_prio + +/* auxiliary functions */ +int nl_compat_error(int); + +/* libnl-1.0 functions with modified prototypes in libnl-2/3*/ +static inline const char * __nl_geterror(int err) +{ + /* err is set, can be parsed */ + return nl_geterror(); +} +#define nl_geterror __nl_geterror + +static inline int __rtnl_addr_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { + *cache = rtnl_addr_alloc_cache(h); + if(!*cache) + return -ENOMEM; + return 0; +} +#define rtnl_addr_alloc_cache __rtnl_addr_alloc_cache + +static inline int __rtnl_route_alloc_cache(struct nl_sock *h, int family, int flags, struct nl_cache **cache) { + *cache = rtnl_route_alloc_cache(h); + if(!*cache) + return -ENOMEM; + return 0; +} +#define rtnl_route_alloc_cache __rtnl_route_alloc_cache + +static inline int __rtnl_link_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { + *cache = rtnl_link_alloc_cache (h); + if(!*cache) + return -ENOMEM; + return 0; +} +#define rtnl_link_alloc_cache __rtnl_link_alloc_cache + +static inline int __rtnl_route_get_metric(struct rtnl_route * route, int metric, unsigned int *value) { + *value = rtnl_route_get_metric(route, metric); + return 0; +} +#define rtnl_route_get_metric __rtnl_route_get_metric + +static inline int __rtnl_addr_add(struct nl_sock * h, struct rtnl_addr * addr, int flags) { + return nl_compat_error(rtnl_addr_add(h,addr,flags)); +} +#define rtnl_addr_add __rtnl_addr_add + +static inline int rtnl_route_delete(struct nl_sock * h, struct rtnl_route * route, int flags) { + return nl_compat_error(rtnl_route_del(h, route, flags)); +} +#define rtnl_route_del rtnl_route_delete + +static inline int __rtnl_link_change(struct nl_sock * h, struct rtnl_link *old, struct rtnl_link * tmpl, int flags) { + return nl_compat_error(rtnl_link_change(h, old, tmpl,flags)); +} +#define rtnl_link_change __rtnl_link_change + +static inline int __nl_cache_include(struct nl_cache * cache, struct nl_object * obj, change_func_t cb, void * data) +{ + return nl_cache_include(cache, obj, cb); +} +#define nl_cache_include __nl_cache_include + +#define NLE_SUCCESS 0 +#define NLE_FAILURE 1 +#define NLE_INTR 2 +#define NLE_BAD_SOCK 3 +#define NLE_AGAIN 4 +#define NLE_NOMEM 5 +#define NLE_EXIST 6 +#define NLE_INVAL 7 +#define NLE_RANGE 8 +#define NLE_MSGSIZE 9 +#define NLE_OPNOTSUPP 10 +#define NLE_AF_NOSUPPORT 11 +#define NLE_OBJ_NOTFOUND 12 +#define NLE_NOATTR 13 +#define NLE_MISSING_ATTR 14 +#define NLE_AF_MISMATCH 15 +#define NLE_SEQ_MISMATCH 16 +#define NLE_MSG_OVERFLOW 17 +#define NLE_MSG_TRUNC 18 +#define NLE_NOADDR 19 +#define NLE_SRCRT_NOSUPPORT 20 +#define NLE_MSG_TOOSHORT 21 +#define NLE_MSGTYPE_NOSUPPORT 22 +#define NLE_OBJ_MISMATCH 23 +#define NLE_NOCACHE 24 +#define NLE_BUSY 25 +#define NLE_PROTO_MISMATCH 26 +#define NLE_NOACCESS 27 +#define NLE_PERM 28 +#define NLE_PKTLOC_FILE 29 +#endif + +#endif /* NM_NETLINK_COMPAT_H */ diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c index 13b3ab9850..978e87d6aa 100644 --- a/src/nm-netlink-monitor.c +++ b/src/nm-netlink-monitor.c @@ -45,6 +45,7 @@ #include #include +#include "nm-netlink-compat.h" #include "nm-netlink-monitor.h" #include "nm-logging.h" @@ -58,12 +59,12 @@ typedef struct { /* Async event listener connection */ - struct nl_handle *nlh_event; + struct nl_sock *nlh_event; GIOChannel * io_channel; guint event_id; /* Sync/blocking request/response connection */ - struct nl_handle *nlh_sync; + struct nl_sock *nlh_sync; struct nl_cache * link_cache; guint request_status_id; @@ -98,7 +99,7 @@ link_msg_handler (struct nl_object *obj, void *arg) error = g_error_new (NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, _("error processing netlink message: %s"), - nl_geterror ()); + nl_geterror (ENOMEM)); g_signal_emit (self, signals[ERROR], 0, error); g_error_free (error); return; @@ -130,7 +131,7 @@ link_msg_handler (struct nl_object *obj, void *arg) static int event_msg_recv (struct nl_msg *msg, void *arg) { - struct nl_handle *nlh = arg; + struct nl_sock *nlh = arg; struct nlmsghdr *hdr = nlmsg_hdr (msg); struct ucred *creds = nlmsg_get_creds (msg); const struct sockaddr_nl *snl; @@ -195,6 +196,7 @@ event_handler (GIOChannel *channel, NMNetlinkMonitor *self = (NMNetlinkMonitor *) user_data; NMNetlinkMonitorPrivate *priv; GError *error = NULL; + int err; g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), TRUE); @@ -225,11 +227,11 @@ event_handler (GIOChannel *channel, g_return_val_if_fail (!(io_condition & ~EVENT_CONDITIONS), FALSE); /* Process the netlink messages */ - if (nl_recvmsgs_default (priv->nlh_event) < 0) { + if ((err = nl_recvmsgs_default (priv->nlh_event)) < 0) { error = g_error_new (NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE, _("error processing netlink message: %s"), - nl_geterror ()); + nl_geterror (err)); g_signal_emit (self, signals[ERROR], 0, error); g_error_free (error); } @@ -238,32 +240,34 @@ event_handler (GIOChannel *channel, } static gboolean -nlh_setup (struct nl_handle *nlh, +nlh_setup (struct nl_sock *nlh, nl_recvmsg_msg_cb_t valid_func, gpointer cb_data, GError **error) { + int err; + nl_socket_modify_cb (nlh, NL_CB_MSG_IN, NL_CB_CUSTOM, event_msg_recv, cb_data); if (valid_func) nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data); - if (nl_connect (nlh, NETLINK_ROUTE) < 0) { + if ((err = nl_connect (nlh, NETLINK_ROUTE)) < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, _("unable to connect to netlink for monitoring link status: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } /* Enable unix socket peer credentials which we use for verifying that the * sender of the message is actually the kernel. */ - if (nl_set_passcred (nlh, 1) < 0) { + if (nl_socket_set_passcred (nlh, 1) < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, _("unable to enable netlink handle credential passing: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } @@ -283,20 +287,20 @@ event_connection_setup (NMNetlinkMonitor *self, GError **error) /* Set up the event listener connection */ cb = nl_cb_alloc (NL_CB_DEFAULT); - priv->nlh_event = nl_handle_alloc_cb (cb); + priv->nlh_event = nl_socket_alloc_cb (cb); nl_cb_put (cb); if (!priv->nlh_event) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), - nl_geterror ()); + nl_geterror (ENOMEM)); goto error; } if (!nlh_setup (priv->nlh_event, event_msg_ready, self, error)) goto error; - nl_disable_sequence_check (priv->nlh_event); + nl_socket_disable_seq_check (priv->nlh_event); /* Subscribe to the LINK group for internal carrier signals */ if (!nm_netlink_monitor_subscribe (self, RTNLGRP_LINK, error)) @@ -327,7 +331,7 @@ error: nm_netlink_monitor_close_connection (self); if (priv->nlh_event) { - nl_handle_destroy (priv->nlh_event); + nl_socket_free (priv->nlh_event); priv->nlh_event = NULL; } @@ -342,16 +346,17 @@ sync_connection_setup (NMNetlinkMonitor *self, GError **error) #ifdef LIBNL_NEEDS_ADDR_CACHING_WORKAROUND struct nl_cache *addr_cache; #endif + int err; /* Set up the event listener connection */ cb = nl_cb_alloc (NL_CB_DEFAULT); - priv->nlh_sync = nl_handle_alloc_cb (cb); + priv->nlh_sync = nl_socket_alloc_cb (cb); nl_cb_put (cb); if (!priv->nlh_sync) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_ALLOC_HANDLE, _("unable to allocate netlink handle for monitoring link status: %s"), - nl_geterror ()); + nl_geterror (ENOMEM)); goto error; } @@ -365,16 +370,18 @@ sync_connection_setup (NMNetlinkMonitor *self, GError **error) * result, most addresses will not compare as equal even to * themselves, busting caching. */ - addr_cache = rtnl_addr_alloc_cache (priv->nlh_sync); + rtnl_addr_alloc_cache (priv->nlh_sync, &addr_cache); nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80; nl_cache_free (addr_cache); #endif - if ((priv->link_cache = rtnl_link_alloc_cache (priv->nlh_sync)) == NULL) { + err = rtnl_link_alloc_cache (priv->nlh_sync, &priv->link_cache); + + if (err) { 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"), - nl_geterror ()); + nl_geterror (err)); goto error; } nl_cache_mngt_provide (priv->link_cache); @@ -388,7 +395,7 @@ error: } if (priv->nlh_sync) { - nl_handle_destroy (priv->nlh_sync); + nl_socket_free (priv->nlh_sync); priv->nlh_sync = NULL; } @@ -483,7 +490,7 @@ gboolean nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error) { NMNetlinkMonitorPrivate *priv; - int subs; + int subs, err; g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); @@ -496,11 +503,11 @@ nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error) subs = get_subs (self, group) + 1; if (subs == 1) { - if (nl_socket_add_membership (priv->nlh_event, group) < 0) { + if ((err = nl_socket_add_membership (priv->nlh_event, group)) < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP, _("unable to join netlink group: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } } @@ -558,14 +565,15 @@ deferred_emit_carrier_state (gpointer user_data) { NMNetlinkMonitor *self = NM_NETLINK_MONITOR (user_data); NMNetlinkMonitorPrivate *priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); + int err; priv->request_status_id = 0; /* 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_sync, priv->link_cache)) { - nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror ()); + if ((err = nl_cache_refill (priv->nlh_sync, priv->link_cache)) != 0) { + nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror (err)); } else nl_cache_foreach_filter (priv->link_cache, NULL, link_msg_handler, self); @@ -614,6 +622,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, NMNetlinkMonitorPrivate *priv; GetFlagsInfo info; struct rtnl_link *filter; + int err; g_return_val_if_fail (self != NULL, FALSE); g_return_val_if_fail (NM_IS_NETLINK_MONITOR (self), FALSE); @@ -622,12 +631,12 @@ 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_sync, priv->link_cache)) { + if ((err = nl_cache_refill (priv->nlh_sync, priv->link_cache)) != 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, _("error updating link cache: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } @@ -640,7 +649,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, _("error updating link cache: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } @@ -651,7 +660,7 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_BAD_ALLOC, _("error processing netlink message: %s"), - nl_geterror ()); + nl_geterror (err)); return FALSE; } rtnl_link_set_ifindex (filter, ifindex); @@ -678,11 +687,11 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, /***************************************************************/ -struct nl_handle * +struct nl_sock * nm_netlink_get_default_handle (void) { NMNetlinkMonitor *self; - struct nl_handle *nlh; + struct nl_sock *nlh; self = nm_netlink_monitor_get (); nlh = NM_NETLINK_MONITOR_GET_PRIVATE (self)->nlh_sync; @@ -796,12 +805,12 @@ finalize (GObject *object) } if (priv->nlh_event) { - nl_handle_destroy (priv->nlh_event); + nl_socket_free (priv->nlh_event); priv->nlh_event = NULL; } if (priv->nlh_sync) { - nl_handle_destroy (priv->nlh_sync); + nl_socket_free (priv->nlh_sync); priv->nlh_sync = NULL; } diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h index 8b57a312d7..38ccd350df 100644 --- a/src/nm-netlink-monitor.h +++ b/src/nm-netlink-monitor.h @@ -90,10 +90,12 @@ gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor guint32 *ifflags, GError **error); +#include "nm-netlink-compat.h" + /* 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); +struct nl_sock *nm_netlink_get_default_handle (void); #endif /* NM_NETLINK_MONITOR_H */ diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index ef7ebed7ba..dfb726546b 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -21,6 +21,7 @@ #include "logging/nm-logging.h" #include "nm-netlink-utils.h" #include "nm-netlink-monitor.h" +#include "nm-netlink-compat.h" #include #include @@ -28,6 +29,8 @@ #include #include +#include + typedef struct { int ifindex; int family; @@ -86,7 +89,7 @@ nm_netlink_find_address (int ifindex, void *addr, /* struct in_addr or struct in6_addr */ int prefix) { - struct nl_handle *nlh = NULL; + struct nl_sock *nlh = NULL; struct nl_cache *cache = NULL; FindAddrInfo info; @@ -109,7 +112,7 @@ nm_netlink_find_address (int ifindex, nlh = nm_netlink_get_default_handle (); if (nlh) { - cache = rtnl_addr_alloc_cache (nlh); + rtnl_addr_alloc_cache(nlh, &cache); if (cache) { nl_cache_mngt_provide (cache); nl_cache_foreach (cache, find_one_address, &info); @@ -152,7 +155,7 @@ nm_netlink_route_new (int ifindex, else if (prop == NMNL_PROP_SCOPE && value != RT_SCOPE_NOWHERE) rtnl_route_set_scope (route, value); else if (prop == NMNL_PROP_PRIO && value > 0) - rtnl_route_set_prio (route, value); + rtnl_route_set_priority (route, value); prop = va_arg (var_args, NmNlProp); } @@ -170,14 +173,15 @@ nm_netlink_route_new (int ifindex, gboolean nm_netlink_route_delete (struct rtnl_route *route) { - struct nl_handle *nlh; - int err; + struct nl_sock *nlh; + int err=0; g_return_val_if_fail (route != NULL, FALSE); nlh = nm_netlink_get_default_handle (); - err = rtnl_route_del (nlh, route, 0); - return err == 0 ? TRUE : FALSE; + err = rtnl_route_delete (nlh, route, 0); + + return ((err < 0) && (err != -NLE_RANGE)) ? FALSE: TRUE; } @@ -321,10 +325,11 @@ nm_netlink_foreach_route (int ifindex, info.user_data = user_data; info.iface = nm_netlink_index_to_iface (ifindex); - cache = rtnl_route_alloc_cache (nm_netlink_get_default_handle ()); + rtnl_route_alloc_cache (nm_netlink_get_default_handle (), family, NL_AUTO_PROVIDE, &cache); g_return_val_if_fail (cache != NULL, NULL); nl_cache_foreach (cache, foreach_route_cb, &info); nl_cache_free (cache); return info.out_route; } + diff --git a/src/nm-system.c b/src/nm-system.c index 21cd8ce972..4f6236db3c 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -49,6 +49,7 @@ #include "nm-logging.h" #include "nm-netlink-monitor.h" #include "nm-netlink-utils.h" +#include "nm-netlink-compat.h" #include #include @@ -92,7 +93,7 @@ nm_system_device_set_ip4_route (int ifindex, guint32 metric, int mss) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct rtnl_route *route; struct nl_addr *dest_addr; struct nl_addr *gw_addr = NULL; @@ -160,7 +161,7 @@ nm_system_device_set_ip4_route (int ifindex, if (err) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 route: %s", - iface, nl_geterror ()); + iface, nl_geterror (err)); rtnl_route_put (route); route = NULL; } @@ -174,7 +175,7 @@ sync_addresses (int ifindex, struct rtnl_addr **addrs, int num_addrs) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct nl_cache *addr_cache; struct rtnl_addr *filter_addr, *match_addr; struct nl_object *match; @@ -193,7 +194,8 @@ sync_addresses (int ifindex, if (!nlh) return FALSE; - addr_cache = rtnl_addr_alloc_cache (nlh); + rtnl_addr_alloc_cache(nlh, &addr_cache); + if (!addr_cache) return FALSE; @@ -266,7 +268,7 @@ sync_addresses (int ifindex, err = rtnl_addr_delete (nlh, match_addr, 0); if (err < 0) { nm_log_err (log_domain, "(%s): error %d returned from rtnl_addr_delete(): %s", - iface, err, nl_geterror ()); + iface, err, nl_geterror (err)); } } @@ -299,10 +301,10 @@ sync_addresses (int ifindex, } err = rtnl_addr_add (nlh, addrs[i], 0); - if (err < 0 && (nl_get_errno () != EEXIST)) { + if (err < 0 && (err != -NLE_EXIST)) { nm_log_err (log_domain, "(%s): error %d returned from rtnl_addr_add():\n%s", - iface, err, nl_geterror ()); + iface, err, nl_geterror (err)); } rtnl_addr_put (addrs[i]); @@ -482,7 +484,7 @@ nm_system_set_ip6_route (int ifindex, int table, struct rtnl_route **out_route) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct rtnl_route *route; struct nl_addr *dest_addr; struct nl_addr *gw_addr = NULL; @@ -634,7 +636,7 @@ nm_system_apply_ip6_config (int ifindex, if (err) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 route: %s", - iface, nl_geterror ()); + iface, nl_geterror (err)); } } } @@ -663,8 +665,9 @@ nm_system_iface_set_up (int ifindex, gboolean *no_firmware) { struct rtnl_link *request = NULL, *old = NULL; - struct nl_handle *nlh; + struct nl_sock *nlh; gboolean success = FALSE; + int err; g_return_val_if_fail (ifindex > 0, FALSE); if (no_firmware) @@ -682,10 +685,13 @@ nm_system_iface_set_up (int ifindex, if (old) { nlh = nm_netlink_get_default_handle (); if (nlh) { - if (rtnl_link_change (nlh, old, request, 0) == 0) + err = rtnl_link_change (nlh, old, request, 0); + if (err == 0) { success = TRUE; - else if ((nl_get_errno () == ENOENT) && no_firmware && up) - *no_firmware = TRUE; + } else { + if ((err == -NLE_OBJ_NOTFOUND) && no_firmware && up) + *no_firmware = TRUE; + } } } @@ -738,7 +744,7 @@ nm_system_iface_set_mtu (int ifindex, guint32 mtu) struct rtnl_link *old; struct rtnl_link *new; gboolean success = FALSE; - struct nl_handle *nlh; + struct nl_sock *nlh; const char *iface; int err; @@ -785,7 +791,7 @@ nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac) { struct rtnl_link *old, *new; gboolean success = FALSE; - struct nl_handle *nlh; + struct nl_sock *nlh; const char *iface; struct nl_addr *addr = NULL; int err; @@ -826,7 +832,7 @@ nm_system_iface_set_mac (int ifindex, const struct ether_addr *mac) static struct rtnl_route * add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; const char *iface; @@ -872,7 +878,7 @@ static int replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *route = NULL; - struct nl_handle *nlh; + struct nl_sock *nlh; struct nl_addr *dst_addr = NULL; guint32 dst = 0; struct nl_addr *gw_addr = NULL; @@ -934,7 +940,7 @@ nm_system_replace_default_ip4_route_vpn (int ifindex, guint32 parent_mss) { struct rtnl_route *gw_route = NULL; - struct nl_handle *nlh; + struct nl_sock *nlh; gboolean success = FALSE; int err; const char *iface; @@ -1023,7 +1029,7 @@ nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) static struct rtnl_route * add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct rtnl_route *route = NULL; struct nl_addr *gw_addr = NULL; const char *iface; @@ -1069,7 +1075,7 @@ static int replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *route = NULL; - struct nl_handle *nlh; + struct nl_sock *nlh; struct nl_addr *gw_addr = NULL; const char *iface; int err = -1; @@ -1266,14 +1272,14 @@ nm_system_device_set_priority (int ifindex, NMIP4Config *config, int priority) { - struct nl_handle *nlh; + struct nl_sock *nlh; struct rtnl_route *found; found = nm_netlink_foreach_route (ifindex, AF_INET, RT_SCOPE_LINK, FALSE, find_route, config); if (found) { nlh = nm_netlink_get_default_handle (); nm_netlink_route_delete (found); - rtnl_route_set_prio (found, priority); + rtnl_route_set_priority (found, priority); rtnl_route_add (nlh, found, 0); rtnl_route_put (found); } -- cgit v1.2.3 From daeb181fa2c7bb2e6aeb44344a73b6fe448a388d Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 29 Jul 2011 14:47:37 +0100 Subject: core: add libnl-3 API compatibility --- configure.ac | 9 +++++++++ src/nm-netlink-compat.h | 7 +++++++ 2 files changed, 16 insertions(+) diff --git a/configure.ac b/configure.ac index 608765b616..509de590e5 100644 --- a/configure.ac +++ b/configure.ac @@ -331,6 +331,15 @@ if (test "${have_libnl2}" = "yes"); then have_libnl="yes" fi +PKG_CHECK_MODULES(LIBNL3, libnl-3.0, [have_libnl2=yes], [have_libnl2=no]) +if (test "${have_libnl2}" = "yes"); then + AC_DEFINE(HAVE_LIBNL3, 1, [Define if you require specific libnl-3 support]) + LIBNL_CFLAGS="$LIBNL3_CFLAGS" + LIBNL_LIBS="$LIBNL3_LIBS" + libnl_version="3" + have_libnl="yes" +fi + if (test "${have_libnl}" = "no"); then AC_MSG_ERROR([libnl development header are required]) fi diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h index 6101b307a4..867c9f4eef 100644 --- a/src/nm-netlink-compat.h +++ b/src/nm-netlink-compat.h @@ -51,6 +51,13 @@ int rtnl_route_get_dst_len(struct rtnl_route *); struct nl_addr * rtnl_route_get_gateway(struct rtnl_route *); #endif +/* libnl-2 API compatibility for libnl-3 */ +#ifdef HAVE_LIBNL3 +static inline int __rtnl_link_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { + return rtnl_link_alloc_cache (h, AF_UNSPEC, cache); +} +#define rtnl_link_alloc_cache __rtnl_link_alloc_cache +#endif /* libnl-1.0 compat functions */ #ifdef HAVE_LIBNL1 -- cgit v1.2.3 From b562839df81255f14af8b9e98ee7dd87342e52a1 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 30 Jul 2011 15:46:33 -0500 Subject: core: misc style fixes to libnl compat code --- src/backends/NetworkManagerGeneric.c | 3 +- src/ip6-manager/nm-ip6-manager.c | 4 +- src/nm-netlink-compat.c | 39 ++++++++++++------ src/nm-netlink-compat.h | 79 +++++++++++++++++++++++------------- src/nm-netlink-monitor.c | 21 ++++++---- src/nm-netlink-monitor.h | 2 +- src/nm-netlink-utils.c | 4 +- src/nm-system.c | 5 +-- 8 files changed, 99 insertions(+), 58 deletions(-) diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 2ef8583c03..7491f52a57 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -94,7 +94,8 @@ void nm_generic_enable_loopback (void) if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) { if (err != -EEXIST) { - nm_log_warn (LOGD_CORE, "error %d returned from rtnl_addr_add():\n%s", err, nl_geterror(err)); + nm_log_warn (LOGD_CORE, "error setting loopback address: (%d) %s", + err, nl_geterror (err)); } } out: diff --git a/src/ip6-manager/nm-ip6-manager.c b/src/ip6-manager/nm-ip6-manager.c index 60045234ca..fb9e77ba33 100644 --- a/src/ip6-manager/nm-ip6-manager.c +++ b/src/ip6-manager/nm-ip6-manager.c @@ -1346,8 +1346,10 @@ nm_ip6_manager_init (NMIP6Manager *manager) G_CALLBACK (netlink_notification), manager); priv->nlh = nm_netlink_get_default_handle (); - rtnl_addr_alloc_cache(priv->nlh, &priv->addr_cache); + rtnl_addr_alloc_cache (priv->nlh, &priv->addr_cache); + g_warn_if_fail (priv->addr_cache != NULL); rtnl_route_alloc_cache (priv->nlh, NETLINK_ROUTE, NL_AUTO_PROVIDE, &priv->route_cache); + g_warn_if_fail (priv->route_cache != NULL); } static void diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c index 38bbf88ddb..ca2fff3377 100644 --- a/src/nm-netlink-compat.c +++ b/src/nm-netlink-compat.c @@ -24,33 +24,40 @@ #include "nm-netlink-compat.h" #ifndef HAVE_LIBNL1 -struct rtnl_nexthop * nm_netlink_get_nh(struct rtnl_route * route) { +struct rtnl_nexthop * +nm_netlink_get_nh (struct rtnl_route * route) +{ int hops; hops = rtnl_route_get_nnexthops (route); g_return_val_if_fail(hops > 0, NULL); - return rtnl_route_nexthop_n (route, 0); } -int rtnl_route_get_oif(struct rtnl_route * route) { +int +rtnl_route_get_oif (struct rtnl_route * route) +{ struct rtnl_nexthop * nh; + nh = nm_netlink_get_nh(route); g_return_val_if_fail(nh, -NLE_OBJ_NOTFOUND); return rtnl_route_nh_get_ifindex (nh); } -int rtnl_route_set_oif(struct rtnl_route * route, int ifindex) { +int +rtnl_route_set_oif (struct rtnl_route * route, int ifindex) +{ struct rtnl_nexthop * nh; nh = rtnl_route_nh_alloc(); rtnl_route_nh_set_ifindex(nh, ifindex); rtnl_route_add_nexthop(route, nh); - return 0; } -struct nl_addr * rtnl_route_get_gateway(struct rtnl_route * route) { +struct nl_addr * +rtnl_route_get_gateway (struct rtnl_route * route) +{ struct rtnl_nexthop * nh; nh = nm_netlink_get_nh(route); @@ -58,7 +65,9 @@ struct nl_addr * rtnl_route_get_gateway(struct rtnl_route * route) { return rtnl_route_nh_get_gateway(nh); } -int rtnl_route_set_gateway(struct rtnl_route * route, struct nl_addr * gw_addr) { +int +rtnl_route_set_gateway (struct rtnl_route * route, struct nl_addr * gw_addr) +{ struct rtnl_nexthop * nh; nh = nm_netlink_get_nh(route); @@ -68,7 +77,9 @@ int rtnl_route_set_gateway(struct rtnl_route * route, struct nl_addr * gw_addr) return 0; } -int rtnl_route_get_dst_len(struct rtnl_route * rtnlroute) { +int +rtnl_route_get_dst_len(struct rtnl_route * rtnlroute) +{ struct nl_addr * dst; dst = rtnl_route_get_dst(rtnlroute); @@ -77,14 +88,16 @@ int rtnl_route_get_dst_len(struct rtnl_route * rtnlroute) { #endif #ifdef HAVE_LIBNL1 -int nl_compat_error(int err) { - err = abs(err); +int +nl_compat_error (int err) +{ + err = abs (err); - if(err==EEXIST) + if (err == EEXIST) err = NLE_EXIST; - else if(err==ENOENT) + else if (err == ENOENT) err = NLE_OBJ_NOTFOUND; - else if(err==ERANGE) + else if (err == ERANGE) err = NLE_RANGE; return -err; diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h index 867c9f4eef..f4e3d466c2 100644 --- a/src/nm-netlink-compat.h +++ b/src/nm-netlink-compat.h @@ -17,6 +17,7 @@ * * Copyright (C) 2011 Caixa Magica Software. */ + #ifndef NM_NETLINK_COMPAT_H #define NM_NETLINK_COMPAT_H @@ -53,7 +54,9 @@ struct nl_addr * rtnl_route_get_gateway(struct rtnl_route *); /* libnl-2 API compatibility for libnl-3 */ #ifdef HAVE_LIBNL3 -static inline int __rtnl_link_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { +static inline int +__rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache) +{ return rtnl_link_alloc_cache (h, AF_UNSPEC, cache); } #define rtnl_link_alloc_cache __rtnl_link_alloc_cache @@ -73,64 +76,82 @@ static inline int __rtnl_link_alloc_cache(struct nl_sock *h, struct nl_cache **c #define rtnl_route_set_priority rtnl_route_set_prio /* auxiliary functions */ -int nl_compat_error(int); +int nl_compat_error (int); /* libnl-1.0 functions with modified prototypes in libnl-2/3*/ -static inline const char * __nl_geterror(int err) +static inline const char * +__nl_geterror (int err) { /* err is set, can be parsed */ - return nl_geterror(); + return nl_geterror (); } #define nl_geterror __nl_geterror -static inline int __rtnl_addr_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { - *cache = rtnl_addr_alloc_cache(h); - if(!*cache) - return -ENOMEM; - return 0; +static inline int +__rtnl_addr_alloc_cache (struct nl_sock *h, struct nl_cache **cache) +{ + g_return_val_if_fail (cache != NULL, -EINVAL); + + *cache = rtnl_addr_alloc_cache (h); + return *cache ? 0 : -ENOMEM; } #define rtnl_addr_alloc_cache __rtnl_addr_alloc_cache -static inline int __rtnl_route_alloc_cache(struct nl_sock *h, int family, int flags, struct nl_cache **cache) { - *cache = rtnl_route_alloc_cache(h); - if(!*cache) - return -ENOMEM; - return 0; +static inline int +__rtnl_route_alloc_cache (struct nl_sock *h, int family, int flags, struct nl_cache **cache) +{ + g_return_val_if_fail (cache != NULL, -EINVAL); + + *cache = rtnl_route_alloc_cache (h); + return *cache ? 0 : -ENOMEM; } #define rtnl_route_alloc_cache __rtnl_route_alloc_cache -static inline int __rtnl_link_alloc_cache(struct nl_sock *h, struct nl_cache **cache) { - *cache = rtnl_link_alloc_cache (h); - if(!*cache) - return -ENOMEM; - return 0; +static inline int +__rtnl_link_alloc_cache (struct nl_sock *h, struct nl_cache **cache) +{ + g_return_val_if_fail (cache != NULL, -EINVAL); + + *cache = rtnl_link_alloc_cache (h); + return *cache ? 0 : -ENOMEM; } #define rtnl_link_alloc_cache __rtnl_link_alloc_cache -static inline int __rtnl_route_get_metric(struct rtnl_route * route, int metric, unsigned int *value) { - *value = rtnl_route_get_metric(route, metric); +static inline int +__rtnl_route_get_metric (struct rtnl_route *route, int metric, unsigned int *value) +{ + g_return_val_if_fail (value != NULL, -EINVAL); + + *value = rtnl_route_get_metric (route, metric); return 0; } #define rtnl_route_get_metric __rtnl_route_get_metric -static inline int __rtnl_addr_add(struct nl_sock * h, struct rtnl_addr * addr, int flags) { - return nl_compat_error(rtnl_addr_add(h,addr,flags)); +static inline int +__rtnl_addr_add (struct nl_sock *h, struct rtnl_addr *addr, int flags) +{ + return nl_compat_error (rtnl_addr_add (h, addr, flags)); } #define rtnl_addr_add __rtnl_addr_add -static inline int rtnl_route_delete(struct nl_sock * h, struct rtnl_route * route, int flags) { - return nl_compat_error(rtnl_route_del(h, route, flags)); +static inline int +rtnl_route_delete (struct nl_sock *h, struct rtnl_route *route, int flags) +{ + return nl_compat_error (rtnl_route_del (h, route, flags)); } #define rtnl_route_del rtnl_route_delete -static inline int __rtnl_link_change(struct nl_sock * h, struct rtnl_link *old, struct rtnl_link * tmpl, int flags) { - return nl_compat_error(rtnl_link_change(h, old, tmpl,flags)); +static inline int +__rtnl_link_change (struct nl_sock *h, struct rtnl_link *old, struct rtnl_link *tmpl, int flags) +{ + return nl_compat_error (rtnl_link_change (h, old, tmpl,flags)); } #define rtnl_link_change __rtnl_link_change -static inline int __nl_cache_include(struct nl_cache * cache, struct nl_object * obj, change_func_t cb, void * data) +static inline int +__nl_cache_include (struct nl_cache *cache, struct nl_object *obj, change_func_t cb, void *data) { - return nl_cache_include(cache, obj, cb); + return nl_cache_include (cache, obj, cb); } #define nl_cache_include __nl_cache_include diff --git a/src/nm-netlink-monitor.c b/src/nm-netlink-monitor.c index 978e87d6aa..040ef5af55 100644 --- a/src/nm-netlink-monitor.c +++ b/src/nm-netlink-monitor.c @@ -227,7 +227,8 @@ event_handler (GIOChannel *channel, g_return_val_if_fail (!(io_condition & ~EVENT_CONDITIONS), FALSE); /* Process the netlink messages */ - if ((err = nl_recvmsgs_default (priv->nlh_event)) < 0) { + err = nl_recvmsgs_default (priv->nlh_event); + if (err < 0) { error = g_error_new (NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_PROCESSING_MESSAGE, _("error processing netlink message: %s"), @@ -252,7 +253,8 @@ nlh_setup (struct nl_sock *nlh, if (valid_func) nl_socket_modify_cb (nlh, NL_CB_VALID, NL_CB_CUSTOM, valid_func, cb_data); - if ((err = nl_connect (nlh, NETLINK_ROUTE)) < 0) { + err = nl_connect (nlh, NETLINK_ROUTE); + if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_CONNECT, _("unable to connect to netlink for monitoring link status: %s"), @@ -371,13 +373,13 @@ sync_connection_setup (NMNetlinkMonitor *self, GError **error) * themselves, busting caching. */ rtnl_addr_alloc_cache (priv->nlh_sync, &addr_cache); + g_warn_if_fail (addr_cache != NULL); nl_cache_get_ops (addr_cache)->co_obj_ops->oo_id_attrs &= ~0x80; nl_cache_free (addr_cache); #endif err = rtnl_link_alloc_cache (priv->nlh_sync, &priv->link_cache); - - if (err) { + if (err < 0) { 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"), @@ -503,7 +505,8 @@ nm_netlink_monitor_subscribe (NMNetlinkMonitor *self, int group, GError **error) subs = get_subs (self, group) + 1; if (subs == 1) { - if ((err = nl_socket_add_membership (priv->nlh_event, group)) < 0) { + err = nl_socket_add_membership (priv->nlh_event, group); + if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_NETLINK_JOIN_GROUP, _("unable to join netlink group: %s"), @@ -572,9 +575,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 ((err = nl_cache_refill (priv->nlh_sync, priv->link_cache)) != 0) { + err = nl_cache_refill (priv->nlh_sync, priv->link_cache); + if (err < 0) nm_log_err (LOGD_HW, "error updating link cache: %s", nl_geterror (err)); - } else + else nl_cache_foreach_filter (priv->link_cache, NULL, link_msg_handler, self); return FALSE; @@ -631,7 +635,8 @@ nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *self, priv = NM_NETLINK_MONITOR_GET_PRIVATE (self); /* Update the link cache with the latest information */ - if ((err = nl_cache_refill (priv->nlh_sync, priv->link_cache)) != 0) { + err = nl_cache_refill (priv->nlh_sync, priv->link_cache); + if (err < 0) { g_set_error (error, NM_NETLINK_MONITOR_ERROR, NM_NETLINK_MONITOR_ERROR_LINK_CACHE_UPDATE, diff --git a/src/nm-netlink-monitor.h b/src/nm-netlink-monitor.h index 38ccd350df..5c1fa33990 100644 --- a/src/nm-netlink-monitor.h +++ b/src/nm-netlink-monitor.h @@ -96,6 +96,6 @@ gboolean nm_netlink_monitor_get_flags_sync (NMNetlinkMonitor *monitor 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_sock *nm_netlink_get_default_handle (void); +struct nl_sock * nm_netlink_get_default_handle (void); #endif /* NM_NETLINK_MONITOR_H */ diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index dfb726546b..cbdbe6eb77 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -174,14 +174,14 @@ gboolean nm_netlink_route_delete (struct rtnl_route *route) { struct nl_sock *nlh; - int err=0; + int err = 0; g_return_val_if_fail (route != NULL, FALSE); nlh = nm_netlink_get_default_handle (); err = rtnl_route_delete (nlh, route, 0); - return ((err < 0) && (err != -NLE_RANGE)) ? FALSE: TRUE; + return (err && (err != -NLE_RANGE)) ? FALSE : TRUE; } diff --git a/src/nm-system.c b/src/nm-system.c index 4f6236db3c..11e9ad0907 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -194,9 +194,8 @@ sync_addresses (int ifindex, if (!nlh) return FALSE; - rtnl_addr_alloc_cache(nlh, &addr_cache); - - if (!addr_cache) + err = rtnl_addr_alloc_cache (nlh, &addr_cache); + if (err < 0) return FALSE; filter_addr = rtnl_addr_alloc (); -- cgit v1.2.3 From 76ecc0998979bff4c805957a5fc972ffc0680092 Mon Sep 17 00:00:00 2001 From: Dan Williams Date: Sat, 30 Jul 2011 16:53:42 -0500 Subject: core: don't warn if loopback address already exists --- src/backends/NetworkManagerGeneric.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/backends/NetworkManagerGeneric.c b/src/backends/NetworkManagerGeneric.c index 7491f52a57..89b8a46dde 100644 --- a/src/backends/NetworkManagerGeneric.c +++ b/src/backends/NetworkManagerGeneric.c @@ -92,11 +92,10 @@ void nm_generic_enable_loopback (void) rtnl_addr_set_scope (addr, RT_SCOPE_HOST); rtnl_addr_set_label (addr, "lo"); - if ((err = rtnl_addr_add (nlh, addr, 0)) < 0) { - if (err != -EEXIST) { - nm_log_warn (LOGD_CORE, "error setting loopback address: (%d) %s", - err, nl_geterror (err)); - } + err = rtnl_addr_add (nlh, addr, 0); + if (err && (err != -NLE_EXIST)) { + nm_log_warn (LOGD_CORE, "error setting loopback address: (%d) %s", + err, nl_geterror (err)); } out: if (addr) -- cgit v1.2.3 From 790c16c9f2d3d1fd4a7f030f4cddf58fa2dfb066 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Thu, 4 Aug 2011 10:26:10 +0100 Subject: libnl3: Add ESRCH to compat error translation --- src/nm-netlink-compat.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/nm-netlink-compat.c b/src/nm-netlink-compat.c index ca2fff3377..e91a1ff22d 100644 --- a/src/nm-netlink-compat.c +++ b/src/nm-netlink-compat.c @@ -95,7 +95,7 @@ nl_compat_error (int err) if (err == EEXIST) err = NLE_EXIST; - else if (err == ENOENT) + else if (err == ENOENT || err == ESRCH) err = NLE_OBJ_NOTFOUND; else if (err == ERANGE) err = NLE_RANGE; -- cgit v1.2.3 From 2e32003fd21e35f5e194508452c6e5c17ce42fc0 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Thu, 4 Aug 2011 10:26:21 +0100 Subject: libnl3: Fix ESRCH return types ESRCH becomes NLE_OBJ_NOTFOUND. Includes workaround for libnl aliased return value where ESRCH is being converted to a generic unspecified error by libnl [1]. [1] http://git.kernel.org/?p=libs/netlink/libnl.git;a=commit;h=7e9d5f --- src/nm-netlink-utils.c | 7 ++++++- src/nm-system.c | 10 +++++----- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index cbdbe6eb77..bbf6e4d8fb 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -181,7 +181,12 @@ nm_netlink_route_delete (struct rtnl_route *route) nlh = nm_netlink_get_default_handle (); err = rtnl_route_delete (nlh, route, 0); - return (err && (err != -NLE_RANGE)) ? FALSE : TRUE; + /* Workaround libnl BUG: ESRCH is aliased to generic NLE_FAILURE + * See: http://git.kernel.org/?p=libs/netlink/libnl.git;a=commit;h=7e9d5f */ + if (err == -NLE_FAILURE) + err = -NLE_OBJ_NOTFOUND; + + return (err && (err != -NLE_OBJ_NOTFOUND)) ? FALSE : TRUE; } diff --git a/src/nm-system.c b/src/nm-system.c index 11e9ad0907..d74e0c83c7 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -136,7 +136,7 @@ nm_system_device_set_ip4_route (int ifindex, /* Add the route */ err = rtnl_route_add (nlh, route, 0); - if (err == -ESRCH && ip4_gateway) { + if (((err == -NLE_OBJ_NOTFOUND) || (err == -NLE_FAILURE)) && ip4_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; @@ -524,7 +524,7 @@ nm_system_set_ip6_route (int ifindex, /* Add the route */ err = rtnl_route_add (nlh, route, 0); - if (err == -ESRCH && ip6_gateway) { + if (((err == -NLE_OBJ_NOTFOUND) || (err == -NLE_FAILURE)) && ip6_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; @@ -953,7 +953,7 @@ nm_system_replace_default_ip4_route_vpn (int ifindex, err = replace_default_ip4_route (ifindex, int_gw, mss); if (err == 0) { return TRUE; - } else if (err != -ESRCH) { + } else if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 default route: %d", iface, err); @@ -999,7 +999,7 @@ nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) err = replace_default_ip4_route (ifindex, gw, mss); if (err == 0) { return TRUE; - } else if (err != -ESRCH) { + } else if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 default route: %d", iface, err); @@ -1141,7 +1141,7 @@ nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) err = replace_default_ip6_route (ifindex, gw); if (err == 0) return TRUE; - if (err != -ESRCH) { + if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 default route: %d", iface, err); -- cgit v1.2.3 From 638d3beb01afb3c1c5dad7854506aff34bbc44f8 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 5 Aug 2011 16:02:19 +0100 Subject: libnl: Use compat return for nl_route_add() --- src/nm-netlink-compat.h | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/nm-netlink-compat.h b/src/nm-netlink-compat.h index f4e3d466c2..3d02169dbe 100644 --- a/src/nm-netlink-compat.h +++ b/src/nm-netlink-compat.h @@ -134,6 +134,13 @@ __rtnl_addr_add (struct nl_sock *h, struct rtnl_addr *addr, int flags) } #define rtnl_addr_add __rtnl_addr_add +static inline int +__rtnl_route_add (struct nl_sock *sk, struct rtnl_route *route, int flags) +{ + return nl_compat_error (rtnl_route_add (sk, route, flags)); +} +#define rtnl_route_add __rtnl_route_add + static inline int rtnl_route_delete (struct nl_sock *h, struct rtnl_route *route, int flags) { -- cgit v1.2.3 From 83b1b1660f23e3cebb17cebe36452937fb2e9149 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 5 Aug 2011 16:02:26 +0100 Subject: libnl: route delete can return ERANGE in libnl-1 --- src/nm-netlink-utils.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index bbf6e4d8fb..d6fdd81aed 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -181,12 +181,15 @@ nm_netlink_route_delete (struct rtnl_route *route) nlh = nm_netlink_get_default_handle (); err = rtnl_route_delete (nlh, route, 0); + if (err) + nm_log_dbg (LOGD_IP4 | LOGD_IP6, "%s (%d)", nl_geterror(err), err); + /* Workaround libnl BUG: ESRCH is aliased to generic NLE_FAILURE * See: http://git.kernel.org/?p=libs/netlink/libnl.git;a=commit;h=7e9d5f */ if (err == -NLE_FAILURE) err = -NLE_OBJ_NOTFOUND; - return (err && (err != -NLE_OBJ_NOTFOUND)) ? FALSE : TRUE; + return (err && (err != -NLE_OBJ_NOTFOUND) && (err != -NLE_RANGE) ) ? FALSE : TRUE; } -- cgit v1.2.3 From a73039c0ec8d1717100cdbe29480e47b8879d816 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 5 Aug 2011 16:02:34 +0100 Subject: libnl: Create a common netlink route add function --- src/nm-netlink-utils.c | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++ src/nm-netlink-utils.h | 7 +++++ 2 files changed, 87 insertions(+) diff --git a/src/nm-netlink-utils.c b/src/nm-netlink-utils.c index d6fdd81aed..cc61197da6 100644 --- a/src/nm-netlink-utils.c +++ b/src/nm-netlink-utils.c @@ -164,6 +164,86 @@ nm_netlink_route_new (int ifindex, return route; } +/** + * nm_netlink_route_add: + * @route: the route to add + * + * Returns: zero if succeeded or the netlink error otherwise. + **/ +int nm_netlink_route_add(struct rtnl_route * route, + int family, + const void * dest, /* in_addr or in6_addr */ + int dest_prefix, + const void * gateway, /* in_addr or in6_addr */ + int flags) +{ + struct nl_sock * sk; + struct nl_addr * dest_addr, * gw_addr; + void * tmp_addr; + int addrlen, err, log; + + if(family == AF_INET) { + addrlen = sizeof(struct in_addr); + log = LOGD_IP4; + } + else if (family == AF_INET6) { + addrlen = sizeof(struct in6_addr); + log = LOGD_IP6; + } else { + g_assert_not_reached (); + } + + + sk = nm_netlink_get_default_handle(); + + /* Build up the destination address */ + if (dest) { + /* Copy to preserve const */ + tmp_addr = g_malloc0(addrlen); + memcpy(tmp_addr, dest, addrlen); + + dest_addr = nl_addr_build (family, tmp_addr, addrlen); + g_free(tmp_addr); + + g_return_val_if_fail (dest_addr != NULL, -NLE_INVAL); + nl_addr_set_prefixlen (dest_addr, dest_prefix); + + rtnl_route_set_dst (route, dest_addr); + nl_addr_put (dest_addr); + } + + /* Build up the gateway address */ + if (gateway) { + tmp_addr = g_malloc0(addrlen); + memcpy(tmp_addr, gateway, addrlen); + + gw_addr = nl_addr_build (family, tmp_addr, addrlen); + g_free(tmp_addr); + + if (gw_addr) { + nl_addr_set_prefixlen (gw_addr, 0); + rtnl_route_set_gateway (route, gw_addr); + rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); + nl_addr_put(gw_addr); + } else { + nm_log_err (LOGD_DEVICE | log, "Invalid gateway"); + } + } + + err = rtnl_route_add (sk, route, 0); + + /* LIBNL Bug: Aliased ESRCH */ + if (err == -NLE_FAILURE) + err = -NLE_OBJ_NOTFOUND; + + if (err) + nm_log_warn (LOGD_DEVICE | log, + "Failed to add route %s", + nl_geterror(err)); + + return err; +} + /** * nm_netlink_route_delete: * @route: the route to delete diff --git a/src/nm-netlink-utils.h b/src/nm-netlink-utils.h index bcee6e3d10..c6c452a00a 100644 --- a/src/nm-netlink-utils.h +++ b/src/nm-netlink-utils.h @@ -43,6 +43,13 @@ struct rtnl_route * nm_netlink_route_new (int ifindex, int mss, ...) __attribute__((__sentinel__)); +int nm_netlink_route_add (struct rtnl_route *route, + int family, + const void * dst, /* struct in_addr or struct in6_addr */ + int prefix, + const void * gw, /* struct in_addr or struct in6_addr */ + int flags); + gboolean nm_netlink_route_delete (struct rtnl_route *route); /** -- cgit v1.2.3 From 07cc83fbdb6a5bc0736f60b7e0075867bc7ee8f7 Mon Sep 17 00:00:00 2001 From: Alfredo Matos Date: Fri, 5 Aug 2011 16:02:44 +0100 Subject: libnl: Move to common route add function interface --- src/nm-system.c | 143 +++++++------------------------------------------------- 1 file changed, 16 insertions(+), 127 deletions(-) diff --git a/src/nm-system.c b/src/nm-system.c index d74e0c83c7..ac428eef5f 100644 --- a/src/nm-system.c +++ b/src/nm-system.c @@ -95,8 +95,6 @@ nm_system_device_set_ip4_route (int ifindex, { struct nl_sock *nlh; struct rtnl_route *route; - struct nl_addr *dest_addr; - struct nl_addr *gw_addr = NULL; int err; const char *iface; @@ -113,41 +111,18 @@ nm_system_device_set_ip4_route (int ifindex, NULL); g_return_val_if_fail (route != NULL, NULL); - /* Destination */ - dest_addr = nl_addr_build (AF_INET, &ip4_dest, sizeof (ip4_dest)); - g_return_val_if_fail (dest_addr != NULL, NULL); - nl_addr_set_prefixlen (dest_addr, (int) ip4_prefix); - - rtnl_route_set_dst (route, dest_addr); - nl_addr_put (dest_addr); - - /* Gateway */ - if (ip4_gateway) { - gw_addr = nl_addr_build (AF_INET, &ip4_gateway, sizeof (ip4_gateway)); - if (gw_addr) { - rtnl_route_set_gateway (route, gw_addr); - rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - } else { - nm_log_err (LOGD_DEVICE | LOGD_IP4, "Invalid gateway 0x%X", ip4_gateway); - rtnl_route_put (route); - return NULL; - } - } - /* Add the route */ - err = rtnl_route_add (nlh, route, 0); - if (((err == -NLE_OBJ_NOTFOUND) || (err == -NLE_FAILURE)) && ip4_gateway) { + err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0); + if (err == -NLE_OBJ_NOTFOUND && ip4_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; route2 = nm_netlink_route_new (ifindex, AF_INET, mss, NULL); if (route2) { /* Add route to gateway over bridge */ - rtnl_route_set_dst (route2, gw_addr); - err = rtnl_route_add (nlh, route2, 0); + err = nm_netlink_route_add(route2, AF_INET, &ip4_gateway, 32, NULL, 0); if (!err) { - /* Try adding the route again */ - err = rtnl_route_add (nlh, route, 0); + err = nm_netlink_route_add(route, AF_INET, &ip4_dest, ip4_prefix, &ip4_gateway, 0); if (err) nm_netlink_route_delete (route2); } @@ -155,9 +130,6 @@ nm_system_device_set_ip4_route (int ifindex, } } - if (gw_addr) - nl_addr_put (gw_addr); - if (err) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 route: %s", @@ -485,8 +457,6 @@ nm_system_set_ip6_route (int ifindex, { struct nl_sock *nlh; struct rtnl_route *route; - struct nl_addr *dest_addr; - struct nl_addr *gw_addr = NULL; int err = 0; g_return_val_if_fail (ifindex >= 0, -1); @@ -501,41 +471,19 @@ nm_system_set_ip6_route (int ifindex, NULL); g_return_val_if_fail (route != NULL, -1); - /* Destination */ - dest_addr = nl_addr_build (AF_INET6, (struct in6_addr *) ip6_dest, sizeof (*ip6_dest)); - g_return_val_if_fail (dest_addr != NULL, -1); - nl_addr_set_prefixlen (dest_addr, (int) ip6_prefix); - - rtnl_route_set_dst (route, dest_addr); - nl_addr_put (dest_addr); - - /* 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)); - if (gw_addr) { - rtnl_route_set_gateway (route, gw_addr); - rtnl_route_set_scope (route, RT_SCOPE_UNIVERSE); - } else { - nm_log_warn (LOGD_DEVICE | LOGD_IP6, "Invalid gateway"); - rtnl_route_put (route); - return -1; - } - } - /* Add the route */ - err = rtnl_route_add (nlh, route, 0); - if (((err == -NLE_OBJ_NOTFOUND) || (err == -NLE_FAILURE)) && ip6_gateway) { + err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0); + if (err == -NLE_OBJ_NOTFOUND && ip6_gateway) { /* Gateway might be over a bridge; try adding a route to gateway first */ struct rtnl_route *route2; route2 = nm_netlink_route_new (ifindex, AF_INET6, mss, NULL); if (route2) { + err = nm_netlink_route_add(route, AF_INET6, &ip6_gateway, 128, NULL, 0); /* Add route to gateway over bridge */ - rtnl_route_set_dst (route2, gw_addr); - err = rtnl_route_add (nlh, route2, 0); if (!err) { /* Try adding the route again */ - err = rtnl_route_add (nlh, route, 0); + err = nm_netlink_route_add(route, AF_INET6, &ip6_dest, ip6_prefix, &ip6_gateway, 0); if (err) nm_netlink_route_delete (route2); } @@ -543,9 +491,6 @@ nm_system_set_ip6_route (int ifindex, } } - if (gw_addr) - nl_addr_put (gw_addr); - if (out_route) *out_route = route; else @@ -833,7 +778,6 @@ add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) { struct nl_sock *nlh; struct rtnl_route *route = NULL; - struct nl_addr *gw_addr = NULL; const char *iface; int err; @@ -850,15 +794,8 @@ add_ip4_route_to_gateway (int ifindex, guint32 gw, guint32 mss) NULL); g_return_val_if_fail (route != NULL, NULL); - gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw)); - if (!gw_addr) - goto error; - nl_addr_set_prefixlen (gw_addr, 32); - 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); + err = nm_netlink_route_add(route, AF_INET, &gw, 32, NULL, 0); if (err) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to add IPv4 route to gateway (%d)", @@ -878,10 +815,8 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) { struct rtnl_route *route = NULL; struct nl_sock *nlh; - struct nl_addr *dst_addr = NULL; - guint32 dst = 0; - struct nl_addr *gw_addr = NULL; int err = -1; + int dst=0; g_return_val_if_fail (ifindex > 0, -ENODEV); @@ -894,32 +829,9 @@ replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) NULL); g_return_val_if_fail (route != NULL, -ENOMEM); - /* Build up the destination address */ - dst_addr = nl_addr_build (AF_INET, &dst, sizeof (dst)); - if (!dst_addr) { - err = -ENOMEM; - goto out; - } - nl_addr_set_prefixlen (dst_addr, 0); - rtnl_route_set_dst (route, dst_addr); - - /* Build up the gateway address */ - gw_addr = nl_addr_build (AF_INET, &gw, sizeof (gw)); - if (!gw_addr) { - err = -ENOMEM; - goto out; - } - nl_addr_set_prefixlen (gw_addr, 0); - rtnl_route_set_gateway (route, gw_addr); - /* Add the new default route */ - err = rtnl_route_add (nlh, route, NLM_F_REPLACE); + err = nm_netlink_route_add (route, AF_INET, &dst, 0, &gw, NLM_F_REPLACE); -out: - if (dst_addr) - nl_addr_put (dst_addr); - if (gw_addr) - nl_addr_put (gw_addr); rtnl_route_put (route); return err; } @@ -999,7 +911,7 @@ nm_system_replace_default_ip4_route (int ifindex, guint32 gw, guint32 mss) err = replace_default_ip4_route (ifindex, gw, mss); if (err == 0) { return TRUE; - } else if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) { + } else if (err != -NLE_OBJ_NOTFOUND) { nm_log_err (LOGD_DEVICE | LOGD_IP4, "(%s): failed to set IPv4 default route: %d", iface, err); @@ -1030,7 +942,6 @@ add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) { struct nl_sock *nlh; struct rtnl_route *route = NULL; - struct nl_addr *gw_addr = NULL; const char *iface; int err; @@ -1047,15 +958,8 @@ add_ip6_route_to_gateway (int ifindex, const struct in6_addr *gw) NULL); g_return_val_if_fail (route != NULL, NULL); - 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); + err = nm_netlink_route_add(route, AF_INET, gw, 128, NULL, 0); if (err) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to add IPv4 route to gateway (%d)", @@ -1075,7 +979,6 @@ replace_default_ip6_route (int ifindex, const struct in6_addr *gw) { struct rtnl_route *route = NULL; struct nl_sock *nlh; - struct nl_addr *gw_addr = NULL; const char *iface; int err = -1; @@ -1093,20 +996,9 @@ replace_default_ip6_route (int ifindex, const struct in6_addr *gw) NULL); g_return_val_if_fail (route != NULL, -ENOMEM); - 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) { + nm_netlink_route_add(route, AF_INET6, NULL, 0, gw, NLM_F_REPLACE); + if (err == -NLE_EXIST) { /* 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. @@ -1114,9 +1006,6 @@ replace_default_ip6_route (int ifindex, const struct in6_addr *gw) err = 0; } -out: - if (gw_addr) - nl_addr_put (gw_addr); rtnl_route_put (route); return err; } @@ -1141,7 +1030,7 @@ nm_system_replace_default_ip6_route (int ifindex, const struct in6_addr *gw) err = replace_default_ip6_route (ifindex, gw); if (err == 0) return TRUE; - if ((err != -NLE_OBJ_NOTFOUND) && (err != -NLE_FAILURE)) { + if (err != -NLE_OBJ_NOTFOUND) { nm_log_err (LOGD_DEVICE | LOGD_IP6, "(%s): failed to set IPv6 default route: %d", iface, err); -- cgit v1.2.3