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 /src/rtnl.c | |
parent | afc99f394364a5bf1a60e558b5672f721d47a68e (diff) | |
download | connman-b7d722c12182908d523234093a60a77c14394f6a.tar.gz connman-b7d722c12182908d523234093a60a77c14394f6a.tar.bz2 connman-b7d722c12182908d523234093a60a77c14394f6a.zip |
Track IP configuration based on RTNL interface list
Diffstat (limited to 'src/rtnl.c')
-rw-r--r-- | src/rtnl.c | 48 |
1 files changed, 48 insertions, 0 deletions
@@ -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; |