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) ...@@ -85,4 +85,6 @@ static inline int sk_decode_shutdown(int val)
#define NETLINK_SOCK_DIAG NETLINK_INET_DIAG #define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
#endif #endif
extern int set_netns(uint32_t ns_id);
#endif /* __CR_SOCKETS_H__ */ #endif /* __CR_SOCKETS_H__ */
...@@ -676,6 +676,9 @@ static int open_inet_sk(struct file_desc *d, int *new_fd) ...@@ -676,6 +676,9 @@ static int open_inet_sk(struct file_desc *d, int *new_fd)
if (inet_validate_address(ie)) if (inet_validate_address(ie))
return -1; return -1;
if (set_netns(ie->ns_id))
return -1;
sk = socket(ie->family, ie->type, ie->proto); sk = socket(ie->family, ie->type, ie->proto);
if (sk < 0) { if (sk < 0) {
pr_perror("Can't create inet socket"); pr_perror("Can't create inet socket");
......
...@@ -200,6 +200,9 @@ static int open_netlink_sk(struct file_desc *d, int *new_fd) ...@@ -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); 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); sk = socket(PF_NETLINK, SOCK_RAW, nse->protocol);
if (sk < 0) { if (sk < 0) {
pr_perror("Can't create netlink sock"); pr_perror("Can't create netlink sock");
......
...@@ -475,6 +475,9 @@ static int open_packet_sk(struct file_desc *d, int *new_fd) ...@@ -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); pr_info("Opening packet socket id %#x\n", pse->id);
if (set_netns(pse->ns_id))
return -1;
if (pse->type == SOCK_PACKET) if (pse->type == SOCK_PACKET)
return open_packet_sk_spkt(pse, new_fd); 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) ...@@ -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", pr_info("Opening pair master (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer); 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) { if (socketpair(PF_UNIX, ui->ue->type, 0, sk) < 0) {
pr_perror("Can't make socketpair"); pr_perror("Can't make socketpair");
return -1; return -1;
...@@ -1301,6 +1304,9 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd) ...@@ -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", pr_info("Opening standalone socket (id %#x ino %#x peer %#x)\n",
ui->ue->id, ui->ue->ino, ui->ue->peer); 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. * Check if this socket was connected to criu service.
* If so, put response, that dumping and restoring * 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) ...@@ -1404,7 +1410,6 @@ static int open_unixsk_standalone(struct unix_sk_info *ui, int *new_fd)
return -1; return -1;
} }
sk = socket(PF_UNIX, ui->ue->type, 0); sk = socket(PF_UNIX, ui->ue->type, 0);
if (sk < 0) { if (sk < 0) {
pr_perror("Can't make unix socket"); pr_perror("Can't make unix socket");
......
#include <sched.h>
#include <unistd.h> #include <unistd.h>
#include <sys/socket.h> #include <sys/socket.h>
#include <linux/netlink.h> #include <linux/netlink.h>
...@@ -24,6 +25,9 @@ ...@@ -24,6 +25,9 @@
#include "net.h" #include "net.h"
#include "xmalloc.h" #include "xmalloc.h"
#include "fs-magic.h" #include "fs-magic.h"
#include "pstree.h"
#include "util.h"
#include "fdstore.h"
#ifndef SOCK_DIAG_BY_FAMILY #ifndef SOCK_DIAG_BY_FAMILY
#define SOCK_DIAG_BY_FAMILY 20 #define SOCK_DIAG_BY_FAMILY 20
...@@ -744,3 +748,37 @@ int collect_sockets(struct ns_id *ns) ...@@ -744,3 +748,37 @@ int collect_sockets(struct ns_id *ns)
return err; 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