[CRIU] [PATCH] netlink: Use nlattr instead of rtattr

Andrey Vagin avagin at openvz.org
Mon Feb 22 15:38:05 PST 2016


From: Andrew Vagin <avagin at virtuozzo.com>

because the kernel uses nlattr for these messages.

Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 criu/include/libnetlink.h |  3 ---
 criu/libnetlink.c         | 16 ++--------------
 criu/net.c                | 26 +++++++++++++-------------
 criu/sk-inet.c            |  8 ++++----
 criu/sk-netlink.c         | 10 +++++-----
 criu/sk-packet.c          | 17 +++++++++--------
 criu/sk-unix.c            | 22 +++++++++++-----------
 7 files changed, 44 insertions(+), 58 deletions(-)

diff --git a/criu/include/libnetlink.h b/criu/include/libnetlink.h
index 92eded4..591af0e 100644
--- a/criu/include/libnetlink.h
+++ b/criu/include/libnetlink.h
@@ -3,9 +3,6 @@
 
 #define CR_NLMSG_SEQ		24680	/* arbitrary chosen */
 
-extern int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len);
-#define parse_rtattr_nested(tb, max, rta) \
-	(parse_rtattr((tb), (max), RTA_DATA(rta), RTA_PAYLOAD(rta)))
 extern int do_rtnl_req(int nl, void *req, int size,
 		int (*receive_callback)(struct nlmsghdr *h, void *),
 		int (*error_callback)(int err, void *), void *);
diff --git a/criu/libnetlink.c b/criu/libnetlink.c
index 49c804f..4a651cb 100644
--- a/criu/libnetlink.c
+++ b/criu/libnetlink.c
@@ -2,25 +2,13 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <libnl3/netlink/attr.h>
 #include <string.h>
 #include <unistd.h>
 
 #include "libnetlink.h"
 #include "util.h"
 
-int parse_rtattr(struct rtattr *tb[], int max, struct rtattr *rta, int len)
-{
-	memset(tb, 0, sizeof(struct rtattr *) * (max + 1));
-	while (RTA_OK(rta, len)) {
-		if ((rta->rta_type <= max) && (!tb[rta->rta_type]))
-			tb[rta->rta_type] = rta;
-		rta = RTA_NEXT(rta, len);
-	}
-	if (len)
-		pr_warn("Trimmed RTA: len %d, rta_len %d\n", len, rta->rta_len);
-	return 0;
-}
-
 static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *), 
 		int (*err_cb)(int, void *), void *arg)
 {
@@ -143,7 +131,7 @@ err:
 int addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data,
 		int alen)
 {
-	int len = RTA_LENGTH(alen);
+	int len = nla_attr_size(alen);
 	struct rtattr *rta;
 
 	if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) {
diff --git a/criu/net.c b/criu/net.c
index a67cd6e..faed2bd 100644
--- a/criu/net.c
+++ b/criu/net.c
@@ -152,7 +152,7 @@ int write_netdev_img(NetDeviceEntry *nde, struct cr_imgset *fds)
 }
 
 static int dump_one_netdev(int type, struct ifinfomsg *ifi,
-		struct rtattr **tb, struct cr_imgset *fds,
+		struct nlattr **tb, struct cr_imgset *fds,
 		int (*dump)(NetDeviceEntry *, struct cr_imgset *))
 {
 	int ret;
@@ -171,8 +171,8 @@ static int dump_one_netdev(int type, struct ifinfomsg *ifi,
 
 	if (tb[IFLA_ADDRESS] && (type != ND_TYPE__LOOPBACK)) {
 		netdev.has_address = true;
-		netdev.address.data = RTA_DATA(tb[IFLA_ADDRESS]);
-		netdev.address.len = RTA_PAYLOAD(tb[IFLA_ADDRESS]);
+		netdev.address.data = nla_data(tb[IFLA_ADDRESS]);
+		netdev.address.len = nla_len(tb[IFLA_ADDRESS]);
 		pr_info("Found ll addr (%02x:../%d) for %s\n",
 				(int)netdev.address.data[0],
 				(int)netdev.address.len, netdev.name);
@@ -196,26 +196,26 @@ err_free:
 	return ret;
 }
 
-static char *link_kind(struct ifinfomsg *ifi, struct rtattr **tb)
+static char *link_kind(struct ifinfomsg *ifi, struct nlattr **tb)
 {
-	struct rtattr *linkinfo[IFLA_INFO_MAX + 1];
+	struct nlattr *linkinfo[IFLA_INFO_MAX + 1];
 
 	if (!tb[IFLA_LINKINFO]) {
 		pr_err("No linkinfo for eth link %d\n", ifi->ifi_index);
 		return NULL;
 	}
 
-	parse_rtattr_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO]);
+	nla_parse_nested(linkinfo, IFLA_INFO_MAX, tb[IFLA_LINKINFO], NULL);
 	if (!linkinfo[IFLA_INFO_KIND]) {
 		pr_err("No kind for eth link %d\n", ifi->ifi_index);
 		return NULL;
 	}
 
-	return RTA_DATA(linkinfo[IFLA_INFO_KIND]);
+	return nla_data(linkinfo[IFLA_INFO_KIND]);
 }
 
 static int dump_unknown_device(struct ifinfomsg *ifi, char *kind,
-		struct rtattr **tb, struct cr_imgset *fds)
+		struct nlattr **tb, struct cr_imgset *fds)
 {
 	int ret;
 
@@ -265,7 +265,7 @@ static int dump_bridge(NetDeviceEntry *nde, struct cr_imgset *imgset)
 }
 
 static int dump_one_ethernet(struct ifinfomsg *ifi, char *kind,
-		struct rtattr **tb, struct cr_imgset *fds)
+		struct nlattr **tb, struct cr_imgset *fds)
 {
 	if (!strcmp(kind, "veth"))
 		/*
@@ -286,7 +286,7 @@ static int dump_one_ethernet(struct ifinfomsg *ifi, char *kind,
 }
 
 static int dump_one_gendev(struct ifinfomsg *ifi, char *kind,
-		struct rtattr **tb, struct cr_imgset *fds)
+		struct nlattr **tb, struct cr_imgset *fds)
 {
 	if (!strcmp(kind, "tun"))
 		return dump_one_netdev(ND_TYPE__TUN, ifi, tb, fds, dump_tun_link);
@@ -295,7 +295,7 @@ static int dump_one_gendev(struct ifinfomsg *ifi, char *kind,
 }
 
 static int dump_one_voiddev(struct ifinfomsg *ifi, char *kind,
-		struct rtattr **tb, struct cr_imgset *fds)
+		struct nlattr **tb, struct cr_imgset *fds)
 {
 	if (!strcmp(kind, "venet"))
 		return dump_one_netdev(ND_TYPE__VENET, ifi, tb, fds, NULL);
@@ -308,7 +308,7 @@ static int dump_one_link(struct nlmsghdr *hdr, void *arg)
 	struct cr_imgset *fds = arg;
 	struct ifinfomsg *ifi;
 	int ret = 0, len = hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*ifi));
-	struct rtattr *tb[IFLA_MAX + 1];
+	struct nlattr *tb[IFLA_MAX + 1];
 	char *kind;
 
 	ifi = NLMSG_DATA(hdr);
@@ -318,7 +318,7 @@ static int dump_one_link(struct nlmsghdr *hdr, void *arg)
 		return -1;
 	}
 
-	parse_rtattr(tb, IFLA_MAX, IFLA_RTA(ifi), len);
+	nlmsg_parse(hdr, sizeof(struct ifinfomsg), tb, IFLA_MAX, NULL);
 	pr_info("\tLD: Got link %d, type %d\n", ifi->ifi_index, ifi->ifi_type);
 
 	if (ifi->ifi_type == ARPHRD_LOOPBACK) 
diff --git a/criu/sk-inet.c b/criu/sk-inet.c
index 4d11107..63bd058 100644
--- a/criu/sk-inet.c
+++ b/criu/sk-inet.c
@@ -2,6 +2,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <libnl3/netlink/msg.h>
 #include <net/if.h>
 #include <sys/mman.h>
 #include <unistd.h>
@@ -404,11 +405,10 @@ int inet_collect_one(struct nlmsghdr *h, int family, int type)
 {
 	struct inet_sk_desc *d;
 	struct inet_diag_msg *m = NLMSG_DATA(h);
-	struct rtattr *tb[INET_DIAG_MAX+1];
+	struct nlattr *tb[INET_DIAG_MAX+1];
 	int ret;
 
-	parse_rtattr(tb, INET_DIAG_MAX, (struct rtattr *)(m + 1),
-		     h->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
+	nlmsg_parse(h, sizeof(struct inet_diag_msg), tb, INET_DIAG_MAX, NULL);
 
 	d = xzalloc(sizeof(*d));
 	if (!d)
@@ -424,7 +424,7 @@ int inet_collect_one(struct nlmsghdr *h, int family, int type)
 	memcpy(d->dst_addr, m->id.idiag_dst, sizeof(u32) * 4);
 
 	if (tb[INET_DIAG_SHUTDOWN])
-		d->shutdown = *(u8 *)RTA_DATA(tb[INET_DIAG_SHUTDOWN]);
+		d->shutdown = nla_get_u8(tb[INET_DIAG_SHUTDOWN]);
 	else
 		pr_err_once("Can't check shutdown state of inet socket\n");
 
diff --git a/criu/sk-netlink.c b/criu/sk-netlink.c
index 67cb681..f839faf 100644
--- a/criu/sk-netlink.c
+++ b/criu/sk-netlink.c
@@ -1,6 +1,7 @@
 #include <unistd.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <libnl3/netlink/msg.h>
 
 #include "imgset.h"
 #include "files.h"
@@ -25,7 +26,7 @@ struct netlink_sk_desc {
 
 int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
 {
-	struct rtattr *tb[NETLINK_DIAG_MAX+1];
+	struct nlattr *tb[NETLINK_DIAG_MAX+1];
 	struct netlink_diag_msg *m;
 	struct netlink_sk_desc *sd;
 	unsigned long *groups;
@@ -43,12 +44,11 @@ int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
 	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)));
+	nlmsg_parse(hdr, sizeof(struct netlink_diag_msg), tb, NETLINK_DIAG_MAX, NULL);
 
 	if (tb[NETLINK_DIAG_GROUPS]) {
-		sd->gsize = RTA_PAYLOAD(tb[NETLINK_DIAG_GROUPS]);
-		groups = RTA_DATA(tb[NETLINK_DIAG_GROUPS]);
+		sd->gsize = nla_len(tb[NETLINK_DIAG_GROUPS]);
+		groups = nla_data(tb[NETLINK_DIAG_GROUPS]);
 
 		sd->groups = xmalloc(sd->gsize);
 		if (!sd->groups) {
diff --git a/criu/sk-packet.c b/criu/sk-packet.c
index 7573859..9d324a9 100644
--- a/criu/sk-packet.c
+++ b/criu/sk-packet.c
@@ -2,6 +2,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <libnl3/netlink/msg.h>
 #include <unistd.h>
 #include <string.h>
 #include "asm/types.h"
@@ -227,27 +228,27 @@ int dump_socket_map(struct vma_area *vma)
 	return 0;
 }
 
-static int packet_save_mreqs(struct packet_sock_desc *sd, struct rtattr *mc)
+static int packet_save_mreqs(struct packet_sock_desc *sd, struct nlattr *mc)
 {
-	sd->mreq_n = RTA_PAYLOAD(mc) / sizeof(struct packet_diag_mclist);
+	sd->mreq_n = nla_len(mc) / sizeof(struct packet_diag_mclist);
 	pr_debug("\tGot %d mreqs\n", sd->mreq_n);
-	sd->mreqs = xmalloc(RTA_PAYLOAD(mc));
+	sd->mreqs = xmalloc(nla_len(mc));
 	if (!sd->mreqs)
 		return -1;
 
-	memcpy(sd->mreqs, RTA_DATA(mc), RTA_PAYLOAD(mc));
+	memcpy(sd->mreqs, nla_data(mc), nla_len(mc));
 	return 0;
 }
 
 int packet_receive_one(struct nlmsghdr *hdr, void *arg)
 {
 	struct packet_diag_msg *m;
-	struct rtattr *tb[PACKET_DIAG_MAX + 1];
+	struct nlattr *tb[PACKET_DIAG_MAX + 1];
 	struct packet_sock_desc *sd;
 
 	m = NLMSG_DATA(hdr);
-	parse_rtattr(tb, PACKET_DIAG_MAX, (struct rtattr *)(m + 1),
-			hdr->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
+	nlmsg_parse(hdr, sizeof(struct packet_diag_msg),
+			tb, PACKET_DIAG_MAX, NULL);
 	pr_info("Collect packet sock %u %u\n", m->pdiag_ino, (unsigned int)m->pdiag_num);
 
 	if (!tb[PACKET_DIAG_INFO]) {
@@ -269,7 +270,7 @@ int packet_receive_one(struct nlmsghdr *hdr, void *arg)
 	sd->proto = htons(m->pdiag_num);
 	sd->rx = NULL;
 	sd->tx = NULL;
-	memcpy(&sd->nli, RTA_DATA(tb[PACKET_DIAG_INFO]), sizeof(sd->nli));
+	memcpy(&sd->nli, nla_data(tb[PACKET_DIAG_INFO]), sizeof(sd->nli));
 
 	if (packet_save_mreqs(sd, tb[PACKET_DIAG_MCLIST]))
 		goto err;
diff --git a/criu/sk-unix.c b/criu/sk-unix.c
index 96aa689..a0a848e 100644
--- a/criu/sk-unix.c
+++ b/criu/sk-unix.c
@@ -1,6 +1,7 @@
 #include <sys/socket.h>
 #include <linux/netlink.h>
 #include <linux/rtnetlink.h>
+#include <libnl3/netlink/msg.h>
 #include <unistd.h>
 #include <netinet/tcp.h>
 #include <sys/stat.h>
@@ -474,17 +475,17 @@ const struct fdtype_ops unix_dump_ops = {
 /*
  * Returns: < 0 on error, 0 if OK, 1 to skip the socket
  */
-static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg *m, struct rtattr **tb)
+static int unix_process_name(struct unix_sk_desc *d, const struct unix_diag_msg *m, struct nlattr **tb)
 {
 	int len, ret;
 	char *name;
 
-	len = RTA_PAYLOAD(tb[UNIX_DIAG_NAME]);
+	len = nla_len(tb[UNIX_DIAG_NAME]);
 	name = xmalloc(len + 1);
 	if (!name)
 		return -ENOMEM;
 
-	memcpy(name, RTA_DATA(tb[UNIX_DIAG_NAME]), len);
+	memcpy(name, nla_data(tb[UNIX_DIAG_NAME]), len);
 	name[len] = '\0';
 
 	if (name[0] != '\0') {
@@ -580,7 +581,7 @@ skip:
 }
 
 static int unix_collect_one(const struct unix_diag_msg *m,
-			    struct rtattr **tb)
+			    struct nlattr **tb)
 {
 	struct unix_sk_desc *d;
 	int ret = 0;
@@ -598,12 +599,12 @@ static int unix_collect_one(const struct unix_diag_msg *m,
 	d->fd = -1;
 
 	if (tb[UNIX_DIAG_SHUTDOWN])
-		d->shutdown = *(u8 *)RTA_DATA(tb[UNIX_DIAG_SHUTDOWN]);
+		d->shutdown = nla_get_u8(tb[UNIX_DIAG_SHUTDOWN]);
 	else
 		pr_err_once("No socket shutdown info\n");
 
 	if (tb[UNIX_DIAG_PEER])
-		d->peer_ino = *(int *)RTA_DATA(tb[UNIX_DIAG_PEER]);
+		d->peer_ino = nla_get_u32(tb[UNIX_DIAG_PEER]);
 
 	if (tb[UNIX_DIAG_NAME]) {
 		ret = unix_process_name(d, m, tb);
@@ -615,14 +616,14 @@ static int unix_collect_one(const struct unix_diag_msg *m,
 	}
 
 	if (tb[UNIX_DIAG_ICONS]) {
-		int len = RTA_PAYLOAD(tb[UNIX_DIAG_ICONS]);
+		int len = nla_len(tb[UNIX_DIAG_ICONS]);
 		int i;
 
 		d->icons = xmalloc(len);
 		if (!d->icons)
 			goto err;
 
-		memcpy(d->icons, RTA_DATA(tb[UNIX_DIAG_ICONS]), len);
+		memcpy(d->icons, nla_data(tb[UNIX_DIAG_ICONS]), len);
 		d->nr_icons = len / sizeof(u32);
 
 		/*
@@ -673,10 +674,9 @@ skip:
 int unix_receive_one(struct nlmsghdr *h, void *arg)
 {
 	struct unix_diag_msg *m = NLMSG_DATA(h);
-	struct rtattr *tb[UNIX_DIAG_MAX+1];
+	struct nlattr *tb[UNIX_DIAG_MAX+1];
 
-	parse_rtattr(tb, UNIX_DIAG_MAX, (struct rtattr *)(m + 1),
-		     h->nlmsg_len - NLMSG_LENGTH(sizeof(*m)));
+	nlmsg_parse(h, sizeof(struct unix_diag_msg), tb, UNIX_DIAG_MAX, NULL);
 
 	return unix_collect_one(m, tb);
 }
-- 
2.5.0



More information about the CRIU mailing list