The conntrack_dump_flush zone selftest assumes that the default conntrack zone is empty except for test connections. This assumption is incorrect on hosts with active traffic, such as ssh sessions, leading to spurious test failures.
Update the test to count only the connections created by the test itself, making it robust against existing host traffic. https://virtuozzo.atlassian.net/browse/VSTOR-120993 Signed-off-by: Aleksei Oladko <[email protected]> --- .../net/netfilter/conntrack_dump_flush.c | 276 ++++++++++++------ 1 file changed, 186 insertions(+), 90 deletions(-) diff --git a/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c index 5f827e10717d..93e11d7c8620 100644 --- a/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c +++ b/tools/testing/selftests/net/netfilter/conntrack_dump_flush.c @@ -15,6 +15,99 @@ #define TEST_ZONE_ID 123 #define NF_CT_DEFAULT_ZONE_ID 0 +struct test_suite { + uint32_t src4; + uint32_t dst4; + struct in6_addr src6; + struct in6_addr dst6; + uint16_t zone; +} suite[] = { + [0] = { + .src4 = 0xf0f0f0f0, + .dst4 = 0xf1f1f1f1, + .src6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x01000000 + } + }}, + .dst6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x02000000 + } + }}, + .zone = TEST_ZONE_ID, + }, + [1] = { + .src4 = 0xf2f2f2f2, + .dst4 = 0xf3f3f3f3, + .src6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x03000000 + } + }}, + .dst6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x04000000 + } + }}, + .zone = TEST_ZONE_ID + 1, + }, + [2] = { + .src4 = 0xf4f4f4f4, + .dst4 = 0xf5f5f5f5, + .src6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x05000000 + } + }}, + .dst6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x06000000 + } + }}, + .zone = TEST_ZONE_ID + 2, + }, + [3] = { + .src4 = 0xf6f6f6f6, + .dst4 = 0xf7f7f7f7, + .src6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x07000000 + } + }}, + .dst6 = (struct in6_addr) {{ + .__u6_addr32 = { + 0xb80d0120, + 0x00000000, + 0x00000000, + 0x08000000 + } + }}, + .zone = NF_CT_DEFAULT_ZONE_ID, + }, +}; + static int reply_counter; static int build_cta_tuple_v4(struct nlmsghdr *nlh, int type, @@ -210,9 +303,90 @@ static int conntrack_data_generate_v6(struct mnl_socket *sock, return conntrack_data_insert(sock, nlh, zone); } +static int parse_conntrack_cb(const struct nlattr *attr, void *data) +{ + const struct nlattr **tb = data; + int type = mnl_attr_get_type(attr); + + if (mnl_attr_type_valid(attr, CTA_MAX) < 0) + return MNL_CB_OK; + + tb[type] = (struct nlattr *)attr; + return MNL_CB_OK; +} + +static int parse_conntrack_ip_cb(const struct nlattr *attr, void *data) +{ + const struct nlattr **tb = data; + int type = mnl_attr_get_type(attr); + + if (mnl_attr_type_valid(attr, CTA_IP_MAX) < 0) + return MNL_CB_OK; + + tb[type] = (struct nlattr *)attr; + return MNL_CB_OK; +} + static int count_entries(const struct nlmsghdr *nlh, void *data) { - reply_counter++; + struct nfgenmsg *nfg; + struct nlattr *tb[CTA_MAX +1] = {}; + struct nlattr *tb_tuple[CTA_MAX + 1] = {}; + struct nlattr *tb_ip[CTA_IP_MAX + 1] = {}; + struct nlattr *tuple, *ip; + int family; + + nfg = mnl_nlmsg_get_payload(nlh); + family = nfg->nfgen_family; + mnl_attr_parse(nlh, sizeof(*nfg), parse_conntrack_cb, tb); + + tuple = tb[CTA_TUPLE_ORIG]; + if (!tuple) + return MNL_CB_OK; + + mnl_attr_parse_nested(tuple, parse_conntrack_cb, tb_tuple); + + ip = tb_tuple[CTA_TUPLE_IP]; + if (!ip) + return MNL_CB_OK; + + mnl_attr_parse_nested(ip, parse_conntrack_ip_cb, tb_ip); + + if (family == AF_INET) { + uint32_t src, dst; + int i; + + if (!tb_ip[CTA_IP_V4_SRC] || !tb_ip[CTA_IP_V4_DST]) + return MNL_CB_OK; + + src = mnl_attr_get_u32(tb_ip[CTA_IP_V4_SRC]); + dst = mnl_attr_get_u32(tb_ip[CTA_IP_V4_DST]); + + for (i = 0; i < sizeof(suite) / sizeof(suite[0]); i++) { + if (src == suite[i].src4 && dst == suite[i].dst4) { + reply_counter++; + return MNL_CB_OK; + } + } + } else if (family == AF_INET6) { + struct in6_addr src6, dst6; + int i; + + if (!tb_ip[CTA_IP_V6_SRC] || !tb_ip[CTA_IP_V6_DST]) + return MNL_CB_OK; + + memcpy(&src6, mnl_attr_get_payload(tb_ip[CTA_IP_V6_SRC]), sizeof(src6)); + memcpy(&dst6, mnl_attr_get_payload(tb_ip[CTA_IP_V6_DST]), sizeof(dst6)); + + for (i = 0; i < sizeof(suite) / sizeof(suite[0]); i++) { + if (!memcmp(&src6, &suite[i].src6, sizeof(src6)) && + !memcmp(&dst6, &suite[i].dst6, sizeof(dst6))) { + reply_counter++; + return MNL_CB_OK; + } + } + } + return MNL_CB_OK; } @@ -316,6 +490,7 @@ FIXTURE_SETUP(conntrack_dump_flush) { struct in6_addr src, dst; int ret; + int i; self->sock = mnl_socket_open(NETLINK_NETFILTER); if (!self->sock) { @@ -332,96 +507,17 @@ FIXTURE_SETUP(conntrack_dump_flush) else if (ret < 0 && errno == EOPNOTSUPP) SKIP(return, "Kernel does not seem to support conntrack zones"); - ret = conntrack_data_generate_v4(self->sock, 0xf0f0f0f0, 0xf1f1f1f1, - TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf2f2f2f2, 0xf3f3f3f3, - TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf4f4f4f4, 0xf5f5f5f5, - TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 0); - ret = conntrack_data_generate_v4(self->sock, 0xf6f6f6f6, 0xf7f7f7f7, - NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); - - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x01000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x02000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID); - EXPECT_EQ(ret, 0); - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x03000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x04000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID + 1); - EXPECT_EQ(ret, 0); - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x05000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x06000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - TEST_ZONE_ID + 2); - EXPECT_EQ(ret, 0); + for (i = 0; i < sizeof(suite) / sizeof(suite[0]); i++) { + ret = conntrack_data_generate_v4(self->sock, suite[i].src4, + suite[i].dst4, suite[i].zone); + EXPECT_EQ(ret, 0); + } - src = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x07000000 - } - }}; - dst = (struct in6_addr) {{ - .__u6_addr32 = { - 0xb80d0120, - 0x00000000, - 0x00000000, - 0x08000000 - } - }}; - ret = conntrack_data_generate_v6(self->sock, src, dst, - NF_CT_DEFAULT_ZONE_ID); - EXPECT_EQ(ret, 0); + for (i = 0; i < sizeof(suite) / sizeof(suite[0]); i++) { + ret = conntrack_data_generate_v6(self->sock, suite[i].src6, + suite[i].dst6, suite[i].zone); + EXPECT_EQ(ret, 0); + } ret = conntracK_count_zone(self->sock, TEST_ZONE_ID); EXPECT_GE(ret, 2); -- 2.43.0 _______________________________________________ Devel mailing list [email protected] https://lists.openvz.org/mailman/listinfo/devel
