summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-08-08 12:39:18 -0700
committerMarcel Holtmann <marcel@holtmann.org>2009-08-08 12:39:18 -0700
commitb7d722c12182908d523234093a60a77c14394f6a (patch)
tree4d2072dc59aa1cdcfe76db7bb8f93480204cb16e
parentafc99f394364a5bf1a60e558b5672f721d47a68e (diff)
downloadconnman-b7d722c12182908d523234093a60a77c14394f6a.tar.gz
connman-b7d722c12182908d523234093a60a77c14394f6a.tar.bz2
connman-b7d722c12182908d523234093a60a77c14394f6a.zip
Track IP configuration based on RTNL interface list
-rw-r--r--include/ipconfig.h2
-rw-r--r--src/connman.h6
-rw-r--r--src/device.c6
-rw-r--r--src/ipconfig.c31
-rw-r--r--src/rtnl.c48
5 files changed, 79 insertions, 14 deletions
diff --git a/include/ipconfig.h b/include/ipconfig.h
index c8062ba9..e347063a 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -47,7 +47,7 @@ enum connman_ipconfig_method {
struct connman_ipconfig;
-struct connman_ipconfig *connman_ipconfig_create(unsigned int index);
+struct connman_ipconfig *connman_ipconfig_create(int index);
struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig);
void connman_ipconfig_unref(struct connman_ipconfig *ipconfig);
diff --git a/src/connman.h b/src/connman.h
index a5fb7091..b9079777 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -93,11 +93,13 @@ int __connman_security_check_privilege(DBusMessage *message,
int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
+void __connman_ipconfig_update_link(struct connman_ipconfig *ipconfig,
+ unsigned flags, unsigned change);
void __connman_ipconfig_add_address(struct connman_ipconfig *ipconfig,
- const char *label, unsigned int prefixlen,
+ const char *label, unsigned char prefixlen,
const char *address, const char *broadcast);
void __connman_ipconfig_del_address(struct connman_ipconfig *ipconfig,
- const char *label, unsigned int prefixlen,
+ const char *label, unsigned char prefixlen,
const char *address, const char *broadcast);
const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method);
diff --git a/src/device.c b/src/device.c
index 751d1902..b238f46c 100644
--- a/src/device.c
+++ b/src/device.c
@@ -1030,10 +1030,10 @@ void connman_device_set_index(struct connman_device *device, int index)
{
device->element.index = index;
- if (device->ipconfig != NULL)
- connman_ipconfig_unref(device->ipconfig);
+ //if (device->ipconfig != NULL)
+ // connman_ipconfig_unref(device->ipconfig);
- device->ipconfig = connman_ipconfig_create(index);
+ //device->ipconfig = connman_ipconfig_create(index);
}
/**
diff --git a/src/ipconfig.c b/src/ipconfig.c
index e08f1e7c..dbf0bc83 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -29,7 +29,7 @@
struct connman_ipconfig {
gint refcount;
- unsigned int index;
+ int index;
char *interface;
enum connman_ipconfig_method method;
};
@@ -41,7 +41,7 @@ struct connman_ipconfig {
*
* Returns: a newly-allocated #connman_ipconfig structure
*/
-struct connman_ipconfig *connman_ipconfig_create(unsigned int index)
+struct connman_ipconfig *connman_ipconfig_create(int index)
{
struct connman_ipconfig *ipconfig;
@@ -51,12 +51,17 @@ struct connman_ipconfig *connman_ipconfig_create(unsigned int index)
if (ipconfig == NULL)
return NULL;
+ ipconfig->refcount = 1;
+
ipconfig->index = index;
ipconfig->interface = connman_inet_ifname(index);
DBG("ipconfig %p", ipconfig);
- __connman_rtnl_register_ipconfig(ipconfig);
+ //__connman_rtnl_register_ipconfig(ipconfig);
+
+ connman_info("%s {create} index %d", ipconfig->interface,
+ ipconfig->index);
return ipconfig;
}
@@ -83,7 +88,10 @@ struct connman_ipconfig *connman_ipconfig_ref(struct connman_ipconfig *ipconfig)
void connman_ipconfig_unref(struct connman_ipconfig *ipconfig)
{
if (g_atomic_int_dec_and_test(&ipconfig->refcount) == TRUE) {
- __connman_rtnl_unregister_ipconfig(ipconfig);
+ //__connman_rtnl_unregister_ipconfig(ipconfig);
+
+ connman_info("%s {remove} index %d", ipconfig->interface,
+ ipconfig->index);
g_free(ipconfig->interface);
g_free(ipconfig);
@@ -110,19 +118,26 @@ int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
return ipconfig->index;
}
+void __connman_ipconfig_update_link(struct connman_ipconfig *ipconfig,
+ unsigned flags, unsigned change)
+{
+ connman_info("%s {update} flags %u change %u", ipconfig->interface,
+ flags, change);
+}
+
void __connman_ipconfig_add_address(struct connman_ipconfig *ipconfig,
- const char *label, unsigned int prefixlen,
+ const char *label, unsigned char prefixlen,
const char *address, const char *broadcast)
{
- connman_info("%s {add} address %s/%d label %s", ipconfig->interface,
+ connman_info("%s {add} address %s/%u label %s", ipconfig->interface,
address, prefixlen, label);
}
void __connman_ipconfig_del_address(struct connman_ipconfig *ipconfig,
- const char *label, unsigned int prefixlen,
+ const char *label, unsigned char prefixlen,
const char *address, const char *broadcast)
{
- connman_info("%s {del} address %s/%d label %s", ipconfig->interface,
+ connman_info("%s {del} address %s/%u label %s", ipconfig->interface,
address, prefixlen, label);
}
diff --git a/src/rtnl.c b/src/rtnl.c
index 40b3ea93..70d65124 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -29,6 +29,7 @@
#include <arpa/inet.h>
#include <linux/if.h>
+#include <linux/if_arp.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
@@ -145,11 +146,43 @@ void connman_rtnl_unregister(struct connman_rtnl *rtnl)
rtnl_list = g_slist_remove(rtnl_list, rtnl);
}
+static GHashTable *ipconfig_hash = NULL;
+
+static void free_ipconfig(gpointer data)
+{
+ struct connman_ipconfig *ipconfig = data;
+
+ __connman_rtnl_unregister_ipconfig(ipconfig);
+
+ connman_ipconfig_unref(ipconfig);
+}
+
static void process_newlink(unsigned short type, int index,
unsigned flags, unsigned change)
{
+ struct connman_ipconfig *ipconfig;
GSList *list;
+ switch (type) {
+ case ARPHRD_ETHER:
+ case ARPHRD_LOOPBACK:
+ case ARPHRD_NONE:
+ ipconfig = g_hash_table_lookup(ipconfig_hash, &index);
+ if (ipconfig == NULL) {
+ ipconfig = connman_ipconfig_create(index);
+ if (ipconfig != NULL) {
+ g_hash_table_insert(ipconfig_hash,
+ &index, ipconfig);
+
+ __connman_rtnl_register_ipconfig(ipconfig);
+
+ __connman_ipconfig_update_link(ipconfig,
+ flags, change);
+ }
+ }
+ break;
+ }
+
for (list = rtnl_list; list; list = list->next) {
struct connman_rtnl *rtnl = list->data;
@@ -179,6 +212,14 @@ static void process_dellink(unsigned short type, int index,
if (rtnl->dellink)
rtnl->dellink(type, index, flags, change);
}
+
+ switch (type) {
+ case ARPHRD_ETHER:
+ case ARPHRD_LOOPBACK:
+ case ARPHRD_NONE:
+ g_hash_table_remove(ipconfig_hash, &index);
+ break;
+ }
}
static char *extract_gateway(struct rtmsg *msg, int bytes, int *index)
@@ -876,6 +917,9 @@ int __connman_rtnl_init(void)
DBG("");
+ ipconfig_hash = g_hash_table_new_full(g_int_hash, g_int_equal,
+ NULL, free_ipconfig);
+
sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
if (sk < 0)
return -1;
@@ -902,6 +946,7 @@ void __connman_rtnl_start(void)
{
DBG("");
+ connman_rtnl_send_getlink();
send_getaddr();
}
@@ -914,6 +959,9 @@ void __connman_rtnl_cleanup(void)
g_slist_free(ipconfig_list);
ipconfig_list = NULL;
+ g_hash_table_destroy(ipconfig_hash);
+ ipconfig_hash = NULL;
+
for (list = watch_list; list; list = list->next) {
struct watch_data *watch = list->data;