From 50f3ec27a2c787b11c3149dcadd9aedc4264a0a5 Mon Sep 17 00:00:00 2001 From: Tambet Ingo Date: Tue, 30 Sep 2008 15:04:10 +0000 Subject: [PATCH] 2008-09-30 Tambet Ingo * src/nm-device.c (nm_device_get_priority): Implement. (nm_device_set_ip4_config): Send the device priority to system ip4 config setter. * src/NetworkManagerSystem.c (nm_system_device_set_from_ip4_config): Add priority argument and if it's >= 0, set the priority of the network route added automatically by netlink (or kernel?). (nm_system_device_set_priority): Implement. * src/NetworkManagerPolicy.c (get_best_device): Use nm_device_get_priority() instead of home-grown version. Revert the meaning, best priority is the lowest one. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@4125 4912f4e0-d625-0410-9fb7-b9a5a253dbdc --- ChangeLog | 15 ++++++ src/NetworkManagerPolicy.c | 26 ++------- src/NetworkManagerSystem.c | 107 +++++++++++++++++++++++++++++++------ src/NetworkManagerSystem.h | 3 +- src/nm-device.c | 11 +++- src/nm-device.h | 2 + 6 files changed, 123 insertions(+), 41 deletions(-) diff --git a/ChangeLog b/ChangeLog index e19c85706..d46f80725 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,18 @@ +2008-09-30 Tambet Ingo + + * src/nm-device.c (nm_device_get_priority): Implement. + (nm_device_set_ip4_config): Send the device priority to system ip4 + config setter. + + * src/NetworkManagerSystem.c (nm_system_device_set_from_ip4_config): + Add priority argument and if it's >= 0, set the priority of the network + route added automatically by netlink (or kernel?). + (nm_system_device_set_priority): Implement. + + * src/NetworkManagerPolicy.c (get_best_device): Use + nm_device_get_priority() instead of home-grown version. Revert the + meaning, best priority is the lowest one. + 2008-09-29 Dan Williams Handle ipw3945 suspend/resume by retrying the GIWRANGE request a few times diff --git a/src/NetworkManagerPolicy.c b/src/NetworkManagerPolicy.c index b6ad36107..b8d5faae9 100644 --- a/src/NetworkManagerPolicy.c +++ b/src/NetworkManagerPolicy.c @@ -172,30 +172,12 @@ get_connection_id (NMConnection *connection) return s_con->id; } -static guint32 -get_device_priority (NMDevice *dev) -{ - if (NM_IS_CDMA_DEVICE (dev)) - return 2; - - if (NM_IS_GSM_DEVICE (dev)) - return 3; - - if (NM_IS_DEVICE_WIFI (dev)) - return 4; - - if (NM_IS_DEVICE_ETHERNET (dev)) - return 5; - - return 1; -} - static NMDevice * get_best_device (NMManager *manager, NMActRequest **out_req) { GSList *devices, *iter; NMDevice *best = NULL; - guint32 best_prio = 0; + int best_prio = G_MAXINT; g_return_val_if_fail (manager != NULL, NULL); g_return_val_if_fail (NM_IS_MANAGER (manager), NULL); @@ -209,7 +191,7 @@ get_best_device (NMManager *manager, NMActRequest **out_req) NMConnection *connection; NMIP4Config *ip4_config; NMSettingIP4Config *s_ip4; - guint32 prio; + int prio; guint i; gboolean can_default = FALSE; @@ -245,8 +227,8 @@ get_best_device (NMManager *manager, NMActRequest **out_req) if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev)) continue; - prio = get_device_priority (dev); - if (prio > best_prio) { + prio = nm_device_get_priority (dev); + if (prio > 0 && prio < best_prio) { best = dev; best_prio = prio; *out_req = req; diff --git a/src/NetworkManagerSystem.c b/src/NetworkManagerSystem.c index eaa53a102..2db294c66 100644 --- a/src/NetworkManagerSystem.c +++ b/src/NetworkManagerSystem.c @@ -61,6 +61,10 @@ #include #include +static void nm_system_device_set_priority (const char *iface, + NMIP4Config *config, + int priority); + static gboolean route_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 prefix) { @@ -277,7 +281,8 @@ add_ip4_addresses (NMIP4Config *config, const char *iface) */ gboolean nm_system_device_set_from_ip4_config (const char *iface, - NMIP4Config *config) + NMIP4Config *config, + int priority) { int len, i; @@ -304,6 +309,9 @@ nm_system_device_set_from_ip4_config (const char *iface, if (nm_ip4_config_get_mtu (config)) nm_system_device_set_mtu (iface, nm_ip4_config_get_mtu (config)); + if (priority > 0) + nm_system_device_set_priority (iface, config, priority); + return TRUE; } @@ -692,9 +700,24 @@ void nm_system_device_flush_ip4_routes (NMDevice *dev) nm_system_device_flush_ip4_routes_with_iface (nm_device_get_iface (dev)); } + +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); + nl_cache_mngt_provide (route_cache); + nl_cache_foreach (route_cache, callback, user_data); + nl_cache_free (route_cache); +} + + typedef struct { const char *iface; - struct nl_handle *nlh; int iface_idx; } RouteCheckData; @@ -711,7 +734,7 @@ check_one_route (struct nl_object *object, void *user_data) if (rtnl_route_get_family (route) != AF_INET) return; - err = rtnl_route_del (data->nlh, route, 0); + err = rtnl_route_del (nm_netlink_get_default_handle (), route, 0); if (err < 0) { nm_warning ("(%s) error %d returned from rtnl_route_del(): %s", data->iface, err, nl_geterror()); @@ -726,8 +749,6 @@ check_one_route (struct nl_object *object, void *user_data) */ void nm_system_device_flush_ip4_routes_with_iface (const char *iface) { - struct nl_handle *nlh = NULL; - struct nl_cache *route_cache = NULL; int iface_idx; RouteCheckData check_data; @@ -735,20 +756,72 @@ void nm_system_device_flush_ip4_routes_with_iface (const char *iface) iface_idx = nm_netlink_iface_to_index (iface); g_return_if_fail (iface_idx >= 0); - nlh = nm_netlink_get_default_handle (); - g_return_if_fail (nlh != NULL); - memset (&check_data, 0, sizeof (check_data)); check_data.iface = iface; - check_data.nlh = nlh; check_data.iface_idx = iface_idx; - route_cache = rtnl_route_alloc_cache (nlh); - g_return_if_fail (route_cache != NULL); - nl_cache_mngt_provide (route_cache); - - /* Remove routing table entries */ - nl_cache_foreach (route_cache, check_one_route, &check_data); - - nl_cache_free (route_cache); + foreach_route (check_one_route, &check_data); +} + +typedef struct { + struct rtnl_route *route; + NMIP4Config *config; + int iface; +} SetPriorityInfo; + +static void +find_route (struct nl_object *object, gpointer user_data) +{ + struct rtnl_route *route = (struct rtnl_route *) object; + SetPriorityInfo *info = (SetPriorityInfo *) user_data; + struct nl_addr *dst; + struct in_addr *dst_addr; + int num; + int i; + + if (info->route || + rtnl_route_get_oif (route) != info->iface || + rtnl_route_get_scope (route) != RT_SCOPE_LINK) + return; + + dst = rtnl_route_get_dst (route); + if (nl_addr_get_family (dst) != AF_INET) + return; + + dst_addr = nl_addr_get_binary_addr (dst); + num = nm_ip4_config_get_num_addresses (info->config); + for (i = 0; i < num; i++) { + const NMSettingIP4Address *addr = nm_ip4_config_get_address (info->config, i); + + if (addr->prefix == nl_addr_get_prefixlen (dst) && + (addr->address & nm_utils_ip4_prefix_to_netmask (addr->prefix)) == dst_addr->s_addr) { + + info->route = route; + break; + } + } +} + +static void +nm_system_device_set_priority (const char *iface, + NMIP4Config *config, + int priority) +{ + SetPriorityInfo info; + + info.route = NULL; + info.config = config; + info.iface = nm_netlink_iface_to_index (iface); + g_return_if_fail (info.iface >= 0); + + 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); + + rtnl_route_set_prio (info.route, priority); + rtnl_route_add (nlh, info.route, 0); + } } diff --git a/src/NetworkManagerSystem.h b/src/NetworkManagerSystem.h index eb321df5a..2a1503ee7 100644 --- a/src/NetworkManagerSystem.h +++ b/src/NetworkManagerSystem.h @@ -46,7 +46,8 @@ void nm_system_enable_loopback (void); void nm_system_update_dns (void); gboolean nm_system_device_set_from_ip4_config (const char *iface, - NMIP4Config *config); + NMIP4Config *config, + int priority); gboolean nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device, const char *iface, diff --git a/src/nm-device.c b/src/nm-device.c index 0fd0909af..149339a9b 100644 --- a/src/nm-device.c +++ b/src/nm-device.c @@ -303,6 +303,15 @@ nm_device_set_device_type (NMDevice *dev, NMDeviceType type) } +int +nm_device_get_priority (NMDevice *dev) +{ + g_return_val_if_fail (NM_IS_DEVICE (dev), -1); + + return (int) nm_device_get_device_type (dev); +} + + /* * Accessor for capabilities */ @@ -1910,7 +1919,7 @@ nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReas if (!nm_ip4_config_is_exported (config)) nm_ip4_config_export (config); - success = nm_system_device_set_from_ip4_config (ip_iface, config); + success = nm_system_device_set_from_ip4_config (ip_iface, config, nm_device_get_priority (self)); if (success) nm_device_update_ip4_address (self); diff --git a/src/nm-device.h b/src/nm-device.h index 0cb705697..9ca0d7ef6 100644 --- a/src/nm-device.h +++ b/src/nm-device.h @@ -127,6 +127,8 @@ NMDeviceType nm_device_get_device_type (NMDevice *dev); guint32 nm_device_get_capabilities (NMDevice *dev); guint32 nm_device_get_type_capabilities (NMDevice *dev); +int nm_device_get_priority (NMDevice *dev); + guint32 nm_device_get_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev); struct in6_addr * nm_device_get_ip6_address (NMDevice *dev);