[PATCH 12/13] idiag: add change attributes for idiag_msg_obj

Thomas Haller thaller at redhat.com
Mon Nov 24 08:14:56 PST 2014


Signed-off-by: Thomas Haller <thaller at redhat.com>
---
 lib/idiag/idiag_msg_obj.c | 141 +++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 127 insertions(+), 14 deletions(-)

diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index b212f69..034faa9 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -17,7 +17,32 @@
 #include <linux/inet_diag.h>
 
 
+/** @cond SKIP */
+#define IDIAGNL_ATTR_FAMILY                     (0x1 << 1)
+#define IDIAGNL_ATTR_STATE                      (0x1 << 2)
+#define IDIAGNL_ATTR_TIMER                      (0x1 << 3)
+#define IDIAGNL_ATTR_RETRANS                    (0x1 << 4)
+#define IDIAGNL_ATTR_SPORT                      (0x1 << 5)
+#define IDIAGNL_ATTR_DPORT                      (0x1 << 6)
+#define IDIAGNL_ATTR_SRC                        (0x1 << 7)
+#define IDIAGNL_ATTR_DST                        (0x1 << 8)
+#define IDIAGNL_ATTR_IFINDEX                    (0x1 << 9)
+#define IDIAGNL_ATTR_EXPIRES                    (0x1 << 10)
+#define IDIAGNL_ATTR_RQUEUE                     (0x1 << 11)
+#define IDIAGNL_ATTR_WQUEUE                     (0x1 << 12)
+#define IDIAGNL_ATTR_UID                        (0x1 << 13)
+#define IDIAGNL_ATTR_INODE                      (0x1 << 14)
+#define IDIAGNL_ATTR_TOS                        (0x1 << 15)
+#define IDIAGNL_ATTR_TCLASS                     (0x1 << 16)
+#define IDIAGNL_ATTR_SHUTDOWN                   (0x1 << 17)
+#define IDIAGNL_ATTR_CONG                       (0x1 << 18)
+#define IDIAGNL_ATTR_MEMINFO                    (0x1 << 19)
+#define IDIAGNL_ATTR_VEGASINFO                  (0x1 << 20)
+#define IDIAGNL_ATTR_TCPINFO                    (0x1 << 21)
+#define IDIAGNL_ATTR_SKMEMINFO                  (0x1 << 22)
+
 #define _INET_DIAG_ALL ((1<<(INET_DIAG_MAX+1))-1)
+/** @endcond */
 
 /**
  * @ingroup idiag
@@ -143,6 +168,7 @@ uint8_t idiagnl_msg_get_family(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_family(struct idiagnl_msg *msg, uint8_t family)
 {
 	msg->idiag_family = family;
+	msg->ce_mask |= IDIAGNL_ATTR_FAMILY;
 }
 
 uint8_t idiagnl_msg_get_state(const struct idiagnl_msg *msg)
@@ -153,6 +179,7 @@ uint8_t idiagnl_msg_get_state(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_state(struct idiagnl_msg *msg, uint8_t state)
 {
 	msg->idiag_state = state;
+	msg->ce_mask |= IDIAGNL_ATTR_STATE;
 }
 
 uint8_t idiagnl_msg_get_timer(const struct idiagnl_msg *msg)
@@ -163,6 +190,7 @@ uint8_t idiagnl_msg_get_timer(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_timer(struct idiagnl_msg *msg, uint8_t timer)
 {
 	msg->idiag_timer = timer;
+	msg->ce_mask |= IDIAGNL_ATTR_TIMER;
 }
 
 uint8_t idiagnl_msg_get_retrans(const struct idiagnl_msg *msg)
@@ -173,6 +201,7 @@ uint8_t idiagnl_msg_get_retrans(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_retrans(struct idiagnl_msg *msg, uint8_t retrans)
 {
 	msg->idiag_retrans = retrans;
+	msg->ce_mask |= IDIAGNL_ATTR_RETRANS;
 }
 
 uint16_t idiagnl_msg_get_sport(struct idiagnl_msg *msg)
@@ -183,6 +212,7 @@ uint16_t idiagnl_msg_get_sport(struct idiagnl_msg *msg)
 void idiagnl_msg_set_sport(struct idiagnl_msg *msg, uint16_t port)
 {
 	msg->idiag_sport = port;
+	msg->ce_mask |= IDIAGNL_ATTR_SPORT;
 }
 
 uint16_t idiagnl_msg_get_dport(struct idiagnl_msg *msg)
@@ -193,6 +223,7 @@ uint16_t idiagnl_msg_get_dport(struct idiagnl_msg *msg)
 void idiagnl_msg_set_dport(struct idiagnl_msg *msg, uint16_t port)
 {
 	msg->idiag_dport = port;
+	msg->ce_mask |= IDIAGNL_ATTR_DPORT;
 }
 
 struct nl_addr *idiagnl_msg_get_src(const struct idiagnl_msg *msg)
@@ -207,6 +238,7 @@ int idiagnl_msg_set_src(struct idiagnl_msg *msg, struct nl_addr *addr)
 
 	nl_addr_get(addr);
 	msg->idiag_src = addr;
+	msg->ce_mask |= IDIAGNL_ATTR_SRC;
 
 	return 0;
 }
@@ -223,6 +255,7 @@ int idiagnl_msg_set_dst(struct idiagnl_msg *msg, struct nl_addr *addr)
 
 	nl_addr_get(addr);
 	msg->idiag_dst = addr;
+	msg->ce_mask |= IDIAGNL_ATTR_DST;
 
 	return 0;
 }
@@ -235,6 +268,7 @@ uint32_t idiagnl_msg_get_ifindex(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_ifindex(struct idiagnl_msg *msg, uint32_t ifindex)
 {
 	msg->idiag_ifindex = ifindex;
+	msg->ce_mask |= IDIAGNL_ATTR_IFINDEX;
 }
 
 uint32_t idiagnl_msg_get_expires(const struct idiagnl_msg *msg)
@@ -245,6 +279,7 @@ uint32_t idiagnl_msg_get_expires(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_expires(struct idiagnl_msg *msg, uint32_t expires)
 {
 	msg->idiag_expires = expires;
+	msg->ce_mask |= IDIAGNL_ATTR_EXPIRES;
 }
 
 uint32_t idiagnl_msg_get_rqueue(const struct idiagnl_msg *msg)
@@ -255,6 +290,7 @@ uint32_t idiagnl_msg_get_rqueue(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_rqueue(struct idiagnl_msg *msg, uint32_t rqueue)
 {
 	msg->idiag_rqueue = rqueue;
+	msg->ce_mask |= IDIAGNL_ATTR_RQUEUE;
 }
 
 uint32_t idiagnl_msg_get_wqueue(const struct idiagnl_msg *msg)
@@ -265,6 +301,7 @@ uint32_t idiagnl_msg_get_wqueue(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_wqueue(struct idiagnl_msg *msg, uint32_t wqueue)
 {
 	msg->idiag_wqueue = wqueue;
+	msg->ce_mask |= IDIAGNL_ATTR_WQUEUE;
 }
 
 uint32_t idiagnl_msg_get_uid(const struct idiagnl_msg *msg)
@@ -275,6 +312,7 @@ uint32_t idiagnl_msg_get_uid(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_uid(struct idiagnl_msg *msg, uint32_t uid)
 {
 	msg->idiag_uid = uid;
+	msg->ce_mask |= IDIAGNL_ATTR_UID;
 }
 
 uint32_t idiagnl_msg_get_inode(const struct idiagnl_msg *msg)
@@ -285,6 +323,7 @@ uint32_t idiagnl_msg_get_inode(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_inode(struct idiagnl_msg *msg, uint32_t inode)
 {
 	msg->idiag_inode = inode;
+	msg->ce_mask |= IDIAGNL_ATTR_INODE;
 }
 
 uint8_t idiagnl_msg_get_tos(const struct idiagnl_msg *msg)
@@ -295,6 +334,7 @@ uint8_t idiagnl_msg_get_tos(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_tos(struct idiagnl_msg *msg, uint8_t tos)
 {
 	msg->idiag_tos = tos;
+	msg->ce_mask |= IDIAGNL_ATTR_TOS;
 }
 
 uint8_t idiagnl_msg_get_tclass(const struct idiagnl_msg *msg)
@@ -305,6 +345,7 @@ uint8_t idiagnl_msg_get_tclass(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_tclass(struct idiagnl_msg *msg, uint8_t tclass)
 {
 	msg->idiag_tclass = tclass;
+	msg->ce_mask |= IDIAGNL_ATTR_TCLASS;
 }
 
 uint8_t	idiagnl_msg_get_shutdown(const struct idiagnl_msg *msg)
@@ -315,6 +356,7 @@ uint8_t	idiagnl_msg_get_shutdown(const struct idiagnl_msg *msg)
 void  idiagnl_msg_set_shutdown(struct idiagnl_msg *msg, uint8_t shutdown)
 {
 	msg->idiag_shutdown = shutdown;
+	msg->ce_mask |= IDIAGNL_ATTR_SHUTDOWN;
 }
 
 char *idiagnl_msg_get_cong(const struct idiagnl_msg *msg)
@@ -326,6 +368,7 @@ void idiagnl_msg_set_cong(struct idiagnl_msg *msg, char *cong)
 {
 	free (msg->idiag_cong);
 	msg->idiag_cong = strdup(cong);
+	msg->ce_mask |= IDIAGNL_ATTR_CONG;
 }
 
 struct idiagnl_meminfo *idiagnl_msg_get_meminfo(const struct idiagnl_msg *msg)
@@ -333,14 +376,14 @@ struct idiagnl_meminfo *idiagnl_msg_get_meminfo(const struct idiagnl_msg *msg)
 	return msg->idiag_meminfo;
 }
 
-void idiagnl_msg_set_meminfo(struct idiagnl_msg *msg, struct idiagnl_meminfo
-		*minfo)
+void idiagnl_msg_set_meminfo(struct idiagnl_msg *msg, struct idiagnl_meminfo *minfo)
 {
 	if (msg->idiag_meminfo)
 		idiagnl_meminfo_put(msg->idiag_meminfo);
 
 	idiagnl_meminfo_get(minfo);
 	msg->idiag_meminfo = minfo;
+	msg->ce_mask |= IDIAGNL_ATTR_MEMINFO;
 }
 
 struct idiagnl_vegasinfo *idiagnl_msg_get_vegasinfo(const struct idiagnl_msg *msg)
@@ -348,14 +391,14 @@ struct idiagnl_vegasinfo *idiagnl_msg_get_vegasinfo(const struct idiagnl_msg *ms
 	return msg->idiag_vegasinfo;
 }
 
-void idiagnl_msg_set_vegasinfo(struct idiagnl_msg *msg, struct idiagnl_vegasinfo
-		*vinfo)
+void idiagnl_msg_set_vegasinfo(struct idiagnl_msg *msg, struct idiagnl_vegasinfo *vinfo)
 {
 	if (msg->idiag_vegasinfo)
 		idiagnl_vegasinfo_put(msg->idiag_vegasinfo);
 
 	idiagnl_vegasinfo_get(vinfo);
 	msg->idiag_vegasinfo = vinfo;
+	msg->ce_mask |= IDIAGNL_ATTR_VEGASINFO;
 }
 
 struct tcp_info idiagnl_msg_get_tcpinfo(const struct idiagnl_msg *msg)
@@ -366,6 +409,7 @@ struct tcp_info idiagnl_msg_get_tcpinfo(const struct idiagnl_msg *msg)
 void idiagnl_msg_set_tcpinfo(struct idiagnl_msg *msg, struct tcp_info *tinfo)
 {
 	memcpy(&msg->idiag_tcpinfo, tinfo, sizeof(struct tcp_info));
+	msg->ce_mask |= IDIAGNL_ATTR_TCPINFO;
 }
 
 /** @} */
@@ -577,30 +621,40 @@ static int idiagnl_msg_clone(struct nl_object *_dst, struct nl_object *_src)
 	dst->idiag_dst = NULL;
 	dst->idiag_meminfo = NULL;
 	dst->idiag_vegasinfo = NULL;
+	dst->ce_mask &= ~(IDIAGNL_ATTR_CONG |
+	                  IDIAGNL_ATTR_SRC |
+	                  IDIAGNL_ATTR_DST |
+	                  IDIAGNL_ATTR_MEMINFO |
+	                  IDIAGNL_ATTR_VEGASINFO);
 
 	if (src->idiag_cong) {
 		if (!(dst->idiag_cong = strdup(src->idiag_cong)))
 			return -NLE_NOMEM;
+		dst->ce_mask |= IDIAGNL_ATTR_CONG;
 	}
 
 	if (src->idiag_src) {
 		if (!(dst->idiag_src = nl_addr_clone(src->idiag_src)))
 			return -NLE_NOMEM;
+		dst->ce_mask |= IDIAGNL_ATTR_SRC;
 	}
 
 	if (src->idiag_dst) {
 		if (!(dst->idiag_dst = nl_addr_clone(src->idiag_dst)))
 			return -NLE_NOMEM;
+		dst->ce_mask |= IDIAGNL_ATTR_DST;
 	}
 
 	if (src->idiag_meminfo) {
 		if (!(dst->idiag_meminfo = (struct idiagnl_meminfo *) nl_object_clone((struct nl_object *) src->idiag_meminfo)))
 			return -NLE_NOMEM;
+		dst->ce_mask |= IDIAGNL_ATTR_MEMINFO;
 	}
 
 	if (src->idiag_vegasinfo) {
 		if (!(dst->idiag_vegasinfo = (struct idiagnl_vegasinfo *) nl_object_clone((struct nl_object *) src->idiag_vegasinfo)))
 			return -NLE_NOMEM;
+		dst->ce_mask |= IDIAGNL_ATTR_VEGASINFO;
 	}
 
 	return 0;
@@ -649,6 +703,19 @@ int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result)
 	msg->idiag_dport = raw_msg->id.idiag_dport;
 	msg->idiag_ifindex = raw_msg->id.idiag_if;
 
+	msg->ce_mask = (IDIAGNL_ATTR_FAMILY |
+	                IDIAGNL_ATTR_STATE |
+	                IDIAGNL_ATTR_TIMER |
+	                IDIAGNL_ATTR_RETRANS |
+	                IDIAGNL_ATTR_EXPIRES |
+	                IDIAGNL_ATTR_RQUEUE |
+	                IDIAGNL_ATTR_WQUEUE |
+	                IDIAGNL_ATTR_UID |
+	                IDIAGNL_ATTR_INODE |
+	                IDIAGNL_ATTR_SPORT |
+	                IDIAGNL_ATTR_DPORT |
+	                IDIAGNL_ATTR_IFINDEX);
+
 	dst = nl_addr_build(raw_msg->idiag_family, raw_msg->id.idiag_dst,
 			sizeof(raw_msg->id.idiag_dst));
 	if (!dst)
@@ -671,21 +738,31 @@ int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result)
 
 	nl_addr_put(src);
 
-	if (tb[INET_DIAG_TOS])
+	if (tb[INET_DIAG_TOS]) {
 		msg->idiag_tos = nla_get_u8(tb[INET_DIAG_TOS]);
+		msg->ce_mask |= IDIAGNL_ATTR_TOS;
+	}
 
-	if (tb[INET_DIAG_TCLASS])
+	if (tb[INET_DIAG_TCLASS]) {
 		msg->idiag_tclass = nla_get_u8(tb[INET_DIAG_TCLASS]);
+		msg->ce_mask |= IDIAGNL_ATTR_TCLASS;
+	}
 
-	if (tb[INET_DIAG_SHUTDOWN])
+	if (tb[INET_DIAG_SHUTDOWN]) {
 		msg->idiag_shutdown = nla_get_u8(tb[INET_DIAG_SHUTDOWN]);
+		msg->ce_mask |= IDIAGNL_ATTR_SHUTDOWN;
+	}
 
-	if (tb[INET_DIAG_CONG])
+	if (tb[INET_DIAG_CONG]) {
 		msg->idiag_cong = nla_strdup(tb[INET_DIAG_CONG]);
+		msg->ce_mask |= IDIAGNL_ATTR_CONG;
+	}
 
-	if (tb[INET_DIAG_INFO])
+	if (tb[INET_DIAG_INFO]) {
 		nla_memcpy(&msg->idiag_tcpinfo, tb[INET_DIAG_INFO],
 				sizeof(msg->idiag_tcpinfo));
+		msg->ce_mask |= IDIAGNL_ATTR_TCPINFO;
+	}
 
 	if (tb[INET_DIAG_MEMINFO]) {
 		struct idiagnl_meminfo *minfo = idiagnl_meminfo_alloc();
@@ -703,6 +780,7 @@ int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result)
 		idiagnl_meminfo_set_tmem(minfo, raw_minfo->idiag_tmem);
 
 		msg->idiag_meminfo = minfo;
+		msg->ce_mask |= IDIAGNL_ATTR_MEMINFO;
 	}
 
 	if (tb[INET_DIAG_VEGASINFO]) {
@@ -721,11 +799,14 @@ int idiagnl_msg_parse(struct nlmsghdr *nlh, struct idiagnl_msg **result)
 		idiagnl_vegasinfo_set_minrtt(vinfo, raw_vinfo->tcpv_minrtt);
 
 		msg->idiag_vegasinfo = vinfo;
+		msg->ce_mask |= IDIAGNL_ATTR_VEGASINFO;
 	}
 
-	if (tb[INET_DIAG_SKMEMINFO])
+	if (tb[INET_DIAG_SKMEMINFO]) {
 		nla_memcpy(&msg->idiag_skmeminfo, tb[INET_DIAG_SKMEMINFO],
 				sizeof(msg->idiag_skmeminfo));
+		msg->ce_mask |= IDIAGNL_ATTR_SKMEMINFO;
+	}
 
 	*result = msg;
 	return 0;
@@ -739,6 +820,37 @@ errout_nomem:
 	goto errout;
 }
 
+static const struct trans_tbl idiagnl_attrs[] = {
+	__ADD(IDIAGNL_ATTR_FAMILY, family),
+	__ADD(IDIAGNL_ATTR_STATE, state),
+	__ADD(IDIAGNL_ATTR_TIMER, timer),
+	__ADD(IDIAGNL_ATTR_RETRANS, retrans),
+	__ADD(IDIAGNL_ATTR_SPORT, sport),
+	__ADD(IDIAGNL_ATTR_DPORT, dport),
+	__ADD(IDIAGNL_ATTR_SRC, src),
+	__ADD(IDIAGNL_ATTR_DST, dst),
+	__ADD(IDIAGNL_ATTR_IFINDEX, ifindex),
+	__ADD(IDIAGNL_ATTR_EXPIRES, expires),
+	__ADD(IDIAGNL_ATTR_RQUEUE, rqueue),
+	__ADD(IDIAGNL_ATTR_WQUEUE, wqueue),
+	__ADD(IDIAGNL_ATTR_UID, uid),
+	__ADD(IDIAGNL_ATTR_INODE, inode),
+	__ADD(IDIAGNL_ATTR_TOS, tos),
+	__ADD(IDIAGNL_ATTR_TCLASS, tclass),
+	__ADD(IDIAGNL_ATTR_SHUTDOWN, shutdown),
+	__ADD(IDIAGNL_ATTR_CONG, cong),
+	__ADD(IDIAGNL_ATTR_MEMINFO, meminfo),
+	__ADD(IDIAGNL_ATTR_VEGASINFO, vegasinfo),
+	__ADD(IDIAGNL_ATTR_TCPINFO, tcpinfo),
+	__ADD(IDIAGNL_ATTR_SKMEMINFO, skmeminfo),
+};
+
+static char *_idiagnl_attrs2str(int attrs, char *buf, size_t len)
+{
+	return __flags2str(attrs, buf, len, idiagnl_attrs,
+	                   ARRAY_SIZE(idiagnl_attrs));
+}
+
 static void idiagnl_keygen(struct nl_object *obj, uint32_t *hashkey,
         uint32_t table_sz)
 {
@@ -777,10 +889,11 @@ struct nl_object_ops idiagnl_msg_obj_ops = {
 		[NL_DUMP_STATS]		 = idiag_msg_dump_stats,
 	},
 	.oo_keygen			= idiagnl_keygen,
-	/* FIXME: using inet diag extended attributes as change flags (ce_mask)
-	 * is very wrong. */
-	.oo_attrs2str			= idiagnl_attrs2str,
-	.oo_id_attrs			= (INET_DIAG_INFO)
+	.oo_attrs2str			= _idiagnl_attrs2str,
+	.oo_id_attrs                    = (IDIAGNL_ATTR_FAMILY |
+	                                   IDIAGNL_ATTR_STATE |
+	                                   IDIAGNL_ATTR_SPORT |
+	                                   IDIAGNL_ATTR_DPORT),
 };
 /** @endcond */
 
-- 
1.9.3




More information about the libnl mailing list