diff options
author | Marcel Holtmann <marcel@holtmann.org> | 2009-08-08 12:39:18 -0700 |
---|---|---|
committer | Marcel Holtmann <marcel@holtmann.org> | 2009-08-08 12:39:18 -0700 |
commit | b7d722c12182908d523234093a60a77c14394f6a (patch) | |
tree | 4d2072dc59aa1cdcfe76db7bb8f93480204cb16e | |
parent | afc99f394364a5bf1a60e558b5672f721d47a68e (diff) | |
download | connman-b7d722c12182908d523234093a60a77c14394f6a.tar.gz connman-b7d722c12182908d523234093a60a77c14394f6a.tar.bz2 connman-b7d722c12182908d523234093a60a77c14394f6a.zip |
Track IP configuration based on RTNL interface list
-rw-r--r-- | include/ipconfig.h | 2 | ||||
-rw-r--r-- | src/connman.h | 6 | ||||
-rw-r--r-- | src/device.c | 6 | ||||
-rw-r--r-- | src/ipconfig.c | 31 | ||||
-rw-r--r-- | src/rtnl.c | 48 |
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); } @@ -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; |