Commit 5cb2893f authored by Andrei Vagin's avatar Andrei Vagin Committed by Pavel Emelyanov

tcp: allow to dump intermediate closing states

soccr already knows how to restore this sockets.

CRIU has to ...:
* unlock all packets with the SOCCR_MARK mark
* request half-closed socket via socket_diag
* transpit src and dst addresses to libsoccr

v2: remove SOCCR_FLAGS_ACKED_FIN
travis-ci: success for series starting with [01/21] build: install libnet-dev
Signed-off-by: 's avatarAndrei Vagin <avagin@virtuozzo.com>
Signed-off-by: 's avatarPavel Emelyanov <xemul@virtuozzo.com>
parent e7f03fba
...@@ -15,6 +15,8 @@ ...@@ -15,6 +15,8 @@
#include <linux/sockios.h> #include <linux/sockios.h>
#include <libnl3/netlink/msg.h> #include <libnl3/netlink/msg.h>
#include "../soccr/soccr.h"
#include "imgset.h" #include "imgset.h"
#include "namespaces.h" #include "namespaces.h"
#include "net.h" #include "net.h"
...@@ -1767,6 +1769,7 @@ int network_lock_internal() ...@@ -1767,6 +1769,7 @@ int network_lock_internal()
":CRIU - [0:0]\n" ":CRIU - [0:0]\n"
"-I INPUT -j CRIU\n" "-I INPUT -j CRIU\n"
"-I OUTPUT -j CRIU\n" "-I OUTPUT -j CRIU\n"
"-A CRIU -m mark --mark " __stringify(SOCCR_MARK) " -j ACCEPT\n"
"-A CRIU -j DROP\n" "-A CRIU -j DROP\n"
"COMMIT\n"; "COMMIT\n";
int ret = 0, nsret; int ret = 0, nsret;
......
...@@ -5,6 +5,8 @@ ...@@ -5,6 +5,8 @@
#include <sys/wait.h> #include <sys/wait.h>
#include <stdlib.h> #include <stdlib.h>
#include "../soccr/soccr.h"
#include "util.h" #include "util.h"
#include "common/list.h" #include "common/list.h"
#include "files.h" #include "files.h"
...@@ -21,7 +23,7 @@ static char buf[512]; ...@@ -21,7 +23,7 @@ static char buf[512];
*/ */
#define NF_CONN_CMD "%s %s -t filter %s %s --protocol tcp " \ #define NF_CONN_CMD "%s %s -t filter %s %s --protocol tcp " \
"--source %s --sport %d --destination %s --dport %d -j DROP" "-m mark ! --mark " __stringify(SOCCR_MARK) " --source %s --sport %d --destination %s --dport %d -j DROP"
static char iptable_cmd_ipv4[] = "iptables"; static char iptable_cmd_ipv4[] = "iptables";
static char iptable_cmd_ipv6[] = "ip6tables"; static char iptable_cmd_ipv6[] = "ip6tables";
......
...@@ -117,13 +117,13 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk) ...@@ -117,13 +117,13 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
{ {
BUG_ON((sk->sd.family != AF_INET) && (sk->sd.family != AF_INET6)); BUG_ON((sk->sd.family != AF_INET) && (sk->sd.family != AF_INET6));
if (sk->shutdown) {
pr_err("Can't dump shutdown inet socket %x\n",
sk->sd.ino);
return 0;
}
if (sk->type == SOCK_DGRAM) { if (sk->type == SOCK_DGRAM) {
if (sk->shutdown) {
pr_err("Can't dump shutdown inet socket %x\n",
sk->sd.ino);
return 0;
}
if (sk->wqlen != 0) { if (sk->wqlen != 0) {
pr_err("Can't dump corked dgram socket %x\n", pr_err("Can't dump corked dgram socket %x\n",
sk->sd.ino); sk->sd.ino);
...@@ -165,6 +165,11 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk) ...@@ -165,6 +165,11 @@ static int can_dump_inet_sk(const struct inet_sk_desc *sk)
} }
break; break;
case TCP_ESTABLISHED: case TCP_ESTABLISHED:
case TCP_FIN_WAIT2:
case TCP_FIN_WAIT1:
case TCP_CLOSE_WAIT:
case TCP_LAST_ACK:
case TCP_CLOSING:
if (!opts.tcp_established_ok) { if (!opts.tcp_established_ok) {
pr_err("Connected TCP socket, consider using --%s option.\n", pr_err("Connected TCP socket, consider using --%s option.\n",
SK_EST_PARAM); SK_EST_PARAM);
...@@ -485,7 +490,7 @@ static struct file_desc_ops inet_desc_ops = { ...@@ -485,7 +490,7 @@ static struct file_desc_ops inet_desc_ops = {
static inline int tcp_connection(InetSkEntry *ie) static inline int tcp_connection(InetSkEntry *ie)
{ {
return (ie->proto == IPPROTO_TCP) && (ie->state == TCP_ESTABLISHED); return (ie->proto == IPPROTO_TCP && ie->dst_port);
} }
static int collect_one_inetsk(void *o, ProtobufCMessage *base, struct cr_img *i) static int collect_one_inetsk(void *o, ProtobufCMessage *base, struct cr_img *i)
...@@ -662,7 +667,7 @@ static int open_inet_sk(struct file_desc *d) ...@@ -662,7 +667,7 @@ static int open_inet_sk(struct file_desc *d)
mutex_unlock(&ii->port->reuseaddr_lock); mutex_unlock(&ii->port->reuseaddr_lock);
} }
if (ie->state == TCP_ESTABLISHED && if (ie->dst_port &&
inet_connect(sk, ii)) inet_connect(sk, ii))
goto err; goto err;
done: done:
......
...@@ -142,6 +142,7 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk) ...@@ -142,6 +142,7 @@ static int dump_tcp_conn_state(struct inet_sk_desc *sk)
tse.has_unsq_len = true; tse.has_unsq_len = true;
tse.mss_clamp = data.mss_clamp; tse.mss_clamp = data.mss_clamp;
tse.opt_mask = data.opt_mask; tse.opt_mask = data.opt_mask;
if (tse.opt_mask & TCPI_OPT_WSCALE) { if (tse.opt_mask & TCPI_OPT_WSCALE) {
tse.snd_wscale = data.snd_wscale; tse.snd_wscale = data.snd_wscale;
tse.rcv_wscale = data.rcv_wscale; tse.rcv_wscale = data.rcv_wscale;
...@@ -226,7 +227,7 @@ err_r: ...@@ -226,7 +227,7 @@ err_r:
int dump_one_tcp(int fd, struct inet_sk_desc *sk) int dump_one_tcp(int fd, struct inet_sk_desc *sk)
{ {
if (sk->state != TCP_ESTABLISHED) if (sk->dst_port == 0)
return 0; return 0;
pr_info("Dumping TCP connection\n"); pr_info("Dumping TCP connection\n");
...@@ -303,7 +304,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_ ...@@ -303,7 +304,7 @@ static int restore_tcp_conn_state(int sk, struct libsoccr_sk *socr, struct inet_
goto err_c; goto err_c;
} }
data.state = TCP_ESTABLISHED; data.state = ii->ie->state;;
data.inq_len = tse->inq_len; data.inq_len = tse->inq_len;
data.inq_seq = tse->inq_seq; data.inq_seq = tse->inq_seq;
data.outq_len = tse->outq_len; data.outq_len = tse->outq_len;
......
...@@ -645,7 +645,10 @@ int collect_sockets(struct ns_id *ns) ...@@ -645,7 +645,10 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_TCP; req.r.i.sdiag_protocol = IPPROTO_TCP;
req.r.i.idiag_ext = 0; req.r.i.idiag_ext = 0;
/* Only listening and established sockets supported yet */ /* Only listening and established sockets supported yet */
req.r.i.idiag_states = (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED); req.r.i.idiag_states = (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED) |
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING);
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, &req.r.i);
if (tmp) if (tmp)
err = tmp; err = tmp;
...@@ -673,7 +676,10 @@ int collect_sockets(struct ns_id *ns) ...@@ -673,7 +676,10 @@ int collect_sockets(struct ns_id *ns)
req.r.i.sdiag_protocol = IPPROTO_TCP; req.r.i.sdiag_protocol = IPPROTO_TCP;
req.r.i.idiag_ext = 0; req.r.i.idiag_ext = 0;
/* Only listening sockets supported yet */ /* Only listening sockets supported yet */
req.r.i.idiag_states = (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED); req.r.i.idiag_states = (1 << TCP_LISTEN) | (1 << TCP_ESTABLISHED) |
(1 << TCP_FIN_WAIT1) | (1 << TCP_FIN_WAIT2) |
(1 << TCP_CLOSE_WAIT) | (1 << TCP_LAST_ACK) |
(1 << TCP_CLOSING);
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, &req.r.i);
if (tmp) if (tmp)
err = tmp; err = tmp;
......
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