From f33303b557c1c12313c42372fdd173c4e69ddef0 Mon Sep 17 00:00:00 2001 From: Marcel Holtmann Date: Tue, 5 Jan 2010 06:59:20 -0800 Subject: [PATCH] Add support for exporting basic interface statistics --- src/connman.h | 10 +++++++-- src/counter.c | 55 ++++++++++++++++++++++++++++++++++++++++-------- src/ipconfig.c | 63 ++++++++++++++++++++++++++++++++++++++----------------- src/rtnl.c | 39 ++++++++++++++++++++-------------- test/test-counter | 8 ++++--- 5 files changed, 126 insertions(+), 49 deletions(-) diff --git a/src/connman.h b/src/connman.h index 109ed8e..0537bf0 100644 --- a/src/connman.h +++ b/src/connman.h @@ -69,6 +69,8 @@ int __connman_counter_register(const char *owner, const char *path, unsigned int interval); int __connman_counter_unregister(const char *owner, const char *path); +void __connman_counter_notify(unsigned int rx_bytes, unsigned int tx_bytes); + int __connman_counter_init(void); void __connman_counter_cleanup(void); @@ -110,10 +112,13 @@ int __connman_security_check_privilege(DBusMessage *message, int __connman_ipconfig_init(void); void __connman_ipconfig_cleanup(void); +struct rtnl_link_stats; + void __connman_ipconfig_newlink(int index, unsigned short type, unsigned int flags, const char *address, - unsigned short mtu); -void __connman_ipconfig_dellink(int index); + unsigned short mtu, + struct rtnl_link_stats *stats); +void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats); void __connman_ipconfig_newaddr(int index, const char *label, unsigned char prefixlen, const char *address); void __connman_ipconfig_deladdr(int index, const char *label, @@ -427,4 +432,5 @@ int __connman_rtnl_init(void); void __connman_rtnl_start(void); void __connman_rtnl_cleanup(void); +int __connman_rtnl_request_update(void); int __connman_rtnl_send(const void *buf, size_t len); diff --git a/src/counter.c b/src/counter.c index 9dea4b7..224d122 100644 --- a/src/counter.c +++ b/src/counter.c @@ -37,6 +37,8 @@ struct connman_counter { char *path; guint timeout; guint watch; + unsigned int rx_bytes; + unsigned int tx_bytes; }; static void remove_counter(gpointer user_data) @@ -69,18 +71,10 @@ static void owner_disconnect(DBusConnection *connection, void *user_data) static gboolean counter_timeout(gpointer user_data) { struct connman_counter *counter = user_data; - DBusMessage *message; DBG("owner %s path %s", counter->owner, counter->path); - message = dbus_message_new_method_call(counter->owner, counter->path, - CONNMAN_COUNTER_INTERFACE, "Usage"); - if (message == NULL) - return TRUE; - - dbus_message_set_no_reply(message, TRUE); - - g_dbus_send_message(connection, message); + __connman_rtnl_request_update(); return TRUE; } @@ -134,6 +128,49 @@ int __connman_counter_unregister(const char *owner, const char *path) return 0; } +static void send_usage(struct connman_counter *counter) +{ + DBusMessage *message; + DBusMessageIter array, dict; + + message = dbus_message_new_method_call(counter->owner, counter->path, + CONNMAN_COUNTER_INTERFACE, "Usage"); + if (message == NULL) + return; + + dbus_message_set_no_reply(message, TRUE); + + dbus_message_iter_init_append(message, &array); + + connman_dbus_dict_open(&array, &dict); + + connman_dbus_dict_append_basic(&dict, "RX.Bytes", + DBUS_TYPE_UINT32, &counter->rx_bytes); + connman_dbus_dict_append_basic(&dict, "TX.Bytes", + DBUS_TYPE_UINT32, &counter->tx_bytes); + + connman_dbus_dict_close(&array, &dict); + + g_dbus_send_message(connection, message); +} + +void __connman_counter_notify(unsigned int rx_bytes, unsigned int tx_bytes) +{ + GHashTableIter iter; + gpointer key, value; + + g_hash_table_iter_init(&iter, counter_table); + + while (g_hash_table_iter_next(&iter, &key, &value) == TRUE) { + struct connman_counter *counter = value; + + counter->rx_bytes = rx_bytes; + counter->tx_bytes = tx_bytes; + + send_usage(counter); + } +} + static void release_counter(gpointer key, gpointer value, gpointer user_data) { struct connman_counter *counter = value; diff --git a/src/ipconfig.c b/src/ipconfig.c index 77720fd..0d0426e 100644 --- a/src/ipconfig.c +++ b/src/ipconfig.c @@ -25,6 +25,7 @@ #include #include +#include #ifndef IFF_LOWER_UP #define IFF_LOWER_UP 0x10000 @@ -46,9 +47,6 @@ struct connman_ipconfig { enum connman_ipconfig_method method; struct connman_ipaddress *address; struct connman_ipaddress *system; - - char *eth; - uint16_t mtu; }; struct connman_ipdevice { @@ -56,6 +54,10 @@ struct connman_ipdevice { char *ifname; unsigned short type; unsigned int flags; + char *address; + uint16_t mtu; + uint32_t tx_bytes; + uint32_t rx_bytes; GSList *address_list; char *gateway; @@ -231,6 +233,7 @@ static void free_ipdevice(gpointer data) free_address_list(ipdevice); g_free(ipdevice->gateway); + g_free(ipdevice->address); g_free(ipdevice->ifname); g_free(ipdevice); } @@ -337,9 +340,30 @@ static void __connman_ipconfig_lower_down(struct connman_ipdevice *ipdevice) connman_inet_clear_address(ipdevice->index); } +static void update_stats(struct connman_ipdevice *ipdevice, + struct rtnl_link_stats *stats) +{ + if (stats->rx_packets == 0 && stats->tx_packets == 0) + return; + + connman_info("%s {RX} %u packets %u bytes", ipdevice->ifname, + stats->rx_packets, stats->rx_bytes); + connman_info("%s {TX} %u packets %u bytes", ipdevice->ifname, + stats->tx_packets, stats->tx_bytes); + + if (ipdevice->config == NULL) + return; + + ipdevice->rx_bytes = stats->rx_bytes; + ipdevice->tx_bytes = stats->tx_bytes; + + __connman_counter_notify(ipdevice->rx_bytes, ipdevice->tx_bytes); +} + void __connman_ipconfig_newlink(int index, unsigned short type, unsigned int flags, const char *address, - unsigned short mtu) + unsigned short mtu, + struct rtnl_link_stats *stats) { struct connman_ipdevice *ipdevice; GList *list; @@ -375,17 +399,17 @@ void __connman_ipconfig_newlink(int index, unsigned short type, ipdevice->ifname = ifname; ipdevice->type = type; + ipdevice->address = g_strdup(address); + 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 (ipdevice->config != NULL) { - g_free(ipdevice->config->eth); - ipdevice->config->eth = g_strdup(address); - ipdevice->config->mtu = mtu; - } + ipdevice->mtu = mtu; + + update_stats(ipdevice, stats); if (flags == ipdevice->flags) return; @@ -455,7 +479,7 @@ update: __connman_ipconfig_lower_down(ipdevice); } -void __connman_ipconfig_dellink(int index) +void __connman_ipconfig_dellink(int index, struct rtnl_link_stats *stats) { struct connman_ipdevice *ipdevice; GList *list; @@ -466,6 +490,8 @@ void __connman_ipconfig_dellink(int index) if (ipdevice == NULL) return; + update_stats(ipdevice, stats); + for (list = g_list_first(ipconfig_list); list; list = g_list_next(list)) { struct connman_ipconfig *ipconfig = list->data; @@ -771,7 +797,6 @@ void connman_ipconfig_unref(struct connman_ipconfig *ipconfig) connman_ipaddress_free(ipconfig->system); connman_ipaddress_free(ipconfig->address); - g_free(ipconfig->eth); g_free(ipconfig); } } @@ -1139,14 +1164,6 @@ void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig, connman_dbus_dict_append_basic(iter, "Method", DBUS_TYPE_STRING, &method); - if (ipconfig->eth != NULL) - connman_dbus_dict_append_basic(iter, "Address", - DBUS_TYPE_STRING, &ipconfig->eth); - - if (ipconfig->mtu > 0) - connman_dbus_dict_append_basic(iter, "MTU", - DBUS_TYPE_UINT16, &ipconfig->mtu); - ipdevice = g_hash_table_lookup(ipdevice_hash, GINT_TO_POINTER(ipconfig->index)); if (ipdevice == NULL) @@ -1155,6 +1172,14 @@ void __connman_ipconfig_append_ethernet(struct connman_ipconfig *ipconfig, if (ipdevice->ifname != NULL) connman_dbus_dict_append_basic(iter, "Interface", DBUS_TYPE_STRING, &ipdevice->ifname); + + if (ipdevice->address != NULL) + connman_dbus_dict_append_basic(iter, "Address", + DBUS_TYPE_STRING, &ipdevice->address); + + if (ipdevice->mtu > 0) + connman_dbus_dict_append_basic(iter, "MTU", + DBUS_TYPE_UINT16, &ipdevice->mtu); } int __connman_ipconfig_load(struct connman_ipconfig *ipconfig, diff --git a/src/rtnl.c b/src/rtnl.c index 2137788..12ebdcb 100644 --- a/src/rtnl.c +++ b/src/rtnl.c @@ -242,9 +242,9 @@ static const char *operstate2str(unsigned char operstate) static void extract_link(struct ifinfomsg *msg, int bytes, struct ether_addr *address, const char **ifname, - unsigned int *mtu, unsigned char *operstate) + unsigned int *mtu, unsigned char *operstate, + struct rtnl_link_stats *stats) { - struct rtnl_link_stats stats; struct rtattr *attr; for (attr = IFLA_RTA(msg); RTA_OK(attr, bytes); @@ -263,12 +263,9 @@ static void extract_link(struct ifinfomsg *msg, int bytes, *mtu = *((unsigned int *) RTA_DATA(attr)); break; case IFLA_STATS: - memcpy(&stats, RTA_DATA(attr), + if (stats != NULL) + memcpy(stats, RTA_DATA(attr), sizeof(struct rtnl_link_stats)); - connman_info("%s {RX} %d packets %d bytes", *ifname, - stats.rx_packets, stats.rx_bytes); - connman_info("%s {TX} %d packets %d bytes", *ifname, - stats.tx_packets, stats.tx_bytes); break; case IFLA_OPERSTATE: if (operstate != NULL) @@ -285,27 +282,30 @@ static void process_newlink(unsigned short type, int index, unsigned flags, { struct ether_addr address = {{ 0, 0, 0, 0, 0, 0 }}; struct ether_addr compare = {{ 0, 0, 0, 0, 0, 0 }}; + struct rtnl_link_stats stats; unsigned char operstate = 0xff; const char *ifname = NULL; unsigned int mtu = 0; char str[18]; GSList *list; - extract_link(msg, bytes, &address, &ifname, &mtu, &operstate); + memset(&stats, 0, sizeof(stats)); + extract_link(msg, bytes, &address, &ifname, &mtu, &operstate, &stats); snprintf(str, 18, "%02X:%02X:%02X:%02X:%02X:%02X", address.ether_addr_octet[0], - address.ether_addr_octet[1], - address.ether_addr_octet[2], - address.ether_addr_octet[3], - address.ether_addr_octet[4], - address.ether_addr_octet[5]); + address.ether_addr_octet[1], + address.ether_addr_octet[2], + address.ether_addr_octet[3], + address.ether_addr_octet[4], + address.ether_addr_octet[5]); switch (type) { case ARPHRD_ETHER: case ARPHRD_LOOPBACK: case ARPHRD_NONE: - __connman_ipconfig_newlink(index, type, flags, str, mtu); + __connman_ipconfig_newlink(index, type, flags, + str, mtu, &stats); break; } @@ -342,11 +342,13 @@ static void process_newlink(unsigned short type, int index, unsigned flags, static void process_dellink(unsigned short type, int index, unsigned flags, unsigned change, struct ifinfomsg *msg, int bytes) { + struct rtnl_link_stats stats; unsigned char operstate = 0xff; const char *ifname = NULL; GSList *list; - extract_link(msg, bytes, NULL, &ifname, NULL, &operstate); + memset(&stats, 0, sizeof(stats)); + extract_link(msg, bytes, NULL, &ifname, NULL, &operstate, &stats); if (operstate != 0xff) connman_info("%s {dellink} index %d operstate %u <%s>", @@ -374,7 +376,7 @@ static void process_dellink(unsigned short type, int index, unsigned flags, case ARPHRD_ETHER: case ARPHRD_LOOPBACK: case ARPHRD_NONE: - __connman_ipconfig_dellink(index); + __connman_ipconfig_dellink(index, &stats); break; } } @@ -1049,6 +1051,11 @@ static int send_getroute(void) return queue_request(req); } +int __connman_rtnl_request_update(void) +{ + return send_getlink(); +} + int __connman_rtnl_init(void) { struct sockaddr_nl addr; diff --git a/test/test-counter b/test/test-counter index b0173a4..d000a8d 100755 --- a/test/test-counter +++ b/test/test-counter @@ -14,9 +14,11 @@ class Counter(dbus.service.Object): mainloop.quit() @dbus.service.method("org.moblin.connman.Counter", - in_signature='', out_signature='') - def Usage(self): - print("Usage") + in_signature='a{sv}', out_signature='') + def Usage(self, stats): + for key in stats.keys(): + val = int(stats[key]) + print "%s = %s" % (key, val) if __name__ == '__main__': dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) -- 2.7.4