[PATCH 1/1] idiag: fix set of identifying properties for idiag_msg_obj

Thomas Haller thaller at redhat.com
Wed Nov 26 03:34:55 PST 2014


The key for a struct idiag_msg_obj should be
'family x src x dst x sport x dport'.

Signed-off-by: Thomas Haller <thaller at redhat.com>
---
Hi Cong,

how about this now? I actually don't know which fields constitute
the identifying properties. I think having state there is wrong.

Can you verify that now it is correct? Note that for this to be correct,
these 5 properties must always be present in every (valid) idiag_msg_obj
and they must never change -- for the same instance.

Thanks,
Thomas

 lib/idiag/idiag_msg_obj.c | 25 +++++++++++++++++++------
 1 file changed, 19 insertions(+), 6 deletions(-)

diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index 8199536..5311e23 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -860,9 +860,10 @@ static int idiagnl_compare(struct nl_object *_a, struct nl_object *_b,
 
 #define _DIFF(ATTR, EXPR) ATTR_DIFF(attrs, IDIAGNL_ATTR_##ATTR, a, b, EXPR)
 	diff |= _DIFF(FAMILY, a->idiag_family != b->idiag_family);
-	diff |= _DIFF(STATE,  a->idiag_state != b->idiag_state);
 	diff |= _DIFF(SPORT,  a->idiag_sport != b->idiag_sport);
 	diff |= _DIFF(DPORT,  a->idiag_dport != b->idiag_dport);
+	diff |= _DIFF(SRC,    nl_addr_cmp (a->idiag_src, b->idiag_src));
+	diff |= _DIFF(DST,    nl_addr_cmp (a->idiag_dst, b->idiag_dst));
 #undef _DIFF
 	return diff;
 }
@@ -874,21 +875,32 @@ static void idiagnl_keygen(struct nl_object *obj, uint32_t *hashkey,
 	unsigned int key_sz;
 	struct idiagnl_hash_key {
 		uint8_t	family;
-		uint8_t	state;
+		uint32_t src_hash;
+		uint32_t dst_hash;
 		uint16_t sport;
 		uint16_t dport;
 	} __attribute__((packed)) key;
 
 	key_sz = sizeof(key);
 	key.family = msg->idiag_family;
-	key.state = msg->idiag_state;
+	key.src_hash = 0;
+	key.dst_hash = 0;
 	key.sport = msg->idiag_sport;
 	key.dport = msg->idiag_dport;
 
+	if (msg->idiag_src) {
+		key.src_hash = nl_hash (nl_addr_get_binary_addr(msg->idiag_src),
+		                        nl_addr_get_len(msg->idiag_src), 0);
+	}
+	if (msg->idiag_dst) {
+		key.dst_hash = nl_hash (nl_addr_get_binary_addr(msg->idiag_dst),
+		                        nl_addr_get_len(msg->idiag_dst), 0);
+	}
+
 	*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);
+	NL_DBG(5, "idiagnl %p key (fam %d src_hash %d dst_hash %d sport %d dport %d) keysz %d, hash 0x%x\n",
+	       msg, key.family, key.src_hash, key.dst_hash, key.sport, key.dport, key_sz, *hashkey);
 
 	return;
 }
@@ -908,7 +920,8 @@ struct nl_object_ops idiagnl_msg_obj_ops = {
 	.oo_keygen			= idiagnl_keygen,
 	.oo_attrs2str			= _idiagnl_attrs2str,
 	.oo_id_attrs                    = (IDIAGNL_ATTR_FAMILY |
-	                                   IDIAGNL_ATTR_STATE |
+	                                   IDIAGNL_ATTR_SRC |
+	                                   IDIAGNL_ATTR_DST |
 	                                   IDIAGNL_ATTR_SPORT |
 	                                   IDIAGNL_ATTR_DPORT),
 };
-- 
1.9.3




More information about the libnl mailing list