From 4a8c02d6368c5010b83cb3973ce349e7bec932cc Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Tue, 29 Nov 2022 15:42:51 +0300 Subject: [PATCH] zdtm: Add tests for IP_PKTINFO and IP_FREEBIND sock options Just creates ipv4/ipv6 raw/dgram sockets with IP_PKTINFO and IP_FREEBIND socket options enabled/disabled and checks that these options persist. Signed-off-by: Pavel Tikhomirov --- test/zdtm/static/Makefile | 3 + test/zdtm/static/sock_ip_opts00.c | 110 +++++++++++++++++++++++++++ test/zdtm/static/sock_ip_opts00.desc | 1 + test/zdtm/static/sock_ip_opts01.c | 1 + test/zdtm/static/sock_ip_opts01.desc | 1 + 5 files changed, 116 insertions(+) create mode 100644 test/zdtm/static/sock_ip_opts00.c create mode 100644 test/zdtm/static/sock_ip_opts00.desc create mode 120000 test/zdtm/static/sock_ip_opts01.c create mode 120000 test/zdtm/static/sock_ip_opts01.desc diff --git a/test/zdtm/static/Makefile b/test/zdtm/static/Makefile index 000488133..4b3d2e341 100644 --- a/test/zdtm/static/Makefile +++ b/test/zdtm/static/Makefile @@ -123,6 +123,8 @@ TST_NOFILE := \ sock_opts00 \ sock_opts01 \ sock_opts02 \ + sock_ip_opts00 \ + sock_ip_opts01 \ sk-unix-unconn \ sk-unix-unconn-seqpacket \ ipc_namespace \ @@ -598,6 +600,7 @@ socket-tcp6-closed: CFLAGS += -D ZDTM_IPV6 socket-tcp6-closed: CFLAGS += -D ZDTM_IPV4V6 socket-tcp-closed-last-ack: CFLAGS += -D ZDTM_TCP_LAST_ACK socket-tcp-skip-in-flight: CFLAGS += -D ZDTM_IPV4V6 +sock_ip_opts01: CFLAGS += -DZDTM_VAL_ZERO tun_ns: CFLAGS += -DTUN_NS mnt_ext_manual: CFLAGS += -D ZDTM_EXTMAP_MANUAL mntns_pivot_root_ro: CFLAGS += -DMNTNS_PIVOT_ROOT_RO diff --git a/test/zdtm/static/sock_ip_opts00.c b/test/zdtm/static/sock_ip_opts00.c new file mode 100644 index 000000000..08970c0da --- /dev/null +++ b/test/zdtm/static/sock_ip_opts00.c @@ -0,0 +1,110 @@ +#include +#include +#include + +#include +#include + +#include "zdtmtst.h" + +const char *test_doc = "Check that different ip socket options are restored"; +const char *test_author = "Pavel Tikhomirov "; + +#ifdef ZDTM_VAL_ZERO +#define IP_OPT_VAL 0 +#else +#define IP_OPT_VAL 1 +#endif + +struct sk_opt { + int level; + int opt; +}; + +struct sk_opt sk_opts_v4[] = { + { SOL_IP, IP_FREEBIND }, + { SOL_IP, IP_PKTINFO }, +}; + +#ifndef IPV6_FREEBIND +#define IPV6_FREEBIND 78 +#endif + +struct sk_opt sk_opts_v6[] = { + { SOL_IPV6, IPV6_FREEBIND }, + { SOL_IPV6, IPV6_RECVPKTINFO }, +}; + +struct sk_conf { + int domain; + int type; + int protocol; + int sk; +} sk_confs[] = { + { AF_INET, SOCK_DGRAM, IPPROTO_UDP }, + { AF_INET, SOCK_RAW, IPPROTO_UDP }, + { AF_INET6, SOCK_DGRAM, IPPROTO_UDP }, + { AF_INET6, SOCK_RAW, IPPROTO_UDP }, +}; + +int main(int argc, char **argv) +{ + struct sk_opt *opts; + int exit_code = 1; + int i, j, val; + socklen_t len; + int n_opts; + + test_init(argc, argv); + + for (i = 0; i < ARRAY_SIZE(sk_confs); i++) { + sk_confs[i].sk = socket(sk_confs[i].domain, sk_confs[i].type, sk_confs[i].protocol); + if (sk_confs[i].sk == -1) { + pr_perror("socket(%d,%d,%d) failed", sk_confs[i].domain, sk_confs[i].type, + sk_confs[i].protocol); + goto close; + } + } + + for (i = 0; i < ARRAY_SIZE(sk_confs); i++) { + opts = sk_confs[i].domain == AF_INET ? sk_opts_v4 : sk_opts_v6; + n_opts = sk_confs[i].domain == AF_INET ? ARRAY_SIZE(sk_opts_v4) : ARRAY_SIZE(sk_opts_v6); + + for (j = 0; j < n_opts; j++) { + val = IP_OPT_VAL; + if (setsockopt(sk_confs[i].sk, opts[j].level, opts[j].opt, &val, sizeof(int)) == -1) { + pr_perror("setsockopt(%d, %d) failed", opts[j].level, opts[j].opt); + goto close; + } + } + } + + test_daemon(); + test_waitsig(); + + for (i = 0; i < ARRAY_SIZE(sk_confs); i++) { + opts = sk_confs[i].domain == AF_INET ? sk_opts_v4 : sk_opts_v6; + n_opts = sk_confs[i].domain == AF_INET ? ARRAY_SIZE(sk_opts_v4) : ARRAY_SIZE(sk_opts_v6); + + for (j = 0; j < n_opts; j++) { + len = sizeof(int); + if (getsockopt(sk_confs[i].sk, opts[j].level, opts[j].opt, &val, &len) == -1) { + pr_perror("getsockopt(%d, %d) failed", opts[j].level, opts[j].opt); + goto close; + } + + if (val != IP_OPT_VAL) { + fail("Unexpected value socket(%d,%d,%d) opts(%d,%d)", sk_confs[i].domain, + sk_confs[i].type, sk_confs[i].protocol, opts[j].level, opts[j].opt); + goto close; + } + } + } + + pass(); + exit_code = 0; +close: + for (i = 0; i < ARRAY_SIZE(sk_confs); i++) + close(sk_confs[i].sk); + return exit_code; +} diff --git a/test/zdtm/static/sock_ip_opts00.desc b/test/zdtm/static/sock_ip_opts00.desc new file mode 100644 index 000000000..2201f0298 --- /dev/null +++ b/test/zdtm/static/sock_ip_opts00.desc @@ -0,0 +1 @@ +{'flags': 'suid', 'feature': 'ipv6_freebind'} diff --git a/test/zdtm/static/sock_ip_opts01.c b/test/zdtm/static/sock_ip_opts01.c new file mode 120000 index 000000000..15526f808 --- /dev/null +++ b/test/zdtm/static/sock_ip_opts01.c @@ -0,0 +1 @@ +sock_ip_opts00.c \ No newline at end of file diff --git a/test/zdtm/static/sock_ip_opts01.desc b/test/zdtm/static/sock_ip_opts01.desc new file mode 120000 index 000000000..e2c29ca25 --- /dev/null +++ b/test/zdtm/static/sock_ip_opts01.desc @@ -0,0 +1 @@ +sock_ip_opts00.desc \ No newline at end of file