[CRIU] [PATCH 1/2 v2] kerndat: check the TCP_REPAIR_WINDOW option
Pavel Emelyanov
xemul at virtuozzo.com
Thu Jul 14 04:04:43 PDT 2016
On 07/14/2016 12:11 AM, Andrey Vagin wrote:
> From: Andrew Vagin <avagin at virtuozzo.com>
>
> 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.
This needs some kernel patches. What are these and what's their
state (in netdev@ / in net-next / in Linus' tree)?
> Signed-off-by: Andrew Vagin <avagin at virtuozzo.com>
> ---
> criu/Makefile.config | 2 +-
> criu/cr-check.c | 17 +++++++++++++++
> criu/include/kerndat.h | 3 +++
> criu/kerndat.c | 4 ++++
> criu/sk-tcp.c | 53 +++++++++++++++++++++++++++++++++++++++++++++++
> scripts/feature-tests.mak | 14 +++++++++++++
> 6 files changed, 92 insertions(+), 1 deletion(-)
>
> diff --git a/criu/Makefile.config b/criu/Makefile.config
> index 15af65f..a502dda 100644
> --- a/criu/Makefile.config
> +++ b/criu/Makefile.config
> @@ -15,7 +15,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
> diff --git a/criu/cr-check.c b/criu/cr-check.c
> index ca506a1..b639afb 100644
> --- a/criu/cr-check.c
> +++ b/criu/cr-check.c
> @@ -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();
> }
>
> /*
> diff --git a/criu/include/kerndat.h b/criu/include/kerndat.h
> index 0a5cd4b..860e32d 100644
> --- a/criu/include/kerndat.h
> +++ b/criu/include/kerndat.h
> @@ -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;
> @@ -57,4 +58,6 @@ enum {
> */
> extern int kerndat_fs_virtualized(unsigned int which, u32 kdev);
>
> +extern int kerndat_tcp_repair_window();
> +
> #endif /* __CR_KERNDAT_H__ */
> diff --git a/criu/kerndat.c b/criu/kerndat.c
> index 04a355b..3cb0a13 100644
> --- a/criu/kerndat.c
> +++ b/criu/kerndat.c
> @@ -485,6 +485,8 @@ int kerndat_init(void)
> ret = kerndat_iptables_has_xtlocks();
> if (!ret)
> ret = kerndat_compat_restore();
> + if (!ret)
> + ret = kerndat_tcp_repair_window();
>
> kerndat_lsm();
>
> @@ -516,6 +518,8 @@ int kerndat_init_rst(void)
> ret = kerndat_iptables_has_xtlocks();
> if (!ret)
> ret = kerndat_compat_restore();
> + if (!ret)
> + ret = kerndat_tcp_repair_window();
>
> kerndat_lsm();
>
> diff --git a/criu/sk-tcp.c b/criu/sk-tcp.c
> index 13d175a..37bf69c 100644
> --- a/criu/sk-tcp.c
> +++ b/criu/sk-tcp.c
> @@ -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;
> +}
> +
> diff --git a/scripts/feature-tests.mak b/scripts/feature-tests.mak
> index e009370..09bbdc8 100644
> --- a/scripts/feature-tests.mak
> +++ b/scripts/feature-tests.mak
> @@ -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>
>
>
More information about the CRIU
mailing list