Commit 4ea9cf33 authored by Andrei Vagin's avatar Andrei Vagin

netlink: add ns_id as a generic argument to receive_callback

ns_id will be used to collect sockets and other per-netns
resources

travis-ci: success for Dump and restore nested network namespaces (rev4)
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
Reviewed-by: 's avatarDmitry Safonov <dsafonov@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent bbbe4f26
......@@ -3,9 +3,10 @@
#define CR_NLMSG_SEQ 24680 /* arbitrary chosen */
struct ns_id;
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 *);
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
int (*error_callback)(int err, void *), struct ns_id *ns, void *);
extern int addattr_l(struct nlmsghdr *n, int maxlen, int type,
const void *data, int alen);
......
......@@ -15,7 +15,7 @@ extern int dump_socket_map(struct vma_area *vma);
extern int collect_socket_map(struct vma_area *);
struct nlmsghdr;
extern int packet_receive_one(struct nlmsghdr *h, void *arg);
extern int packet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg);
#ifndef PACKET_VNET_HDR
#define PACKET_VNET_HDR 15
......
......@@ -50,9 +50,9 @@ extern const struct fdtype_ops inet6_dump_ops;
extern const struct fdtype_ops netlink_dump_ops;
extern const struct fdtype_ops packet_dump_ops;
extern int inet_collect_one(struct nlmsghdr *h, int family, int type);
extern int unix_receive_one(struct nlmsghdr *h, void *);
extern int netlink_receive_one(struct nlmsghdr *hdr, void *arg);
extern int inet_collect_one(struct nlmsghdr *h, int family, int type, struct ns_id *ns);
extern int unix_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *);
extern int netlink_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg);
extern int unix_sk_id_add(unsigned int ino);
extern int unix_sk_ids_parse(char *optarg);
......
......@@ -10,8 +10,9 @@
#include "libnetlink.h"
#include "util.h"
static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *),
int (*err_cb)(int, void *), void *arg)
static int nlmsg_receive(char *buf, int len,
int (*cb)(struct nlmsghdr *, struct ns_id *ns, void *),
int (*err_cb)(int, void *), struct ns_id *ns, void *arg)
{
struct nlmsghdr *hdr;
......@@ -42,7 +43,7 @@ static int nlmsg_receive(char *buf, int len, int (*cb)(struct nlmsghdr *, void *
return err_cb(err->error, arg);
}
if (cb(hdr, arg))
if (cb(hdr, ns, arg))
return -1;
}
......@@ -56,8 +57,8 @@ static int rtnl_return_err(int err, void *arg)
}
int do_rtnl_req(int nl, void *req, int size,
int (*receive_callback)(struct nlmsghdr *h, void *),
int (*error_callback)(int err, void *), void *arg)
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
int (*error_callback)(int err, void *), struct ns_id *ns, void *arg)
{
struct msghdr msg;
struct sockaddr_nl nladdr;
......@@ -116,7 +117,7 @@ int do_rtnl_req(int nl, void *req, int size,
goto err;
}
err = nlmsg_receive(buf, err, receive_callback, error_callback, arg);
err = nlmsg_receive(buf, err, receive_callback, error_callback, ns, arg);
if (err < 0)
goto err;
if (err == 0)
......
......@@ -783,7 +783,7 @@ static int dump_one_sit(struct ifinfomsg *ifi, char *kind,
return dump_one_netdev(ND_TYPE__SIT, ifi, tb, fds, dump_sit);
}
static int dump_one_link(struct nlmsghdr *hdr, void *arg)
static int dump_one_link(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
{
struct cr_imgset *fds = arg;
struct ifinfomsg *ifi;
......@@ -833,7 +833,7 @@ unk:
return ret;
}
static int dump_one_nf(struct nlmsghdr *hdr, void *arg)
static int dump_one_nf(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
{
struct cr_img *img = arg;
......@@ -946,7 +946,7 @@ static int restore_nf_ct(int pid, int type)
goto out;
nlh->nlmsg_flags = NLM_F_REQUEST|NLM_F_ACK|NLM_F_CREATE;
ret = do_rtnl_req(sk, nlh, nlh->nlmsg_len, NULL, NULL, NULL);
ret = do_rtnl_req(sk, nlh, nlh->nlmsg_len, NULL, NULL, NULL, NULL);
if (ret)
goto out;
}
......@@ -995,7 +995,7 @@ static int dump_nf_ct(struct cr_imgset *fds, int type)
img = img_from_set(fds, type);
ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_nf, NULL, img);
ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_nf, NULL, NULL, img);
close(sk);
out:
return ret;
......@@ -1026,13 +1026,13 @@ static int dump_links(struct cr_imgset *fds)
req.nlh.nlmsg_seq = CR_NLMSG_SEQ;
req.g.rtgen_family = AF_PACKET;
ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, fds);
ret = do_rtnl_req(sk, &req, sizeof(req), dump_one_link, NULL, NULL, fds);
close(sk);
out:
return ret;
}
static int restore_link_cb(struct nlmsghdr *hdr, void *arg)
static int restore_link_cb(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
{
pr_info("Got response on SETLINK =)\n");
return 0;
......@@ -1116,7 +1116,7 @@ static int do_rtm_link_req(int msg_type, NetDeviceEntry *nde, int nlsk,
if (populate_newlink_req(&req, msg_type, nde, link_info, extras) < 0)
return -1;
return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL);
return do_rtnl_req(nlsk, &req, req.h.nlmsg_len, restore_link_cb, NULL, NULL, NULL);
}
int restore_link_parms(NetDeviceEntry *nde, int nlsk)
......@@ -1270,7 +1270,7 @@ static int userns_restore_one_link(void *arg, int fd, pid_t pid)
addattr_l(&req->h, sizeof(*req), IFLA_NET_NS_FD, &fd, sizeof(fd));
ret = do_rtnl_req(nlsk, req, req->h.nlmsg_len, restore_link_cb, NULL, NULL);
ret = do_rtnl_req(nlsk, req, req->h.nlmsg_len, restore_link_cb, NULL, NULL, NULL);
close(nlsk);
out:
......
......@@ -484,7 +484,7 @@ const struct fdtype_ops inet6_dump_ops = {
.dump = dump_one_inet6_fd,
};
int inet_collect_one(struct nlmsghdr *h, int family, int type)
int inet_collect_one(struct nlmsghdr *h, int family, int type, struct ns_id *ns)
{
struct inet_sk_desc *d;
struct inet_diag_msg *m = NLMSG_DATA(h);
......
......@@ -24,7 +24,7 @@ struct netlink_sk_desc {
u8 protocol;
};
int netlink_receive_one(struct nlmsghdr *hdr, void *arg)
int netlink_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
{
struct nlattr *tb[NETLINK_DIAG_MAX+1];
struct netlink_diag_msg *m;
......
......@@ -247,7 +247,7 @@ static int packet_save_mreqs(struct packet_sock_desc *sd, struct nlattr *mc)
return 0;
}
int packet_receive_one(struct nlmsghdr *hdr, void *arg)
int packet_receive_one(struct nlmsghdr *hdr, struct ns_id *ns, void *arg)
{
struct packet_diag_msg *m;
struct nlattr *tb[PACKET_DIAG_MAX + 1];
......
......@@ -588,7 +588,7 @@ skip:
}
static int unix_collect_one(const struct unix_diag_msg *m,
struct nlattr **tb)
struct nlattr **tb, struct ns_id *ns)
{
struct unix_sk_desc *d;
int ret = 0;
......@@ -679,14 +679,14 @@ skip:
return ret;
}
int unix_receive_one(struct nlmsghdr *h, void *arg)
int unix_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
{
struct unix_diag_msg *m = NLMSG_DATA(h);
struct nlattr *tb[UNIX_DIAG_MAX+1];
nlmsg_parse(h, sizeof(struct unix_diag_msg), tb, UNIX_DIAG_MAX, NULL);
return unix_collect_one(m, tb);
return unix_collect_one(m, tb, ns);
}
static int dump_external_sockets(struct unix_sk_desc *peer)
......
......@@ -116,7 +116,7 @@ bool socket_test_collect_bit(unsigned int family, unsigned int proto)
return test_bit(nr, socket_cl_bits) != 0;
}
static int probe_recv_one(struct nlmsghdr *h, void *arg)
static int probe_recv_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
{
pr_err("PROBE RECEIVED\n");
return -1;
......@@ -135,7 +135,7 @@ static int probe_err(int err, void *arg)
static inline void probe_diag(int nl, struct sock_diag_req *req, int expected_err)
{
do_rtnl_req(nl, req, req->hdr.nlmsg_len, probe_recv_one, probe_err, &expected_err);
do_rtnl_req(nl, req, req->hdr.nlmsg_len, probe_recv_one, probe_err, NULL, &expected_err);
}
void preload_socket_modules(void)
......@@ -588,7 +588,7 @@ int dump_socket(struct fd_parms *p, int lfd, FdinfoEntry *e)
return do_dump_gen_file(p, lfd, ops, e);
}
static int inet_receive_one(struct nlmsghdr *h, void *arg)
static int inet_receive_one(struct nlmsghdr *h, struct ns_id *ns, void *arg)
{
struct inet_diag_req_v2 *i = arg;
int type;
......@@ -606,15 +606,16 @@ static int inet_receive_one(struct nlmsghdr *h, void *arg)
return -1;
}
return inet_collect_one(h, i->sdiag_family, type);
return inet_collect_one(h, i->sdiag_family, type, ns);
}
static int do_collect_req(int nl, struct sock_diag_req *req, int size,
int (*receive_callback)(struct nlmsghdr *h, void *), void *arg)
int (*receive_callback)(struct nlmsghdr *h, struct ns_id *ns, void *),
struct ns_id *ns, void *arg)
{
int tmp;
tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, arg);
tmp = do_rtnl_req(nl, req, size, receive_callback, NULL, ns, arg);
if (tmp == 0)
set_collect_bit(req->r.n.sdiag_family, req->r.n.sdiag_protocol);
......@@ -640,7 +641,7 @@ int collect_sockets(struct ns_id *ns)
req.r.u.udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_VFS |
UDIAG_SHOW_PEER | UDIAG_SHOW_ICONS |
UDIAG_SHOW_RQLEN;
tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, NULL);
tmp = do_collect_req(nl, &req, sizeof(req), unix_receive_one, ns, NULL);
if (tmp)
err = tmp;
......@@ -653,7 +654,7 @@ int collect_sockets(struct ns_id *ns)
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING) | (1 << TCP_SYN_SENT);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -662,7 +663,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDP;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -671,7 +672,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDPLITE;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -684,7 +685,7 @@ int collect_sockets(struct ns_id *ns)
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING) | (1 << TCP_SYN_SENT);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -693,7 +694,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDP;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -702,7 +703,7 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_UDPLITE;
req.r.i.idiag_ext = 0;
req.r.i.idiag_states = -1; /* All */
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, &req.r.i);
tmp = do_collect_req(nl, &req, sizeof(req), inet_receive_one, ns, &req.r.i);
if (tmp)
err = tmp;
......@@ -710,7 +711,7 @@ int collect_sockets(struct ns_id *ns)
req.r.p.sdiag_protocol = 0;
req.r.p.pdiag_show = PACKET_SHOW_INFO | PACKET_SHOW_MCLIST |
PACKET_SHOW_FANOUT | PACKET_SHOW_RING_CFG;
tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, NULL);
tmp = do_collect_req(nl, &req, sizeof(req), packet_receive_one, ns, NULL);
if (tmp) {
pr_warn("The current kernel doesn't support packet_diag\n");
if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
......@@ -720,7 +721,7 @@ int collect_sockets(struct ns_id *ns)
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_collect_req(nl, &req, sizeof(req), netlink_receive_one, NULL);
tmp = do_collect_req(nl, &req, sizeof(req), netlink_receive_one, ns, NULL);
if (tmp) {
pr_warn("The current kernel doesn't support netlink_diag\n");
if (ns->ns_pid == 0 || tmp != -ENOENT) /* Fedora 19 */
......
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