mirror of
https://github.com/checkpoint-restore/criu.git
synced 2026-07-17 16:47:50 +00:00
kerndat: check the TCP_REPAIR_WINDOW option
It's a new option to get/set window parameters.
v2: don't do this check to unprivileged users, because TCP_REPAIR
is protected by CAP_NET_ADMIN.
Signed-off-by: Andrew Vagin <avagin@virtuozzo.com>
Signed-off-by: Pavel Emelyanov <xemul@virtuozzo.com>
This commit is contained in:
parent
488fc072a5
commit
f3b730d0e2
6 changed files with 92 additions and 1 deletions
|
|
@ -13,7 +13,7 @@ ifeq ($(call pkg-config-check,libselinux),y)
|
|||
endif
|
||||
|
||||
FEATURES_LIST := TCP_REPAIR STRLCPY STRLCAT PTRACE_PEEKSIGINFO \
|
||||
SETPROCTITLE_INIT MEMFD
|
||||
SETPROCTITLE_INIT MEMFD TCP_REPAIR_WINDOW
|
||||
|
||||
# $1 - config name
|
||||
define gen-feature-test
|
||||
|
|
|
|||
|
|
@ -917,6 +917,22 @@ static int check_cgroupns(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int check_tcp_window(void)
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret = kerndat_tcp_repair_window();
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
|
||||
if (!kdat.has_tcp_window) {
|
||||
pr_err("The TCP_REPAIR_WINDOW option isn't supported.\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int (*chk_feature)(void);
|
||||
|
||||
/*
|
||||
|
|
@ -1014,6 +1030,7 @@ int cr_check(void)
|
|||
ret |= check_fdinfo_lock();
|
||||
ret |= check_clone_parent_vs_pid();
|
||||
ret |= check_cgroupns();
|
||||
ret |= check_tcp_window();
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
|
|||
|
|
@ -31,6 +31,7 @@ struct kerndat_s {
|
|||
bool has_dirty_track;
|
||||
bool has_memfd;
|
||||
bool has_fdinfo_lock;
|
||||
bool has_tcp_window;
|
||||
unsigned long task_size;
|
||||
bool ipv6;
|
||||
bool has_loginuid;
|
||||
|
|
@ -56,4 +57,6 @@ enum {
|
|||
*/
|
||||
extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
|
||||
|
||||
extern int kerndat_tcp_repair_window();
|
||||
|
||||
#endif /* __CR_KERNDAT_H__ */
|
||||
|
|
|
|||
|
|
@ -472,6 +472,8 @@ int kerndat_init(void)
|
|||
ret = kerndat_loginuid(true);
|
||||
if (!ret)
|
||||
ret = kerndat_iptables_has_xtlocks();
|
||||
if (!ret)
|
||||
ret = kerndat_tcp_repair_window();
|
||||
|
||||
kerndat_lsm();
|
||||
|
||||
|
|
@ -501,6 +503,8 @@ int kerndat_init_rst(void)
|
|||
ret = kerndat_loginuid(false);
|
||||
if (!ret)
|
||||
ret = kerndat_iptables_has_xtlocks();
|
||||
if (!ret)
|
||||
ret = kerndat_tcp_repair_window();
|
||||
|
||||
kerndat_lsm();
|
||||
|
||||
|
|
|
|||
|
|
@ -33,6 +33,17 @@
|
|||
#define SIOCOUTQNSD 0x894B
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_HAS_TCP_REPAIR_WINDOW
|
||||
struct tcp_repair_window {
|
||||
u32 snd_wl1;
|
||||
u32 snd_wnd;
|
||||
u32 max_window;
|
||||
|
||||
u32 rcv_wnd;
|
||||
u32 rcv_wup;
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef CONFIG_HAS_TCP_REPAIR
|
||||
/*
|
||||
* It's been reported that both tcp_repair_opt
|
||||
|
|
@ -58,6 +69,10 @@ enum {
|
|||
#define TCP_TIMESTAMP 24
|
||||
#endif
|
||||
|
||||
#ifndef TCP_REPAIR_WINDOW
|
||||
#define TCP_REPAIR_WINDOW 29
|
||||
#endif
|
||||
|
||||
#ifndef TCPOPT_SACK_PERM
|
||||
#define TCPOPT_SACK_PERM TCPOPT_SACK_PERMITTED
|
||||
#endif
|
||||
|
|
@ -751,3 +766,41 @@ out:
|
|||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int kerndat_tcp_repair_window()
|
||||
{
|
||||
struct tcp_repair_window opt;
|
||||
socklen_t optlen = sizeof(opt);
|
||||
int sk, val = 1;
|
||||
|
||||
sk = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (sk < 0) {
|
||||
pr_perror("Unable to create a netlink socket");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (setsockopt(sk, SOL_TCP, TCP_REPAIR, &val, sizeof(val))) {
|
||||
if (errno == EPERM) {
|
||||
kdat.has_tcp_window = false;
|
||||
pr_warn("TCP_REPAIR isn't available to unprivileged users\n");
|
||||
return 0;
|
||||
}
|
||||
pr_perror("Unable to set TCP_REPAIR");
|
||||
close(sk);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (getsockopt(sk, SOL_TCP, TCP_REPAIR_WINDOW, &opt, &optlen)) {
|
||||
if (errno != ENOPROTOOPT) {
|
||||
pr_perror("Unable to set TCP_REPAIR_WINDOW");
|
||||
close(sk);
|
||||
return -1;
|
||||
}
|
||||
kdat.has_tcp_window = false;
|
||||
} else
|
||||
kdat.has_tcp_window = true;
|
||||
close(sk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,6 +12,20 @@ int main(void)
|
|||
}
|
||||
endef
|
||||
|
||||
define FEATURE_TEST_TCP_REPAIR_WINDOW
|
||||
|
||||
#include <netinet/tcp.h>
|
||||
|
||||
int main(void)
|
||||
{
|
||||
struct tcp_repair_window opts;
|
||||
|
||||
opts.snd_wl1 = 0;
|
||||
|
||||
return opts.snd_wl1;
|
||||
}
|
||||
endef
|
||||
|
||||
define FEATURE_TEST_LIBBSD_DEV
|
||||
#include <bsd/string.h>
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue