2008-09-30 Tambet Ingo <tambet@gmail.com>

* 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
This commit is contained in:
Tambet Ingo
2008-09-30 15:04:10 +00:00
parent 11f71598b7
commit 50f3ec27a2
6 changed files with 123 additions and 41 deletions

View File

@@ -1,3 +1,18 @@
2008-09-30 Tambet Ingo <tambet@gmail.com>
* 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 <dcbw@redhat.com> 2008-09-29 Dan Williams <dcbw@redhat.com>
Handle ipw3945 suspend/resume by retrying the GIWRANGE request a few times Handle ipw3945 suspend/resume by retrying the GIWRANGE request a few times

View File

@@ -172,30 +172,12 @@ get_connection_id (NMConnection *connection)
return s_con->id; 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 * static NMDevice *
get_best_device (NMManager *manager, NMActRequest **out_req) get_best_device (NMManager *manager, NMActRequest **out_req)
{ {
GSList *devices, *iter; GSList *devices, *iter;
NMDevice *best = NULL; 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 (manager != NULL, NULL);
g_return_val_if_fail (NM_IS_MANAGER (manager), 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; NMConnection *connection;
NMIP4Config *ip4_config; NMIP4Config *ip4_config;
NMSettingIP4Config *s_ip4; NMSettingIP4Config *s_ip4;
guint32 prio; int prio;
guint i; guint i;
gboolean can_default = FALSE; 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)) if (!can_default && !NM_IS_HSO_GSM_DEVICE (dev))
continue; continue;
prio = get_device_priority (dev); prio = nm_device_get_priority (dev);
if (prio > best_prio) { if (prio > 0 && prio < best_prio) {
best = dev; best = dev;
best_prio = prio; best_prio = prio;
*out_req = req; *out_req = req;

View File

@@ -61,6 +61,10 @@
#include <netlink/utils.h> #include <netlink/utils.h>
#include <netlink/route/link.h> #include <netlink/route/link.h>
static void nm_system_device_set_priority (const char *iface,
NMIP4Config *config,
int priority);
static gboolean static gboolean
route_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 prefix) route_in_same_subnet (NMIP4Config *config, guint32 dest, guint32 prefix)
{ {
@@ -277,7 +281,8 @@ add_ip4_addresses (NMIP4Config *config, const char *iface)
*/ */
gboolean gboolean
nm_system_device_set_from_ip4_config (const char *iface, nm_system_device_set_from_ip4_config (const char *iface,
NMIP4Config *config) NMIP4Config *config,
int priority)
{ {
int len, i; int len, i;
@@ -304,6 +309,9 @@ nm_system_device_set_from_ip4_config (const char *iface,
if (nm_ip4_config_get_mtu (config)) if (nm_ip4_config_get_mtu (config))
nm_system_device_set_mtu (iface, 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; 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)); 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 { typedef struct {
const char *iface; const char *iface;
struct nl_handle *nlh;
int iface_idx; int iface_idx;
} RouteCheckData; } RouteCheckData;
@@ -711,7 +734,7 @@ check_one_route (struct nl_object *object, void *user_data)
if (rtnl_route_get_family (route) != AF_INET) if (rtnl_route_get_family (route) != AF_INET)
return; return;
err = rtnl_route_del (data->nlh, route, 0); err = rtnl_route_del (nm_netlink_get_default_handle (), route, 0);
if (err < 0) { if (err < 0) {
nm_warning ("(%s) error %d returned from rtnl_route_del(): %s", nm_warning ("(%s) error %d returned from rtnl_route_del(): %s",
data->iface, err, nl_geterror()); 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) 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; int iface_idx;
RouteCheckData check_data; 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); iface_idx = nm_netlink_iface_to_index (iface);
g_return_if_fail (iface_idx >= 0); 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)); memset (&check_data, 0, sizeof (check_data));
check_data.iface = iface; check_data.iface = iface;
check_data.nlh = nlh;
check_data.iface_idx = iface_idx; check_data.iface_idx = iface_idx;
route_cache = rtnl_route_alloc_cache (nlh); foreach_route (check_one_route, &check_data);
g_return_if_fail (route_cache != NULL); }
nl_cache_mngt_provide (route_cache);
typedef struct {
/* Remove routing table entries */ struct rtnl_route *route;
nl_cache_foreach (route_cache, check_one_route, &check_data); NMIP4Config *config;
int iface;
nl_cache_free (route_cache); } 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);
}
} }

View File

@@ -46,7 +46,8 @@ void nm_system_enable_loopback (void);
void nm_system_update_dns (void); void nm_system_update_dns (void);
gboolean nm_system_device_set_from_ip4_config (const char *iface, 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, gboolean nm_system_vpn_device_set_from_ip4_config (NMDevice *active_device,
const char *iface, const char *iface,

View File

@@ -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 * Accessor for capabilities
*/ */
@@ -1910,7 +1919,7 @@ nm_device_set_ip4_config (NMDevice *self, NMIP4Config *config, NMDeviceStateReas
if (!nm_ip4_config_is_exported (config)) if (!nm_ip4_config_is_exported (config))
nm_ip4_config_export (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) if (success)
nm_device_update_ip4_address (self); nm_device_update_ip4_address (self);

View File

@@ -127,6 +127,8 @@ NMDeviceType nm_device_get_device_type (NMDevice *dev);
guint32 nm_device_get_capabilities (NMDevice *dev); guint32 nm_device_get_capabilities (NMDevice *dev);
guint32 nm_device_get_type_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); guint32 nm_device_get_ip4_address (NMDevice *dev);
void nm_device_update_ip4_address (NMDevice *dev); void nm_device_update_ip4_address (NMDevice *dev);
struct in6_addr * nm_device_get_ip6_address (NMDevice *dev); struct in6_addr * nm_device_get_ip6_address (NMDevice *dev);