From 6b8f85ab661243c7a34da9aaf10de464ad752308 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Mon, 10 Aug 2009 00:57:10 -0700 Subject: [PATCH] Add more detailed tracking of IP devices --- include/ipconfig.h | 5 +- src/connman.h | 39 ++-- src/device.c | 39 +++- src/ipconfig.c | 534 +++++++++++++++++++++++++++++++++++++---------------- src/main.c | 2 + src/rtnl.c | 117 ++---------- 6 files changed, 457 insertions(+), 279 deletions(-) diff --git a/include/ipconfig.h b/include/ipconfig.h index ad7cbc6..8477ede 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 1ba327f..5ea9ea4 100644 --- a/src/connman.h +++ b/src/connman.h @@ -91,25 +91,26 @@ int __connman_security_check_privilege(DBusMessage *message, #include -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 b238f46..b29fb6b 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 2fd3559..d5f3a10 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -24,6 +24,7 @@ #endif #include +#include #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 3e77472..ac62312 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 f0a9dc6..ec163a0 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; -- 2.7.4