summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarcel Holtmann <marcel@holtmann.org>2009-08-10 00:57:10 -0700
committerMarcel Holtmann <marcel@holtmann.org>2009-08-10 00:57:10 -0700
commit6b8f85ab661243c7a34da9aaf10de464ad752308 (patch)
tree8cb4798c95039f28c79692f56b1265facadc43cc
parent32ad68a235d4ee69fae7f797c2052b7bd8b4ad1e (diff)
downloadconnman-6b8f85ab661243c7a34da9aaf10de464ad752308.tar.gz
connman-6b8f85ab661243c7a34da9aaf10de464ad752308.tar.bz2
connman-6b8f85ab661243c7a34da9aaf10de464ad752308.zip
Add more detailed tracking of IP devices
-rw-r--r--include/ipconfig.h5
-rw-r--r--src/connman.h39
-rw-r--r--src/device.c39
-rw-r--r--src/ipconfig.c534
-rw-r--r--src/main.c2
-rw-r--r--src/rtnl.c117
6 files changed, 457 insertions, 279 deletions
diff --git a/include/ipconfig.h b/include/ipconfig.h
index ad7cbc68..8477edee 100644
--- a/include/ipconfig.h
+++ b/include/ipconfig.h
@@ -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);
diff --git a/src/connman.h b/src/connman.h
index 1ba327f3..5ea9ea45 100644
--- a/src/connman.h
+++ b/src/connman.h
@@ -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);
diff --git a/src/device.c b/src/device.c
index b238f46c..b29fb6b0 100644
--- a/src/device.c
+++ b/src/device.c
@@ -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);
}
/**
diff --git a/src/ipconfig.c b/src/ipconfig.c
index 2fd35596..d5f3a10d 100644
--- a/src/ipconfig.c
+++ b/src/ipconfig.c
@@ -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;
+}
diff --git a/src/main.c b/src/main.c
index 3e77472e..ac623121 100644
--- a/src/main.c
+++ b/src/main.c
@@ -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();
diff --git a/src/rtnl.c b/src/rtnl.c
index f0a9dc65..ec163a00 100644
--- a/src/rtnl.c
+++ b/src/rtnl.c
@@ -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;