[CRIU] [PATCH 5/8] sockets: use socket diag for collecting netlink sockets

Andrey Vagin avagin at openvz.org
Mon Mar 25 11:28:46 EDT 2013


Signed-off-by: Andrey Vagin <avagin at openvz.org>
---
 include/sockets.h |  1 +
 sk-netlink.c      | 60 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 sockets.c         |  9 +++++++++
 3 files changed, 70 insertions(+)

diff --git a/include/sockets.h b/include/sockets.h
index 816f863..42509dc 100644
--- a/include/sockets.h
+++ b/include/sockets.h
@@ -57,6 +57,7 @@ extern int dump_one_unix(struct fd_parms *p, int lfd, const int fdinfo);
 
 extern int inet_collect_one(struct nlmsghdr *h, int family, int type, int proto);
 extern int unix_receive_one(struct nlmsghdr *h, void *);
+extern int netlink_receive_one(struct nlmsghdr *hdr, void *arg);
 
 extern int do_dump_opt(int sk, int level, int name, void *val, int len);
 #define dump_opt(s, l, n, f)	do_dump_opt(s, l, n, f, sizeof(*f))
diff --git a/sk-netlink.c b/sk-netlink.c
index f31cce5..fe26317 100644
--- a/sk-netlink.c
+++ b/sk-netlink.c
@@ -1,9 +1,69 @@
 #include <unistd.h>
+#include <linux/sock_diag.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
 
 #include "crtools.h"
+#include "files.h"
+#include "sockets.h"
+#include "util.h"
 
 #include "protobuf.h"
 #include "protobuf/sk-netlink.pb-c.h"
+#include "netlink_diag.h"
+#include "libnetlink.h"
+
+struct netlink_sk_desc {
+	struct socket_desc	sd;
+	u32                     portid;
+	u32			*groups;
+	u32			gsize;
+	u32                     dst_portid;
+	u32			dst_group;
+	u8			state;
+	u8			protocol;
+};
+
+int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
+{
+	struct rtattr *tb[NETLINK_DIAG_MAX+1];
+	struct netlink_diag_msg *m;
+	struct netlink_sk_desc *sd;
+	unsigned long *groups;
+
+	m = NLMSG_DATA(hdr);
+	pr_info("Collect netlink sock 0x%x\n", m->ndiag_ino);
+
+	sd = xmalloc(sizeof(*sd));
+	if (!sd)
+		return -1;
+
+	sd->protocol = m->ndiag_protocol;
+	sd->portid = m->ndiag_portid;
+	sd->dst_portid = m->ndiag_dst_portid;
+	sd->dst_group = m->ndiag_dst_group;
+	sd->state = m->ndiag_state;
+
+	parse_rtattr(tb, NETLINK_DIAG_MAX, (struct rtattr *)(m + 1),
+		     hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
+
+	if (tb[NETLINK_DIAG_GROUPS]) {
+		sd->gsize = RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]);
+		groups = RTA_DATA(tb[NETLINK_DIAG_GROUPS]);
+
+		sd->groups = xmalloc(sizeof(sd->gsize));
+		if (!sd->groups) {
+			xfree(sd);
+			return -1;
+		}
+		memcpy(sd->groups, groups, sd->gsize);
+	} else {
+		sd->groups = NULL;
+		sd->gsize = 0;
+	}
+
+	return sk_collect_one(m->ndiag_ino, PF_NETLINK, &sd->sd);
+}
 
 void show_netlinksk(int fd, struct cr_options *o)
 {
diff --git a/sockets.c b/sockets.c
index b854eb4..ee5d381 100644
--- a/sockets.c
+++ b/sockets.c
@@ -13,6 +13,7 @@
 #include "unix_diag.h"
 #include "inet_diag.h"
 #include "packet_diag.h"
+#include "netlink_diag.h"
 #include "files.h"
 #include "util-net.h"
 #include "sk-packet.h"
@@ -417,6 +418,7 @@ int collect_sockets(int pid)
 			struct unix_diag_req	u;
 			struct inet_diag_req_v2	i;
 			struct packet_diag_req	p;
+			struct netlink_diag_req n;
 		} r;
 	} req;
 
@@ -514,6 +516,13 @@ int collect_sockets(int pid)
 	if (tmp)
 		err = tmp;
 
+	req.r.n.sdiag_family	= AF_NETLINK;
+	req.r.n.sdiag_protocol	= NDIAG_PROTO_ALL;
+	req.r.n.ndiag_show	= NDIAG_SHOW_GROUPS;
+	tmp = do_rtnl_req(nl, &req, sizeof(req), netlink_receive_one, NULL);
+	if (tmp)
+		err = tmp;
+
 	close(nl);
 out:
 	if (rst >= 0) {
-- 
1.7.11.7



More information about the CRIU mailing list