From fbb8b82ea2cf0e9991915a8daa0357f5671d25a5 Mon Sep 17 00:00:00 2001 From: Pavel Tikhomirov Date: Wed, 8 Apr 2015 14:37:00 +0300 Subject: [PATCH] zdtm: netns check ipv4 device config preserve while c/r check it for default/lo, test values for config options are randomly generated and restricted by rand_limit changes: v2: make for all config options, avoid use of "system". v3: err->fail, run in own set of namespaces, add random, check not all options. v4: use all options because test is run in net-namespace, use ARRAY_SIZE macro v5: check fscanf and snprintf return values properly Signed-off-by: Pavel Tikhomirov Acked-by: Andrew Vagin Signed-off-by: Pavel Emelyanov --- test/zdtm.sh | 2 + test/zdtm/live/static/Makefile | 1 + test/zdtm/live/static/netns-dev.c | 208 ++++++++++++++++++++++++++++++ 3 files changed, 211 insertions(+) create mode 100644 test/zdtm/live/static/netns-dev.c diff --git a/test/zdtm.sh b/test/zdtm.sh index a1c4ae44e..88398804c 100755 --- a/test/zdtm.sh +++ b/test/zdtm.sh @@ -191,6 +191,7 @@ generate_test_list() transition/ipc static/netns-nf static/netns + ns/static/netns-dev static/cgroup00 static/cgroup01 static/cgroup02 @@ -324,6 +325,7 @@ mntns_shared_bind mntns_shared_bind02 mntns_root_bind mntns_rw_ro_rw +netns-dev sockets00 cow01 " diff --git a/test/zdtm/live/static/Makefile b/test/zdtm/live/static/Makefile index 976bd0aba..6f7e8f9d0 100644 --- a/test/zdtm/live/static/Makefile +++ b/test/zdtm/live/static/Makefile @@ -95,6 +95,7 @@ TST_NOFILE = \ poll \ mountpoints \ netns \ + netns-dev \ session01 \ session02 \ session03 \ diff --git a/test/zdtm/live/static/netns-dev.c b/test/zdtm/live/static/netns-dev.c new file mode 100644 index 000000000..d8d68fa2d --- /dev/null +++ b/test/zdtm/live/static/netns-dev.c @@ -0,0 +1,208 @@ +#include +#include +#include + +#include "zdtmtst.h" + +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) + +#define LO_CONF_DIR_PATH "/proc/sys/net/ipv4/conf/lo" +#define DEF_CONF_DIR_PATH "/proc/sys/net/ipv4/conf/default" + +char *devconfs[] = { + "accept_local", + "accept_redirects", + "accept_source_route", + "arp_accept", + "arp_announce", + "arp_filter", + "arp_ignore", + "arp_notify", + "bootp_relay", + "disable_policy", + "disable_xfrm", + "force_igmp_version", + "forwarding", + "igmpv2_unsolicited_report_interval", + "igmpv3_unsolicited_report_interval", + "log_martians", + "mc_forwarding", + "medium_id", + "promote_secondaries", + "proxy_arp", + "proxy_arp_pvlan", + "route_localnet", + "rp_filter", + "secure_redirects", + "send_redirects", + "shared_media", + "src_valid_mark", + "tag", + NULL, +}; + +int rand_limit[] = { + 2, /* accept_local */ + 2, /* accept_redirects */ + 2, /* accept_source_route */ + 2, /* arp_accept */ + 3, /* arp_announce */ + 2, /* arp_filter */ + 9, /* arp_ignore */ + 2, /* arp_notify */ + 2, /* bootp_relay */ + 2, /* disable_policy */ + 2, /* disable_xfrm */ + 0, /* force_igmp_version */ + 2, /* forwarding */ + 0, /* igmpv2_unsolicited_report_interval */ + 0, /* igmpv3_unsolicited_report_interval */ + 2, /* log_martians */ + 2, /* mc_forwarding */ + 0, /* medium_id */ + 2, /* promote_secondaries */ + 2, /* proxy_arp */ + 2, /* proxy_arp_pvlan */ + 2, /* route_localnet */ + 3, /* rp_filter */ + 2, /* secure_redirects */ + 2, /* send_redirects */ + 2, /* shared_media */ + 0, /* src_valid_mark */ + 0, /* tag */ +}; + +struct test_conf { + int ipv4_conf[ARRAY_SIZE(devconfs)]; + int ipv4_conf_rand[ARRAY_SIZE(devconfs)]; + char *dir; +} lo, def; + +static int save_and_set(int opt, FILE *fp, struct test_conf *tc) { + int ret; + int val; + + /* + * Save + */ + ret = fscanf(fp, "%d", &tc->ipv4_conf[opt]); + if (ret != 1) { + err("fscanf"); + return -1; + } + + /* + * Set random value + */ + val = (int)lrand48(); + + if (rand_limit[opt] != 0) + tc->ipv4_conf_rand[opt] = val % rand_limit[opt]; + else + tc->ipv4_conf_rand[opt] = val; + + ret = fprintf(fp, "%d", tc->ipv4_conf_rand[opt]); + if (ret < 0) { + err("fprintf"); + return -1; + } + + return 0; +} + +static int check_and_restore(int opt, FILE *fp, struct test_conf *tc) { + int ret; + int val; + + /* + * Check opt + */ + ret = fscanf(fp, "%d", &val); + if (ret != 1) { + err("fscanf"); + return -1; + } + + if (val != tc->ipv4_conf_rand[opt]) { + fail("Option \"%s/%s\" changed from %d to %d", + tc->dir, devconfs[opt], tc->ipv4_conf_rand[opt], val); + return -1; + } + + /* + * Restore opt + */ + ret = fprintf(fp, "%d", tc->ipv4_conf[opt]); + if (ret < 0) { + err("fprintf"); + return -1; + } + + return 0; +} + +static int for_each_option_do(int (*f)(int opt, FILE *fp, struct test_conf *tc), struct test_conf *tc) { + int ret; + int i; + + for (i = 0; devconfs[i]; i++) { + FILE *fp; + char path[PATH_MAX]; + + ret = snprintf(path, sizeof(path), "%s/%s", tc->dir, devconfs[i]); + if (ret < 0) { + err("snprintf"); + return -1; + } + + ret = access(path, W_OK); + if (ret < 0) + continue; + + fp = fopen(path, "r+"); + if (fp == NULL) { + err("fopen"); + return -1; + } + + ret = (*f)(i, fp, tc); + if (ret < 0) + return -1; + + fclose(fp); + } + + return 0; +} + +int main(int argc, char **argv) +{ + int ret; + + lo.dir = LO_CONF_DIR_PATH; + def.dir = DEF_CONF_DIR_PATH; + + test_init(argc, argv); + + ret = for_each_option_do(save_and_set, &lo); + if (ret < 0) + return -1; + + ret = for_each_option_do(save_and_set, &def); + if (ret < 0) + return -1; + + test_daemon(); + test_waitsig(); + + ret = for_each_option_do(check_and_restore, &lo); + if (ret < 0) + return -1; + + ret = for_each_option_do(check_and_restore, &def); + if (ret < 0) + return -1; + + pass(); + return 0; +}