[CRIU] [PATCH 4/4] net: block all traffic in internal network (v2)

Andrey Vagin avagin at openvz.org
Tue Nov 17 12:19:39 PST 2015


From: Andrew Vagin <avagin at openvz.org>

Let's imagine that we have two local interconnected sockets.
Whe we are restoring tcp sockets, we need to disable the repair mode
to restore data in sending queues.

If traffic isn't blocked, a socket starts operating, but
in this time another end can be not restored yet.

$ test/zdtm.sh -r ns/static/socket-tcpbuf-local
...
(00.274632) 5: Error (sk-tcp.c:485): Can't restore 2 queue data (-1), want (1780919:1780919): Connection reset by peer

We create a separate chain to avoid conflicts with other rules.

https://bugs.openvz.org/browse/CRIU-96

v2: use iptables-restore to apply whole configuration for one call
Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
---
 net.c | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
 1 file changed, 83 insertions(+), 2 deletions(-)

diff --git a/net.c b/net.c
index 43232b9..bfdebad 100644
--- a/net.c
+++ b/net.c
@@ -956,6 +956,82 @@ int netns_keep_nsfd(void)
 	pr_info("Saved netns fd for links restore\n");
 	return 0;
 }
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+static int iptables_restore(bool ipv6, char *buf, int size)
+{
+	int pfd[2], ret = -1;
+	char *cmd4[] = {"iptables-restore",  "--noflush", NULL};
+	char *cmd6[] = {"ip6tables-restore", "--noflush", NULL};
+	char **cmd = ipv6 ? cmd6 : cmd4;;
+
+	if (pipe(pfd) < 0) {
+		pr_perror("Unable to create pipe");
+		return -1;
+	}
+
+	if (write(pfd[1], buf, size) < size) {
+		pr_perror("Unable to write iptables configugration");
+		goto err;
+	}
+	close_safe(&pfd[1]);
+
+	ret = cr_system(pfd[0], -1, -1, cmd[0], cmd, 0);
+err:
+	close_safe(&pfd[1]);
+	close_safe(&pfd[0]);
+	return ret;
+}
+
+static int network_lock_internal()
+{
+	char conf[] =	"*filter\n"
+				":CRIU - [0:0]\n"
+				"-I INPUT -j CRIU\n"
+				"-I OUTPUT -j CRIU\n"
+				"-A CRIU -j DROP\n"
+				"COMMIT\n";
+	int ret = 0, nsret;
+
+	if (switch_ns(root_item->pid.real, &net_ns_desc, &nsret))
+		return -1;
+
+
+	ret |= iptables_restore(false, conf, sizeof(conf) - 1);
+	if (kdat.ipv6)
+		ret |= iptables_restore(true, conf, sizeof(conf) - 1);
+
+	if (restore_ns(nsret, &net_ns_desc))
+		ret = -1;
+
+	return ret;
+}
+
+static int network_unlock_internal()
+{
+	char conf[] =	"*filter\n"
+			":CRIU - [0:0]\n"
+			"-D INPUT -j CRIU\n"
+			"-D OUTPUT -j CRIU\n"
+			"-X CRIU\n"
+			"COMMIT\n";
+	int ret = 0, nsret;
+
+	if (switch_ns(root_item->pid.real, &net_ns_desc, &nsret))
+		return -1;
+
+
+	ret |= iptables_restore(false, conf, sizeof(conf) - 1);
+	if (kdat.ipv6)
+		ret |= iptables_restore(true, conf, sizeof(conf) - 1);
+
+	if (restore_ns(nsret, &net_ns_desc))
+		ret = -1;
+
+	return ret;
+}
 
 int network_lock(void)
 {
@@ -965,7 +1041,10 @@ int network_lock(void)
 	if  (!(root_ns_mask & CLONE_NEWNET))
 		return 0;
 
-	return run_scripts(ACT_NET_LOCK);
+	if (run_scripts(ACT_NET_LOCK))
+		return -1;
+
+	return network_lock_internal();
 }
 
 void network_unlock(void)
@@ -975,8 +1054,10 @@ void network_unlock(void)
 	cpt_unlock_tcp_connections();
 	rst_unlock_tcp_connections();
 
-	if (root_ns_mask & CLONE_NEWNET)
+	if (root_ns_mask & CLONE_NEWNET) {
 		run_scripts(ACT_NET_UNLOCK);
+		network_unlock_internal();
+	}
 }
 
 int veth_pair_add(char *in, char *out)
-- 
2.4.3



More information about the CRIU mailing list