Commit bab4e9c9 authored by Andrew Vagin's avatar Andrew Vagin Committed by Pavel Emelyanov

netlink: Use nlattr instead of rtattr

because the kernel uses nlattr for these messages.
Signed-off-by: 's avatarAndrew Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent cae683dc
......@@ -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 *);
......
......@@ -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) {
......
......@@ -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)
......
......@@ -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");
......
#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) {
......
......@@ -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;
......
#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);
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment