Add more detailed tracking of IP devices
authorMarcel Holtmann <marcel@holtmann.org>
Mon, 10 Aug 2009 07:57:10 +0000 (00:57 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Mon, 10 Aug 2009 07:57:10 +0000 (00:57 -0700)
include/ipconfig.h
src/connman.h
src/device.c
src/ipconfig.c
src/main.c
src/rtnl.c

index ad7cbc6..8477ede 100644 (file)
@@ -61,8 +61,11 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig);
 void *connman_ipconfig_get_data(struct connman_ipconfig *ipconfig);
 void connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data);
 
+int connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
+const char *connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig);
+
 void connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
-                                       struct connman_ipconfig_ops *ops);
+                               const struct connman_ipconfig_ops *ops);
 
 int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
                                        enum connman_ipconfig_method method);
index 1ba327f..5ea9ea4 100644 (file)
@@ -91,25 +91,26 @@ int __connman_security_check_privilege(DBusMessage *message,
 
 #include <connman/ipconfig.h>
 
-int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig);
-unsigned short __connman_ipconfig_get_type(struct connman_ipconfig *ipconfig);
-unsigned int __connman_ipconfig_get_flags(struct connman_ipconfig *ipconfig);
-const char *__connman_ipconfig_get_gateway(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 char prefixlen,
-                               const char *address, const char *broadcast);
-void __connman_ipconfig_del_address(struct connman_ipconfig *ipconfig,
-                               const char *label, unsigned char prefixlen,
-                               const char *address, const char *broadcast);
-void __connman_ipconfig_add_route(struct connman_ipconfig *ipconfig,
-                               unsigned char scope, const char *destination,
-                                                       const char *gateway);
-void __connman_ipconfig_del_route(struct connman_ipconfig *ipconfig,
-                               unsigned char scope, const char *destination,
-                                                       const char *gateway);
+int __connman_ipconfig_init(void);
+void __connman_ipconfig_cleanup(void);
+
+void __connman_ipconfig_newlink(int index, unsigned short type,
+                                                       unsigned int flags);
+void __connman_ipconfig_dellink(int index);
+void __connman_ipconfig_newaddr(int index, const char *label,
+                               unsigned char prefixlen, const char *address);
+void __connman_ipconfig_deladdr(int index, const char *label,
+                               unsigned char prefixlen, const char *address);
+void __connman_ipconfig_newroute(int index, unsigned char scope,
+                                       const char *dst, const char *gateway);
+void __connman_ipconfig_delroute(int index, unsigned char scope,
+                                       const char *dst, const char *gateway);
+
+void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
+                                                       void *user_data);
+unsigned short __connman_ipconfig_get_type(int index);
+unsigned int __connman_ipconfig_get_flags(int index);
+const char *__connman_ipconfig_get_gateway(int index);
 
 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method);
 enum connman_ipconfig_method __connman_ipconfig_string2method(const char *method);
index b238f46..b29fb6b 100644 (file)
@@ -1019,6 +1019,33 @@ const char *connman_device_get_path(struct connman_device *device)
        return device->element.path;
 }
 
+static void device_up(struct connman_ipconfig *ipconfig)
+{
+       connman_info("%s up", connman_ipconfig_get_ifname(ipconfig));
+}
+
+static void device_down(struct connman_ipconfig *ipconfig)
+{
+       connman_info("%s down", connman_ipconfig_get_ifname(ipconfig));
+}
+
+static void device_lower_up(struct connman_ipconfig *ipconfig)
+{
+       connman_info("%s lower up", connman_ipconfig_get_ifname(ipconfig));
+}
+
+static void device_lower_down(struct connman_ipconfig *ipconfig)
+{
+        connman_info("%s lower down", connman_ipconfig_get_ifname(ipconfig));
+}
+
+static const struct connman_ipconfig_ops device_ops = {
+       .up             = device_up,
+       .down           = device_down,
+       .lower_up       = device_lower_up,
+       .lower_down     = device_lower_down,
+};
+
 /**
  * connman_device_set_index:
  * @device: device structure
@@ -1030,10 +1057,16 @@ 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) {
+               if (index == connman_ipconfig_get_index(device->ipconfig))
+                       return;
+
+               connman_ipconfig_unref(device->ipconfig);
+       }
+
+       device->ipconfig = connman_ipconfig_create(index);
 
-       //device->ipconfig = connman_ipconfig_create(index);
+       connman_ipconfig_set_ops(device->ipconfig, &device_ops);
 }
 
 /**
index 2fd3559..d5f3a10 100644 (file)
@@ -24,6 +24,7 @@
 #endif
 
 #include <net/if.h>
+#include <net/if_arp.h>
 
 #ifndef IFF_LOWER_UP
 #define IFF_LOWER_UP   0x10000
@@ -38,26 +39,34 @@ struct connman_ipaddress {
        char *address;
 };
 
-struct connman_ipconfig {
-       gint refcount;
+struct connman_ipdevice {
        int index;
-       char *interface;
+       char *ifname;
        unsigned short type;
        unsigned int flags;
 
-       struct connman_ipconfig_ops *ops;
+       GSList *address_list;
+       char *gateway;
+};
+
+struct connman_ipconfig {
+       gint refcount;
+       int index;
+
+       const struct connman_ipconfig_ops *ops;
        void *ops_data;
 
        enum connman_ipconfig_method method;
-       GSList *address_list;
-       char *gateway;
 };
 
-static void free_address_list(struct connman_ipconfig *ipconfig)
+static GHashTable *ipdevice_hash = NULL;
+static GList *ipconfig_list = NULL;
+
+static void free_address_list(struct connman_ipdevice *ipdevice)
 {
        GSList *list;
 
-       for (list = ipconfig->address_list; list; list = list->next) {
+       for (list = ipdevice->address_list; list; list = list->next) {
                struct connman_ipaddress *ipaddress = list->data;
 
                g_free(ipaddress->address);
@@ -65,16 +74,16 @@ static void free_address_list(struct connman_ipconfig *ipconfig)
                list->data = NULL;
        }
 
-       g_slist_free(ipconfig->address_list);
-       ipconfig->address_list = NULL;
+       g_slist_free(ipdevice->address_list);
+       ipdevice->address_list = NULL;
 }
 
-static struct connman_ipaddress *find_ipaddress(struct connman_ipconfig *ipconfig,
+static struct connman_ipaddress *find_ipaddress(struct connman_ipdevice *ipdevice,
                                unsigned char prefixlen, const char *address)
 {
        GSList *list;
 
-       for (list = ipconfig->address_list; list; list = list->next) {
+       for (list = ipdevice->address_list; list; list = list->next) {
                struct connman_ipaddress *ipaddress = list->data;
 
                if (g_strcmp0(ipaddress->address, address) == 0 &&
@@ -85,6 +94,310 @@ static struct connman_ipaddress *find_ipaddress(struct connman_ipconfig *ipconfi
        return NULL;
 }
 
+static const char *type2str(unsigned short type)
+{
+       switch (type) {
+       case ARPHRD_ETHER:
+               return "ETHER";
+       case ARPHRD_LOOPBACK:
+               return "LOOPBACK";
+       case ARPHRD_PPP:
+               return "PPP";
+       case ARPHRD_NONE:
+               return "NONE";
+       case ARPHRD_VOID:
+               return "VOID";
+       }
+
+       return "";
+}
+
+static const char *scope2str(unsigned char scope)
+{
+       switch (scope) {
+       case 0:
+               return "UNIVERSE";
+       case 253:
+               return "LINK";
+       }
+
+       return "";
+}
+
+static void free_ipdevice(gpointer data)
+{
+       struct connman_ipdevice *ipdevice = data;
+
+       connman_info("%s {remove} index %d", ipdevice->ifname,
+                                                       ipdevice->index);
+
+       free_address_list(ipdevice);
+       g_free(ipdevice->gateway);
+
+       g_free(ipdevice->ifname);
+       g_free(ipdevice);
+}
+
+void __connman_ipconfig_newlink(int index, unsigned short type,
+                                                       unsigned int flags)
+{
+       struct connman_ipdevice *ipdevice;
+       GList *list;
+       GString *str;
+       gboolean up = FALSE, down = FALSE;
+       gboolean lower_up = FALSE, lower_down = FALSE;
+
+       DBG("index %d", index);
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice != NULL)
+               goto update;
+
+       ipdevice = g_try_new0(struct connman_ipdevice, 1);
+       if (ipdevice == NULL)
+               return;
+
+       ipdevice->index = index;
+       ipdevice->ifname = connman_inet_ifname(index);
+       ipdevice->type = type;
+
+       g_hash_table_insert(ipdevice_hash, GINT_TO_POINTER(index), ipdevice);
+
+       connman_info("%s {create} index %d type %d <%s>", ipdevice->ifname,
+                                               index, type, type2str(type));
+
+update:
+       if (flags == ipdevice->flags)
+               return;
+
+       if ((ipdevice->flags & IFF_UP) != (flags & IFF_UP)) {
+               if (flags & IFF_UP)
+                       up = TRUE;
+               else
+                       down = TRUE;
+       }
+
+       if ((ipdevice->flags & (IFF_RUNNING | IFF_LOWER_UP)) !=
+                               (flags & (IFF_RUNNING | IFF_LOWER_UP))) {
+               if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) ==
+                                       (IFF_RUNNING | IFF_LOWER_UP))
+                       lower_up = TRUE;
+               else if ((flags & (IFF_RUNNING | IFF_LOWER_UP)) == 0)
+                       lower_down = TRUE;
+       }
+
+       ipdevice->flags = flags;
+
+       str = g_string_new(NULL);
+       if (str == NULL)
+               return;
+
+       if (flags & IFF_UP)
+               g_string_append(str, "UP");
+       else
+               g_string_append(str, "DOWN");
+
+       if (flags & IFF_RUNNING)
+               g_string_append(str, ",RUNNING");
+
+       if (flags & IFF_LOWER_UP)
+               g_string_append(str, ",LOWER_UP");
+
+       connman_info("%s {update} flags %u <%s>", ipdevice->ifname,
+                                                       flags, str->str);
+
+       g_string_free(str, TRUE);
+
+       for (list = g_list_first(ipconfig_list); list;
+                                               list = g_list_next(list)) {
+               struct connman_ipconfig *ipconfig = list->data;
+
+               if (index != ipconfig->index)
+                       continue;
+
+               if (ipconfig->ops) {
+                       if (up == TRUE && ipconfig->ops->up)
+                               ipconfig->ops->up(ipconfig);
+                       if (lower_up == TRUE && ipconfig->ops->lower_up)
+                               ipconfig->ops->lower_up(ipconfig);
+
+                       if (lower_down == TRUE && ipconfig->ops->lower_down)
+                               ipconfig->ops->lower_down(ipconfig);
+                       if (down == TRUE && ipconfig->ops->down)
+                               ipconfig->ops->down(ipconfig);
+               }
+       }
+}
+
+void __connman_ipconfig_dellink(int index)
+{
+       GList *list;
+
+       DBG("index %d", index);
+
+       for (list = g_list_first(ipconfig_list); list;
+                                               list = g_list_next(list)) {
+               struct connman_ipconfig *ipconfig = list->data;
+
+               if (index != ipconfig->index)
+                       continue;
+
+               ipconfig->index = -1;
+
+               if (ipconfig->ops && ipconfig->ops->lower_down)
+                       ipconfig->ops->lower_down(ipconfig);
+               if (ipconfig->ops && ipconfig->ops->down)
+                       ipconfig->ops->down(ipconfig);
+       }
+
+       g_hash_table_remove(ipdevice_hash, GINT_TO_POINTER(index));
+}
+
+void __connman_ipconfig_newaddr(int index, const char *label,
+                               unsigned char prefixlen, const char *address)
+{
+       struct connman_ipdevice *ipdevice;
+       struct connman_ipaddress *ipaddress;
+
+       DBG("index %d", index);
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return;
+
+       ipaddress = g_try_new0(struct connman_ipaddress, 1);
+       if (ipaddress == NULL)
+               return;
+
+       ipaddress->prefixlen = prefixlen;
+       ipaddress->address = g_strdup(address);
+
+       ipdevice->address_list = g_slist_append(ipdevice->address_list,
+                                                               ipaddress);
+
+       connman_info("%s {add} address %s/%u label %s", ipdevice->ifname,
+                                               address, prefixlen, label);
+}
+
+void __connman_ipconfig_deladdr(int index, const char *label,
+                               unsigned char prefixlen, const char *address)
+{
+       struct connman_ipdevice *ipdevice;
+       struct connman_ipaddress *ipaddress;
+
+       DBG("index %d", index);
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return;
+
+       ipaddress = find_ipaddress(ipdevice, prefixlen, address);
+       if (ipaddress == NULL)
+               return;
+
+       ipdevice->address_list = g_slist_remove(ipdevice->address_list,
+                                                               ipaddress);
+
+       g_free(ipaddress->address);
+       g_free(ipaddress);
+
+       connman_info("%s {del} address %s/%u label %s", ipdevice->ifname,
+                                               address, prefixlen, label);
+}
+
+void __connman_ipconfig_newroute(int index, unsigned char scope,
+                                       const char *dst, const char *gateway)
+{
+       struct connman_ipdevice *ipdevice;
+
+       DBG("index %d", index);
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return;
+
+       if (scope == 0 && g_strcmp0(dst, "0.0.0.0") == 0) {
+               g_free(ipdevice->gateway);
+               ipdevice->gateway = g_strdup(gateway);
+       }
+
+       connman_info("%s {add} route %s gw %s scope %u <%s>",
+                                       ipdevice->ifname, dst, gateway,
+                                               scope, scope2str(scope));
+}
+
+void __connman_ipconfig_delroute(int index, unsigned char scope,
+                                       const char *dst, const char *gateway)
+{
+       struct connman_ipdevice *ipdevice;
+
+       DBG("index %d", index);
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return;
+
+       if (scope == 0 && g_strcmp0(dst, "0.0.0.0") == 0) {
+               g_free(ipdevice->gateway);
+               ipdevice->gateway = NULL;
+       }
+
+       connman_info("%s {del} route %s gw %s scope %u <%s>",
+                                       ipdevice->ifname, dst, gateway,
+                                               scope, scope2str(scope));
+}
+
+void __connman_ipconfig_foreach(void (*function) (int index, void *user_data),
+                                                       void *user_data)
+{
+       GList *list, *keys;
+
+       keys = g_hash_table_get_keys(ipdevice_hash);
+       if (keys == NULL)
+               return;
+
+       for (list = g_list_first(keys); list; list = g_list_next(list)) {
+               int index = GPOINTER_TO_INT(list->data);
+
+               function(index, user_data);
+       }
+
+       g_list_free(keys);
+}
+
+unsigned short __connman_ipconfig_get_type(int index)
+{
+       struct connman_ipdevice *ipdevice;
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return ARPHRD_VOID;
+
+       return ipdevice->type;
+}
+
+unsigned int __connman_ipconfig_get_flags(int index)
+{
+       struct connman_ipdevice *ipdevice;
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return 0;
+
+       return ipdevice->flags;
+}
+
+const char *__connman_ipconfig_get_gateway(int index)
+{
+       struct connman_ipdevice *ipdevice;
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(index));
+       if (ipdevice == NULL)
+               return NULL;
+
+       return ipdevice->gateway;
+}
+
 /**
  * connman_ipconfig_create:
  *
@@ -96,7 +409,7 @@ struct connman_ipconfig *connman_ipconfig_create(int index)
 {
        struct connman_ipconfig *ipconfig;
 
-       DBG("");
+       DBG("index %d", index);
 
        ipconfig = g_try_new0(struct connman_ipconfig, 1);
        if (ipconfig == NULL)
@@ -105,12 +418,10 @@ struct connman_ipconfig *connman_ipconfig_create(int index)
        ipconfig->refcount = 1;
 
        ipconfig->index = index;
-       ipconfig->interface = connman_inet_ifname(index);
 
        DBG("ipconfig %p", ipconfig);
 
-       connman_info("%s {create} index %d", ipconfig->interface,
-                                                       ipconfig->index);
+       ipconfig_list = g_list_append(ipconfig_list, ipconfig);
 
        return ipconfig;
 }
@@ -137,14 +448,8 @@ 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_info("%s {remove} index %d", ipconfig->interface,
-                                                       ipconfig->index);
-
-               g_free(ipconfig->gateway);
+               ipconfig_list = g_list_remove(ipconfig_list, ipconfig);
 
-               free_address_list(ipconfig);
-
-               g_free(ipconfig->interface);
                g_free(ipconfig);
        }
 }
@@ -173,6 +478,38 @@ void connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
 }
 
 /**
+ * connman_ipconfig_get_index:
+ * @ipconfig: ipconfig structure
+ *
+ * Get interface index
+ */
+int connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
+{
+       return ipconfig->index;
+}
+
+/**
+ * connman_ipconfig_get_ifname:
+ * @ipconfig: ipconfig structure
+ *
+ * Get interface name
+ */
+const char *connman_ipconfig_get_ifname(struct connman_ipconfig *ipconfig)
+{
+       struct connman_ipdevice *ipdevice;
+
+       if (ipconfig->index < 0)
+               return NULL;
+
+       ipdevice = g_hash_table_lookup(ipdevice_hash,
+                                       GINT_TO_POINTER(ipconfig->index));
+       if (ipdevice == NULL)
+               return NULL;
+
+       return ipdevice->ifname;
+}
+
+/**
  * connman_ipconfig_set_ops:
  * @ipconfig: ipconfig structure
  * @ops: operation callbacks
@@ -180,7 +517,7 @@ void connman_ipconfig_set_data(struct connman_ipconfig *ipconfig, void *data)
  * Set the operation callbacks
  */
 void connman_ipconfig_set_ops(struct connman_ipconfig *ipconfig,
-                                       struct connman_ipconfig_ops *ops)
+                               const struct connman_ipconfig_ops *ops)
 {
        ipconfig->ops = ops;
 }
@@ -200,137 +537,6 @@ int connman_ipconfig_set_method(struct connman_ipconfig *ipconfig,
        return 0;
 }
 
-int __connman_ipconfig_get_index(struct connman_ipconfig *ipconfig)
-{
-       return ipconfig->index;
-}
-
-unsigned short __connman_ipconfig_get_type(struct connman_ipconfig *ipconfig)
-{
-       return ipconfig->type;
-}
-
-unsigned int __connman_ipconfig_get_flags(struct connman_ipconfig *ipconfig)
-{
-       return ipconfig->flags;
-}
-
-const char *__connman_ipconfig_get_gateway(struct connman_ipconfig *ipconfig)
-{
-       return ipconfig->gateway;
-}
-
-void __connman_ipconfig_update_link(struct connman_ipconfig *ipconfig,
-                                       unsigned flags, unsigned change)
-{
-       GString *str;
-
-       if (flags == ipconfig->flags)
-               return;
-
-       ipconfig->flags = flags;
-
-       str = g_string_new(NULL);
-       if (str == NULL)
-               return;
-
-       if (flags & IFF_UP)
-               g_string_append(str, "UP");
-       else
-               g_string_append(str, "DOWN");
-
-       if (flags & IFF_RUNNING)
-               g_string_append(str, ",RUNNING");
-
-       if (flags & IFF_LOWER_UP)
-               g_string_append(str, ",LOWER_UP");
-
-       connman_info("%s {update} flags %u change %u <%s>",
-                               ipconfig->interface, flags, change, str->str);
-
-       g_string_free(str, TRUE);
-}
-
-void __connman_ipconfig_add_address(struct connman_ipconfig *ipconfig,
-                               const char *label, unsigned char prefixlen,
-                               const char *address, const char *broadcast)
-{
-       struct connman_ipaddress *ipaddress;
-
-       ipaddress = g_try_new0(struct connman_ipaddress, 1);
-       if (ipaddress == NULL)
-               return;
-
-       ipaddress->prefixlen = prefixlen;
-       ipaddress->address = g_strdup(address);
-
-       ipconfig->address_list = g_slist_append(ipconfig->address_list,
-                                                               ipaddress);
-
-       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 char prefixlen,
-                               const char *address, const char *broadcast)
-{
-       struct connman_ipaddress *ipaddress;
-
-       ipaddress = find_ipaddress(ipconfig, prefixlen, address);
-       if (ipaddress == NULL)
-               return;
-
-       ipconfig->address_list = g_slist_remove(ipconfig->address_list,
-                                                               ipaddress);
-
-       g_free(ipaddress->address);
-       g_free(ipaddress);
-
-       connman_info("%s {del} address %s/%u label %s", ipconfig->interface,
-                                               address, prefixlen, label);
-}
-
-static const char *scope2str(unsigned char scope)
-{
-       switch (scope) {
-       case 0:
-               return "UNIVERSE";
-       case 253:
-               return "LINK";
-       }
-
-       return "";
-}
-
-void __connman_ipconfig_add_route(struct connman_ipconfig *ipconfig,
-                               unsigned char scope, const char *destination,
-                                                       const char *gateway)
-{
-       if (scope == 0 && g_strcmp0(destination, "0.0.0.0") == 0) {
-               g_free(ipconfig->gateway);
-               ipconfig->gateway = g_strdup(gateway);
-       }
-
-       connman_info("%s {add} route %s gw %s scope %u <%s>",
-                                       ipconfig->interface, destination,
-                                       gateway, scope, scope2str(scope));
-}
-
-void __connman_ipconfig_del_route(struct connman_ipconfig *ipconfig,
-                               unsigned char scope, const char *destination,
-                                                       const char *gateway)
-{
-       if (scope == 0 && g_strcmp0(destination, "0.0.0.0") == 0) {
-               g_free(ipconfig->gateway);
-               ipconfig->gateway = NULL;
-       }
-
-       connman_info("%s {del} route %s gw %s scope %u <%s>",
-                                       ipconfig->interface, destination,
-                                       gateway, scope, scope2str(scope));
-}
-
 const char *__connman_ipconfig_method2string(enum connman_ipconfig_method method)
 {
        switch (method) {
@@ -466,3 +672,21 @@ void connman_ipconfig_driver_unregister(struct connman_ipconfig_driver *driver)
 
        driver_list = g_slist_remove(driver_list, driver);
 }
+
+int __connman_ipconfig_init(void)
+{
+       DBG("");
+
+       ipdevice_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
+                                                       NULL, free_ipdevice);
+
+       return 0;
+}
+
+void __connman_ipconfig_cleanup(void)
+{
+       DBG("");
+
+       g_hash_table_destroy(ipdevice_hash);
+       ipdevice_hash = NULL;
+}
index 3e77472..ac62312 100644 (file)
@@ -205,6 +205,7 @@ int main(int argc, char *argv[])
        __connman_profile_init(conn);
 
        __connman_resolver_init();
+       __connman_ipconfig_init();
        __connman_rtnl_init();
        __connman_udev_init();
        __connman_task_init();
@@ -235,6 +236,7 @@ int main(int argc, char *argv[])
        __connman_task_cleanup();
        __connman_udev_cleanup();
        __connman_rtnl_cleanup();
+       __connman_ipconfig_cleanup();
        __connman_resolver_cleanup();
 
        __connman_profile_cleanup();
index f0a9dc6..ec163a0 100644 (file)
@@ -50,28 +50,6 @@ struct watch_data {
 static GSList *watch_list = NULL;
 static unsigned int watch_id = 0;
 
-static GHashTable *ipconfig_hash = NULL;
-static GSList *ipconfig_list = NULL;
-
-static void register_ipconfig(struct connman_ipconfig *ipconfig)
-{
-       ipconfig_list = g_slist_append(ipconfig_list, ipconfig);
-}
-
-static void unregister_ipconfig(struct connman_ipconfig *ipconfig)
-{
-       ipconfig_list = g_slist_remove(ipconfig_list, ipconfig);
-}
-
-static void free_ipconfig(gpointer data)
-{
-       struct connman_ipconfig *ipconfig = data;
-
-       unregister_ipconfig(ipconfig);
-
-       connman_ipconfig_unref(ipconfig);
-}
-
 /**
  * connman_rtnl_add_newlink_watch:
  * @index: network device index
@@ -85,7 +63,6 @@ static void free_ipconfig(gpointer data)
 unsigned int connman_rtnl_add_newlink_watch(int index,
                        connman_rtnl_link_cb_t callback, void *user_data)
 {
-       struct connman_ipconfig *ipconfig;
        struct watch_data *watch;
 
        watch = g_try_new0(struct watch_data, 1);
@@ -102,11 +79,10 @@ unsigned int connman_rtnl_add_newlink_watch(int index,
 
        DBG("id %d", watch->id);
 
-       ipconfig = g_hash_table_lookup(ipconfig_hash, GINT_TO_POINTER(index));
-       if (ipconfig != NULL) {
-               unsigned int flags = __connman_ipconfig_get_flags(ipconfig);
+       if (callback) {
+               unsigned int flags = __connman_ipconfig_get_flags(index);
 
-               if (callback)
+               if (flags > 0)
                        callback(flags, 0, user_data);
        }
 
@@ -139,24 +115,19 @@ void connman_rtnl_remove_watch(unsigned int id)
        }
 }
 
-static void trigger_rtnl(gpointer key, gpointer value, gpointer user_data)
+static void trigger_rtnl(int index, void *user_data)
 {
        struct connman_rtnl *rtnl = user_data;
-       struct connman_ipconfig *ipconfig = value;
-       int index = GPOINTER_TO_INT(key);
-
-       if (index < 0 || ipconfig == NULL)
-               return;
 
        if (rtnl->newlink) {
-               unsigned short type = __connman_ipconfig_get_type(ipconfig);
-               unsigned int flags = __connman_ipconfig_get_flags(ipconfig);
+               unsigned short type = __connman_ipconfig_get_type(index);
+               unsigned int flags = __connman_ipconfig_get_flags(index);
 
                rtnl->newlink(type, index, flags, 0);
        }
 
        if (rtnl->newgateway) {
-               const char *gateway = __connman_ipconfig_get_gateway(ipconfig);
+               const char *gateway = __connman_ipconfig_get_gateway(index);
 
                if (gateway != NULL)
                        rtnl->newgateway(index, gateway);
@@ -188,7 +159,7 @@ int connman_rtnl_register(struct connman_rtnl *rtnl)
        rtnl_list = g_slist_insert_sorted(rtnl_list, rtnl,
                                                        compare_priority);
 
-       g_hash_table_foreach(ipconfig_hash, trigger_rtnl, rtnl);
+       __connman_ipconfig_foreach(trigger_rtnl, rtnl);
 
        return 0;
 }
@@ -209,28 +180,13 @@ void connman_rtnl_unregister(struct connman_rtnl *rtnl)
 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,
-                                               GINT_TO_POINTER(index));
-               if (ipconfig == NULL) {
-                       ipconfig = connman_ipconfig_create(index);
-                       if (ipconfig != NULL) {
-                               g_hash_table_insert(ipconfig_hash,
-                                       GINT_TO_POINTER(index), ipconfig);
-
-                               register_ipconfig(ipconfig);
-                       }
-               }
-
-               if (ipconfig != NULL)
-                       __connman_ipconfig_update_link(ipconfig,
-                                                       flags, change);
+               __connman_ipconfig_newlink(index, type, flags);
                break;
        }
 
@@ -268,7 +224,7 @@ static void process_dellink(unsigned short type, int index,
        case ARPHRD_ETHER:
        case ARPHRD_LOOPBACK:
        case ARPHRD_NONE:
-               g_hash_table_remove(ipconfig_hash, GINT_TO_POINTER(index));
+               __connman_ipconfig_dellink(index);
                break;
        }
 }
@@ -307,7 +263,6 @@ static void extract_addr(struct ifaddrmsg *msg, int bytes,
 static void process_newaddr(unsigned char family, unsigned char prefixlen,
                                int index, struct ifaddrmsg *msg, int bytes)
 {
-       GSList *list;
        const char *label;
        struct in_addr address = { INADDR_ANY };
 
@@ -316,21 +271,13 @@ static void process_newaddr(unsigned char family, unsigned char prefixlen,
 
        extract_addr(msg, bytes, &label, &address, NULL, NULL);
 
-       for (list = ipconfig_list; list; list = list->next) {
-               struct connman_ipconfig *ipconfig = list->data;
-
-               if (__connman_ipconfig_get_index(ipconfig) != index)
-                       continue;
-
-               __connman_ipconfig_add_address(ipconfig, label, prefixlen,
-                                               inet_ntoa(address), NULL);
-       }
+       __connman_ipconfig_newaddr(index, label,
+                                       prefixlen, inet_ntoa(address));
 }
 
 static void process_deladdr(unsigned char family, unsigned char prefixlen,
                                int index, struct ifaddrmsg *msg, int bytes)
 {
-       GSList *list;
        const char *label;
        struct in_addr address = { INADDR_ANY };
 
@@ -339,15 +286,8 @@ static void process_deladdr(unsigned char family, unsigned char prefixlen,
 
        extract_addr(msg, bytes, &label, &address, NULL, NULL);
 
-       for (list = ipconfig_list; list; list = list->next) {
-               struct connman_ipconfig *ipconfig = list->data;
-
-               if (__connman_ipconfig_get_index(ipconfig) != index)
-                       continue;
-
-               __connman_ipconfig_del_address(ipconfig, label, prefixlen,
-                                               inet_ntoa(address), NULL);
-       }
+       __connman_ipconfig_deladdr(index, label,
+                                       prefixlen, inet_ntoa(address));
 }
 
 static void extract_route(struct rtmsg *msg, int bytes, int *index,
@@ -391,15 +331,7 @@ static void process_newroute(unsigned char family, unsigned char scope,
        inet_ntop(family, &dst, dststr, sizeof(dststr));
        inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
 
-       for (list = ipconfig_list; list; list = list->next) {
-               struct connman_ipconfig *ipconfig = list->data;
-
-               if (__connman_ipconfig_get_index(ipconfig) != index)
-                       continue;
-
-               __connman_ipconfig_add_route(ipconfig, scope,
-                                                       dststr, gatewaystr);
-       }
+       __connman_ipconfig_newroute(index, scope, dststr, gatewaystr);
 
        if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
                return;
@@ -428,15 +360,7 @@ static void process_delroute(unsigned char family, unsigned char scope,
        inet_ntop(family, &dst, dststr, sizeof(dststr));
        inet_ntop(family, &gateway, gatewaystr, sizeof(gatewaystr));
 
-       for (list = ipconfig_list; list; list = list->next) {
-               struct connman_ipconfig *ipconfig = list->data;
-
-               if (__connman_ipconfig_get_index(ipconfig) != index)
-                       continue;
-
-               __connman_ipconfig_del_route(ipconfig, scope,
-                                                       dststr, gatewaystr);
-       }
+       __connman_ipconfig_delroute(index, scope, dststr, gatewaystr);
 
        if (scope != RT_SCOPE_UNIVERSE || dst.s_addr != INADDR_ANY)
                return;
@@ -982,9 +906,6 @@ int __connman_rtnl_init(void)
 
        DBG("");
 
-       ipconfig_hash = g_hash_table_new_full(g_direct_hash, g_direct_equal,
-                                                       NULL, free_ipconfig);
-
        sk = socket(PF_NETLINK, SOCK_DGRAM, NETLINK_ROUTE);
        if (sk < 0)
                return -1;
@@ -1022,12 +943,6 @@ void __connman_rtnl_cleanup(void)
 
        DBG("");
 
-       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;