summaryrefslogtreecommitdiff
path: root/lib/idiag
diff options
context:
space:
mode:
authorCong Wang <xiyou.wangcong@gmail.com>2014-11-20 12:26:01 -0800
committerThomas Haller <thaller@redhat.com>2014-11-24 10:49:34 +0100
commit9c066b9271493ce3efff0b9d7b6e424990bba3f2 (patch)
tree5bf2926a29ebcfdcee192135db8753e9d026429c /lib/idiag
parent0020ba1212caad02841f72d680815e67d7180683 (diff)
downloadlibnl-9c066b9271493ce3efff0b9d7b6e424990bba3f2.tar.gz
idiag: provide a hash function for idiag objects
Without ->oo_keygen, libnl will use linear search for cache objects. This is extremely slow for idiag when we have a lot of TCP connections. Provide a hash function for idiag so that libnl will be able to lookup a hashtable. http://lists.infradead.org/pipermail/libnl/2014-November/001715.html Cc: Thomas Graf <tgraf@suug.ch> Cc: Thomas Haller <thaller@redhat.com> Signed-off-by: Cong Wang <xiyou.wangcong@gmail.com> Signed-off-by: Thomas Haller <thaller@redhat.com>
Diffstat (limited to 'lib/idiag')
-rw-r--r--lib/idiag/idiag_msg_obj.c28
1 files changed, 28 insertions, 0 deletions
diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index 19e6c5be..92a98e91 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -10,6 +10,7 @@
*/
#include <netlink-private/netlink.h>
+#include <netlink/hashtable.h>
#include <netlink/idiag/msg.h>
#include <netlink/idiag/meminfo.h>
#include <netlink/idiag/vegasinfo.h>
@@ -710,6 +711,32 @@ errout_nomem:
goto errout;
}
+static void idiagnl_keygen(struct nl_object *obj, uint32_t *hashkey,
+ uint32_t table_sz)
+{
+ struct idiagnl_msg *msg = (struct idiagnl_msg *)obj;
+ unsigned int key_sz;
+ struct idiagnl_hash_key {
+ uint8_t family;
+ uint8_t state;
+ uint16_t sport;
+ uint16_t dport;
+ } __attribute__((packed)) key;
+
+ key_sz = sizeof(key);
+ key.family = msg->idiag_family;
+ key.state = msg->idiag_state;
+ key.sport = msg->idiag_sport;
+ key.dport = msg->idiag_dport;
+
+ *hashkey = nl_hash(&key, key_sz, 0) % table_sz;
+
+ NL_DBG(5, "idiagnl %p key (fam %d state %d sport %d dport %d) keysz %d, hash 0x%x\n",
+ msg, key.family, key.state, key.sport, key.dport, key_sz, *hashkey);
+
+ return;
+}
+
/** @cond SKIP */
struct nl_object_ops idiagnl_msg_obj_ops = {
.oo_name = "idiag/idiag_msg",
@@ -721,6 +748,7 @@ struct nl_object_ops idiagnl_msg_obj_ops = {
[NL_DUMP_DETAILS] = idiag_msg_dump_details,
[NL_DUMP_STATS] = idiag_msg_dump_stats,
},
+ .oo_keygen = idiagnl_keygen,
.oo_attrs2str = idiagnl_attrs2str,
.oo_id_attrs = (IDIAG_ATTR_INFO)
};