[Patch v2 1/2] idiag: add a copy of linux/sock_diag.h

Cong Wang xiyou.wangcong at gmail.com
Mon Oct 27 09:50:17 PDT 2014


When we test idiag on 3.4 kernel, we always get ERANGE.
This is because libnl has its own copy for SK_MEMINFO_*,
which is actually newer than 3.4, where SK_MEMINFO_VARS
is larger than kernel's.

We add a copy from latest kernel, so on older kernel
libnl should still compile. Note, for kernel < 3.6
we don't have SK_MEMINFO_BACKLOG, we have to relax
the minlen.

Signed-off-by: Cong Wang <xiyou.wangcong at gmail.com>
---
 include/Makefile.am                     |  1 +
 include/linux-private/linux/sock_diag.h | 26 ++++++++++++++++++++++++++
 include/netlink-private/types.h         |  2 +-
 include/netlink/idiag/idiagnl.h         | 27 +++++++++++----------------
 lib/idiag/idiag_msg_obj.c               | 19 ++++++++++---------
 5 files changed, 49 insertions(+), 26 deletions(-)
 create mode 100644 include/linux-private/linux/sock_diag.h

diff --git a/include/Makefile.am b/include/Makefile.am
index 82684a1..273aee1 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -150,6 +150,7 @@ noinst_HEADERS = \
 	linux-private/linux/rtnetlink.h \
 	linux-private/linux/snmp.h \
 	linux-private/linux/xfrm.h \
+	linux-private/linux/sock_diag.h \
 	linux-private/linux/tc_ematch/tc_em_meta.h \
 	netlink-private/genl.h \
 	netlink-private/netlink.h \
diff --git a/include/linux-private/linux/sock_diag.h b/include/linux-private/linux/sock_diag.h
new file mode 100644
index 0000000..b00e29e
--- /dev/null
+++ b/include/linux-private/linux/sock_diag.h
@@ -0,0 +1,26 @@
+#ifndef _UAPI__SOCK_DIAG_H__
+#define _UAPI__SOCK_DIAG_H__
+
+#include <linux/types.h>
+
+#define SOCK_DIAG_BY_FAMILY 20
+
+struct sock_diag_req {
+	__u8	sdiag_family;
+	__u8	sdiag_protocol;
+};
+
+enum {
+	SK_MEMINFO_RMEM_ALLOC,
+	SK_MEMINFO_RCVBUF,
+	SK_MEMINFO_WMEM_ALLOC,
+	SK_MEMINFO_SNDBUF,
+	SK_MEMINFO_FWD_ALLOC,
+	SK_MEMINFO_WMEM_QUEUED,
+	SK_MEMINFO_OPTMEM,
+	SK_MEMINFO_BACKLOG,
+
+	SK_MEMINFO_VARS,
+};
+
+#endif /* _UAPI__SOCK_DIAG_H__ */
diff --git a/include/netlink-private/types.h b/include/netlink-private/types.h
index 6f3243b..c30cd36 100644
--- a/include/netlink-private/types.h
+++ b/include/netlink-private/types.h
@@ -1000,7 +1000,7 @@ struct idiagnl_msg {
 	struct idiagnl_meminfo *    idiag_meminfo;
 	struct idiagnl_vegasinfo *  idiag_vegasinfo;
 	struct tcp_info		    idiag_tcpinfo;
-	uint32_t		    idiag_skmeminfo[IDIAG_SK_MEMINFO_VARS];
+	uint32_t		    idiag_skmeminfo[SK_MEMINFO_VARS];
 };
 
 struct idiagnl_req {
diff --git a/include/netlink/idiag/idiagnl.h b/include/netlink/idiag/idiagnl.h
index d7434cd..64bccd7 100644
--- a/include/netlink/idiag/idiagnl.h
+++ b/include/netlink/idiag/idiagnl.h
@@ -13,6 +13,7 @@
 #define NETLINK_IDIAGNL_H_
 
 #include <netlink/netlink.h>
+#include <linux/sock_diag.h>
 
 #ifdef __cplusplus
 extern "C" {
@@ -74,22 +75,16 @@ enum {
  */
 #define IDIAG_ATTR_ALL ((1<<IDIAG_ATTR_MAX)-1)
 
-/**
- * Socket memory info identifiers
- * @ingroup idiag
- */
-enum {
-	IDIAG_SK_MEMINFO_RMEM_ALLOC,
-	IDIAG_SK_MEMINFO_RCVBUF,
-	IDIAG_SK_MEMINFO_WMEM_ALLOC,
-	IDIAG_SK_MEMINFO_SNDBUF,
-	IDIAG_SK_MEMINFO_FWD_ALLOC,
-	IDIAG_SK_MEMINFO_WMEM_QUEUED,
-	IDIAG_SK_MEMINFO_OPTMEM,
-	IDIAG_SK_MEMINFO_BACKLOG,
-
-	IDIAG_SK_MEMINFO_VARS,
-};
+/* Keep these only for compatibility, DO NOT USE THEM */
+#define	IDIAG_SK_MEMINFO_RMEM_ALLOC SK_MEMINFO_RMEM_ALLOC
+#define	IDIAG_SK_MEMINFO_RCVBUF SK_MEMINFO_RCVBUF
+#define	IDIAG_SK_MEMINFO_WMEM_ALLOC SK_MEMINFO_WMEM_ALLOC
+#define	IDIAG_SK_MEMINFO_SNDBUF SK_MEMINFO_SNDBUF
+#define	IDIAG_SK_MEMINFO_FWD_ALLOC SK_MEMINFO_FWD_ALLOC
+#define	IDIAG_SK_MEMINFO_WMEM_QUEUED SK_MEMINFO_WMEM_QUEUED
+#define	IDIAG_SK_MEMINFO_OPTMEM SK_MEMINFO_OPTMEM
+#define	IDIAG_SK_MEMINFO_BACKLOG SK_MEMINFO_BACKLOG
+#define	IDIAG_SK_MEMINFO_VARS SK_MEMINFO_VARS
 
 /**
  * Socket timer indentifiers
diff --git a/lib/idiag/idiag_msg_obj.c b/lib/idiag/idiag_msg_obj.c
index 19e6c5b..f9d5b0f 100644
--- a/lib/idiag/idiag_msg_obj.c
+++ b/lib/idiag/idiag_msg_obj.c
@@ -528,24 +528,24 @@ static void idiag_msg_dump_stats(struct nl_object *obj, struct nl_dump_params *p
 
 	nl_dump(p, "skmeminfo:  [\n");
 	nl_dump(p, "\trmem alloc: %d\n",
-			msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_RMEM_ALLOC]);
+			msg->idiag_skmeminfo[SK_MEMINFO_RMEM_ALLOC]);
 	nl_dump(p, "\trcv buf: %s\n",
-			nl_size2str(msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_RCVBUF],
+			nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_RCVBUF],
 				buf, sizeof(buf)));
 	nl_dump(p, "\twmem alloc: %d\n",
-			msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_WMEM_ALLOC]);
+			msg->idiag_skmeminfo[SK_MEMINFO_WMEM_ALLOC]);
 	nl_dump(p, "\tsnd buf: %s\n",
-			nl_size2str(msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_SNDBUF],
+			nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_SNDBUF],
 				buf, sizeof(buf)));
 	nl_dump(p, "\tfwd alloc: %d\n",
-			msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_FWD_ALLOC]);
+			msg->idiag_skmeminfo[SK_MEMINFO_FWD_ALLOC]);
 	nl_dump(p, "\twmem queued: %s\n",
-			nl_size2str(msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_WMEM_QUEUED],
+			nl_size2str(msg->idiag_skmeminfo[SK_MEMINFO_WMEM_QUEUED],
 				buf, sizeof(buf)));
 	nl_dump(p, "\topt mem: %d\n",
-			msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_OPTMEM]);
+			msg->idiag_skmeminfo[SK_MEMINFO_OPTMEM]);
 	nl_dump(p, "\tbacklog: %d\n",
-			msg->idiag_skmeminfo[IDIAG_SK_MEMINFO_BACKLOG]);
+			msg->idiag_skmeminfo[SK_MEMINFO_BACKLOG]);
 	nl_dump(p, "]\n\n");
 }
 
@@ -585,7 +585,8 @@ static struct nla_policy ext_policy[IDIAG_ATTR_MAX] = {
 	[IDIAG_ATTR_CONG]       = { .type = NLA_STRING },
 	[IDIAG_ATTR_TOS]        = { .type = NLA_U8 },
 	[IDIAG_ATTR_TCLASS]     = { .type = NLA_U8 },
-	[IDIAG_ATTR_SKMEMINFO]  = { .minlen = (sizeof(uint32_t) * IDIAG_SK_MEMINFO_VARS)  },
+	/* Older kernel doesn't have SK_MEMINFO_BACKLOG */
+	[IDIAG_ATTR_SKMEMINFO]  = { .minlen = (sizeof(uint32_t) * (SK_MEMINFO_OPTMEM + 1)) },
 	[IDIAG_ATTR_SHUTDOWN]   = { .type = NLA_U8 },
 };
 
-- 
1.8.3.1




More information about the libnl mailing list