Integrate RTNL deeper into IP configuration tracking
authorMarcel Holtmann <marcel@holtmann.org>
Sat, 8 Aug 2009 21:18:17 +0000 (14:18 -0700)
committerMarcel Holtmann <marcel@holtmann.org>
Sat, 8 Aug 2009 21:18:17 +0000 (14:18 -0700)
include/rtnl.h
plugins/ethernet.c
plugins/mbm.c
plugins/wifi.c
src/connman.h
src/ipconfig.c
src/rtnl.c
src/udev-compat.c

index 4a60fb0..6c40f41 100644 (file)
@@ -57,7 +57,6 @@ struct connman_rtnl {
 int connman_rtnl_register(struct connman_rtnl *rtnl);
 void connman_rtnl_unregister(struct connman_rtnl *rtnl);
 
-int connman_rtnl_send_getlink(void);
 int connman_rtnl_send_getroute(void);
 
 #ifdef __cplusplus
index cce61c2..97e1d6a 100644 (file)
@@ -93,8 +93,6 @@ static int ethernet_probe(struct connman_device *device)
        ethernet->watch = connman_rtnl_add_newlink_watch(ethernet->index,
                                                ethernet_newlink, device);
 
-       //connman_rtnl_send_getlink();
-
        return 0;
 }
 
index de3da0c..d27a3f4 100644 (file)
@@ -224,8 +224,6 @@ static int mbm_probe(struct connman_device *device)
        data->watch = connman_rtnl_add_newlink_watch(index,
                                                mbm_newlink, device);
 
-       //connman_rtnl_send_getlink();
-
        return 0;
 }
 
index 039e117..4dfaf27 100644 (file)
@@ -133,8 +133,6 @@ static int wifi_probe(struct connman_device *device)
        wifi->watch = connman_rtnl_add_newlink_watch(wifi->index,
                                                        wifi_newlink, device);
 
-       //connman_rtnl_send_getlink();
-
        return 0;
 }
 
index b907977..28df972 100644 (file)
@@ -92,6 +92,8 @@ 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);
 
 void __connman_ipconfig_update_link(struct connman_ipconfig *ipconfig,
                                        unsigned flags, unsigned change);
@@ -358,6 +360,3 @@ void __connman_rtnl_start(void);
 void __connman_rtnl_cleanup(void);
 
 int __connman_rtnl_send(const void *buf, size_t len);
-
-int __connman_rtnl_register_ipconfig(struct connman_ipconfig *ipconfig);
-void __connman_rtnl_unregister_ipconfig(struct connman_ipconfig *ipconfig);
index 764836a..70131ad 100644 (file)
@@ -37,6 +37,7 @@ struct connman_ipconfig {
        gint refcount;
        int index;
        char *interface;
+       unsigned short type;
        unsigned int flags;
        enum connman_ipconfig_method method;
 };
@@ -65,8 +66,6 @@ struct connman_ipconfig *connman_ipconfig_create(int index)
 
        DBG("ipconfig %p", ipconfig);
 
-       //__connman_rtnl_register_ipconfig(ipconfig);
-
        connman_info("%s {create} index %d", ipconfig->interface,
                                                        ipconfig->index);
 
@@ -95,8 +94,6 @@ 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_info("%s {remove} index %d", ipconfig->interface,
                                                        ipconfig->index);
 
@@ -125,6 +122,16 @@ 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;
+}
+
 void __connman_ipconfig_update_link(struct connman_ipconfig *ipconfig,
                                        unsigned flags, unsigned change)
 {
index d7b317c..bec9674 100644 (file)
@@ -47,6 +47,28 @@ 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
@@ -60,6 +82,7 @@ static unsigned int watch_id = 0;
 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);
@@ -76,6 +99,14 @@ 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)
+                       callback(flags, 0, user_data);
+       }
+
        return watch->id;
 }
 
@@ -105,6 +136,23 @@ void connman_rtnl_remove_watch(unsigned int id)
        }
 }
 
+static void trigger_newlink(gpointer key, gpointer value, gpointer 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);
+
+               rtnl->newlink(type, index, flags, 0);
+       }
+}
+
 static GSList *rtnl_list = NULL;
 
 static gint compare_priority(gconstpointer a, gconstpointer b)
@@ -130,6 +178,8 @@ 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_newlink, rtnl);
+
        return 0;
 }
 
@@ -146,17 +196,6 @@ 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)
 {
@@ -175,7 +214,7 @@ static void process_newlink(unsigned short type, int index,
                                g_hash_table_insert(ipconfig_hash,
                                        GINT_TO_POINTER(index), ipconfig);
 
-                               __connman_rtnl_register_ipconfig(ipconfig);
+                               register_ipconfig(ipconfig);
                        }
                }
 
@@ -318,8 +357,6 @@ static void extract_addr(struct ifaddrmsg *msg, int bytes,
        }
 }
 
-static GSList *ipconfig_list = NULL;
-
 static void process_newaddr(int family, int prefixlen, int index,
                                        struct ifaddrmsg *msg, int bytes)
 {
@@ -364,22 +401,6 @@ static void process_deladdr(int family, int prefixlen, int index,
        }
 }
 
-int __connman_rtnl_register_ipconfig(struct connman_ipconfig *ipconfig)
-{
-       DBG("ipconfig %p", ipconfig);
-
-       ipconfig_list = g_slist_append(ipconfig_list, ipconfig);
-
-       return 0;
-}
-
-void __connman_rtnl_unregister_ipconfig(struct connman_ipconfig *ipconfig)
-{
-       DBG("ipconfig %p", ipconfig);
-
-       ipconfig_list = g_slist_remove(ipconfig_list, ipconfig);
-}
-
 static inline void print_inet(struct rtattr *attr, const char *name, int family)
 {
        if (family == AF_INET) {
@@ -852,7 +873,7 @@ static gboolean netlink_event(GIOChannel *chan,
        return TRUE;
 }
 
-int connman_rtnl_send_getlink(void)
+static int send_getlink(void)
 {
        struct rtnl_request *req;
 
@@ -948,7 +969,7 @@ void __connman_rtnl_start(void)
 {
        DBG("");
 
-       connman_rtnl_send_getlink();
+       send_getlink();
        send_getaddr();
        connman_rtnl_send_getroute();
 }
index 3ac069b..238c822 100644 (file)
@@ -135,8 +135,6 @@ int __connman_udev_init(void)
 void __connman_udev_start(void)
 {
        DBG("");
-
-       connman_rtnl_send_getlink();
 }
 
 void __connman_udev_cleanup(void)