Commit 7a6a42d0 authored by Andrei Vagin's avatar Andrei Vagin

net: set a proper network namespace to create a socket

Each socket has to be restored from a proper network namespaces
where it was created.

We set a specified network namespace before restoring a socket.
A task network namespace is set after restoring all files.

v2: don't set the root netns for transport sockets
Acked-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
parent 2b6ed5bf
......@@ -85,4 +85,6 @@ static inline int sk_decode_shutdown(int val)
#define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
#endif
extern int set_netns(uint32_t ns_id);
#endif /* __CR_SOCKETS_H__ */
......@@ -676,6 +676,9 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
if (inet_validate_address(ie))
return -1;
if (set_netns(ie->ns_id))
return -1;
sk = socket(ie->family, ie->type, ie->proto);
if (sk < 0) {
pr_perror("Can't create inet socket");
......
......@@ -200,6 +200,9 @@ static int open_netlink_sk(struct file_desc *d, int *new_fd)
pr_info("Opening netlink socket id %#x\n", nse->id);
if (set_netns(nse->ns_id))
return -1;
sk = socket(PF_NETLINK, SOCK_RAW, nse->protocol);
if (sk < 0) {
pr_perror("Can't create netlink sock");
......
......@@ -475,6 +475,9 @@ static int open_packet_sk(struct file_desc *d, int *new_fd)
pr_info("Opening packet socket id %#x\n", pse->id);
if (set_netns(pse->ns_id))
return -1;
if (pse->type == SOCK_PACKET)
return open_packet_sk_spkt(pse, new_fd);
......
......@@ -1246,6 +1246,9 @@ static int open_unixsk_pair_master(struct unix_sk_info *ui, int *new_fd)
pr_info("Opening pair master (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer);
if (set_netns(ui->ue->ns_id))
return -1;
if (socketpair(PF_UNIX, ui->ue->type, 0, sk) < 0) {
pr_perror("Can't make socketpair");
return -1;
......@@ -1301,6 +1304,9 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
pr_info("Opening standalone socket (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer);
if (set_netns(ui->ue->ns_id))
return -1;
/*
* Check if this socket was connected to criu service.
* If so, put response, that dumping and restoring
......@@ -1404,7 +1410,6 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
return -1;
}
sk = socket(PF_UNIX, ui->ue->type, 0);
if (sk < 0) {
pr_perror("Can't make unix socket");
......
#include <sched.h>
#include <unistd.h>
#include <sys/socket.h>
#include <linux/netlink.h>
......@@ -24,6 +25,9 @@
#include "net.h"
#include "xmalloc.h"
#include "fs-magic.h"
#include "pstree.h"
#include "util.h"
#include "fdstore.h"
#ifndef SOCK_DIAG_BY_FAMILY
#define SOCK_DIAG_BY_FAMILY 20
......@@ -744,3 +748,37 @@ int collect_sockets(struct ns_id *ns)
return err;
}
static uint32_t last_ns_id = 0;
int set_netns(uint32_t ns_id)
{
struct ns_id *ns;
int nsfd;
if (!(root_ns_mask & CLONE_NEWNET))
return 0;
if (ns_id == last_ns_id)
return 0;
ns = lookup_ns_by_id(ns_id, &net_ns_desc);
if (ns == NULL) {
pr_err("Unable to find a network namespace\n");
return -1;
}
nsfd = fdstore_get(ns->net.nsfd_id);
if (nsfd < 0)
return -1;
if (setns(nsfd, CLONE_NEWNET)) {
pr_perror("Unable to switch a network namespace");
close(nsfd);
return -1;
}
last_ns_id = ns_id;
close(nsfd);
close_pid_proc();
return 0;
}
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