diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h index 15f862235..015c3e0b7 100644 --- a/criu/include/kerndat.h +++ b/criu/include/kerndat.h @@ -34,6 +34,7 @@ struct kerndat_s { bool ipv6; bool has_loginuid; enum pagemap_func pmap; + unsigned int has_xtlocks; }; extern struct kerndat_s kdat; diff --git a/criu/kerndat.c b/criu/kerndat.c index 8127b6e26..5793de180 100644 --- a/criu/kerndat.c +++ b/criu/kerndat.c @@ -446,6 +446,17 @@ int kerndat_loginuid(bool only_dump) return 0; } +static int kerndat_iptables_has_xtlocks(void) +{ + char *argv[4] = { "sh", "-c", "iptables -w -L", NULL }; + + kdat.has_xtlocks = 1; + if (cr_system(-1, -1, -1, "sh", argv, CRS_CAN_FAIL) == -1) + kdat.has_xtlocks = 0; + + return 0; +} + int kerndat_init(void) { int ret; @@ -467,6 +478,8 @@ int kerndat_init(void) ret = get_ipv6(); if (!ret) ret = kerndat_loginuid(true); + if (!ret) + ret = kerndat_iptables_has_xtlocks(); kerndat_lsm(); @@ -494,6 +507,8 @@ int kerndat_init_rst(void) ret = get_ipv6(); if (!ret) ret = kerndat_loginuid(false); + if (!ret) + ret = kerndat_iptables_has_xtlocks(); kerndat_lsm(); diff --git a/criu/netfilter.c b/criu/netfilter.c index a105ed777..7a1ac9191 100644 --- a/criu/netfilter.c +++ b/criu/netfilter.c @@ -12,6 +12,7 @@ #include "netfilter.h" #include "sockets.h" #include "sk-inet.h" +#include "kerndat.h" static char buf[512]; @@ -20,7 +21,7 @@ static char buf[512]; * ANy brave soul to write it using xtables-devel? */ -static const char *nf_conn_cmd = "%s -w -t filter %s %s --protocol tcp " +static const char *nf_conn_cmd = "%s %s -t filter %s %s --protocol tcp " "--source %s --sport %d --destination %s --dport %d -j DROP"; static char iptable_cmd_ipv4[] = "iptables"; @@ -73,6 +74,7 @@ static int nf_connection_switch_raw(int family, u32 *src_addr, u16 src_port, } snprintf(buf, sizeof(buf), nf_conn_cmd, cmd, + kdat.has_xtlocks ? "-w" : "", lock ? "-A" : "-D", input ? "INPUT" : "OUTPUT", dip, (int)dst_port, sip, (int)src_port);