static bool test_next_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_hop; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_HOP); hdr_hop = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, NEXTHDR_ROUTING); hdr_route = add_route_hdr(hdr_hop, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(hdr_frag, iterator.data, "Frag:data"); success &= ASSERT_UINT(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 1"); success &= ASSERT_PTR(hdr_hop, iterator.data, "Hop:data"); success &= ASSERT_UINT(NEXTHDR_HOP, iterator.hdr_type, "Hop:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 2"); success &= ASSERT_PTR(hdr_route, iterator.data, "Routing:data"); success &= ASSERT_UINT(NEXTHDR_ROUTING, iterator.hdr_type, "Routing:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 3"); success &= ASSERT_PTR(payload, iterator.data, "Payload1:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Next 4"); success &= ASSERT_PTR(payload, iterator.data, "Payload2:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload2:type"); /* Fall through. */ end: kfree(hdr6); return success; }
static bool test_foreach_sample(void) { struct pool4_sample expected[COUNT]; unsigned int i = 0; struct foreach_sample_args args; int error; bool success = true; if (!add_common_samples()) return false; init_sample(&expected[i++], 0xc0000200U, 6, 7); init_sample(&expected[i++], 0xc0000201U, 6, 7); init_sample(&expected[i++], 0xc0000210U, 15, 19); init_sample(&expected[i++], 0xc0000210U, 22, 23); init_sample(&expected[i++], 0xc0000211U, 19, 19); init_sample(&expected[i++], 0xc0000220U, 1, 1); init_sample(&expected[i++], 0xc0000221U, 1, 1); init_sample(&expected[i++], 0xc0000222U, 1, 1); init_sample(&expected[i++], 0xc0000223U, 1, 1); if (i != COUNT) { log_err("Input mismatch. Unit test is broken: %u %u", i, COUNT); return false; } args.expected = &expected[0]; args.expected_len = COUNT; args.samples = 0; args.taddrs = 0; error = pool4db_foreach_sample(pool, L4PROTO_TCP, validate_sample, &args, NULL); success &= ASSERT_INT(0, error, "no-offset call"); success &= ASSERT_UINT(9, args.samples, "no-offset samples"); success &= ASSERT_UINT(16, args.taddrs, "no-offset taddrs"); for (i = 0; i < COUNT; i++) { /* foreach sample skips offset. */ args.expected = &expected[i + 1]; args.expected_len = COUNT - i - 1; args.samples = 0; args.taddrs = 0; error = pool4db_foreach_sample(pool, L4PROTO_TCP, validate_sample, &args, &expected[i]); success &= ASSERT_INT(0, error, "call %u", i); /* log_debug("--------------"); */ } return success; }
static bool test_last_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_esp; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_ESP); hdr_esp = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, FRAG_HDR_LEN); hdr_route = add_route_hdr(hdr_esp, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); hdr_iterator_last(&iterator); success &= ASSERT_PTR(hdr_esp, iterator.data, "Last:data"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "Last:type"); /* End */ kfree(hdr6); return success; }
static bool test_next_unsupported(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; struct frag_hdr *hdr_frag; struct ipv6_opt_hdr *hdr_esp; struct ipv6_opt_hdr *hdr_route; unsigned char *payload; hdr6 = kmalloc_packet(FRAG_HDR_LEN + OPT_HDR_LEN + ROUTE_HDR_LEN + 4, NEXTHDR_FRAGMENT); if (!hdr6) return false; hdr_frag = add_frag_hdr(hdr6, HDR6_LEN, NEXTHDR_ESP); hdr_esp = add_opt_hdr(hdr_frag, FRAG_HDR_LEN, FRAG_HDR_LEN); hdr_route = add_route_hdr(hdr_esp, OPT_HDR_LEN, NEXTHDR_UDP); payload = add_payload(hdr_route, ROUTE_HDR_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(hdr_frag, iterator.data, "Frag:pointer"); success &= ASSERT_UINT(NEXTHDR_FRAGMENT, iterator.hdr_type, "Frag:type"); if (!success) goto end; success &= ASSERT_INT(EAGAIN, hdr_iterator_next(&iterator), "Next 1"); success &= ASSERT_PTR(hdr_esp, iterator.data, "ESP1:pointer"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "ESP1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Next 2"); success &= ASSERT_PTR(hdr_esp, iterator.data, "ESP2:pointer"); success &= ASSERT_UINT(NEXTHDR_ESP, iterator.hdr_type, "ESP2:type"); /* Fall through. */ end: kfree(hdr6); return success; }
static bool __foreach(struct pool4_sample *expected, unsigned int expected_len, unsigned int expected_taddrs) { struct foreach_sample_args args; int error; bool success = true; args.expected = expected; args.expected_len = expected_len; args.samples = 0; args.taddrs = 0; error = pool4db_foreach_sample(pool, L4PROTO_TCP, validate_sample, &args, NULL); success &= ASSERT_INT(0, error, "foreach result"); success &= ASSERT_UINT(expected_len, args.samples, "foreach count"); success &= ASSERT_UINT(expected_taddrs, args.taddrs, "foreach taddrs"); return success; }
static bool test_next_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; unsigned char *payload; hdr6 = kmalloc_packet(4, NEXTHDR_UDP); if (!hdr6) return false; payload = add_payload(hdr6, HDR6_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); success &= ASSERT_PTR(payload, iterator.data, "Payload1:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload1:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result1"); success &= ASSERT_PTR(payload, iterator.data, "Payload2:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload2:type"); if (!success) goto end; success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result2"); success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result3"); success &= ASSERT_INT(0, hdr_iterator_next(&iterator), "Result4"); success &= ASSERT_PTR(payload, iterator.data, "Payload3:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Payload3:type"); /* Fall through. */ end: kfree(hdr6); return success; }
static int validate_sample(struct pool4_sample *sample, void *void_args) { struct foreach_sample_args *args = void_args; bool success = true; /* log_debug(" foreaching %pI4 %u-%u", &sample->range.addr, sample->range.ports.min, sample->range.ports.max); */ success &= ASSERT_BOOL(true, args->samples < args->expected_len, "overflow (%u %u)", args->samples, args->expected_len); if (!success) return -EINVAL; success &= __ASSERT_ADDR4(&args->expected[args->samples].range.addr, &sample->range.addr, "addr"); success &= ASSERT_UINT(args->expected[args->samples].range.ports.min, sample->range.ports.min, "min"); success &= ASSERT_UINT(args->expected[args->samples].range.ports.max, sample->range.ports.max, "max"); args->samples++; args->taddrs += port_range_count(&sample->range.ports); return success ? 0 : -EINVAL; }
static bool assert_bib_exists(char *addr6, u16 port6, char *addr4, u16 port4, l4_protocol proto, unsigned int session_count) { struct bib_entry bib; struct ipv6_transport_addr tuple_addr; bool success = true; if (str_to_addr6(addr6, &tuple_addr.l3)) return false; tuple_addr.l4 = port6; success &= ASSERT_INT(0, bib_find6(jool.nat64.bib, proto, &tuple_addr, &bib), "BIB exists"); if (!success) return false; success &= ASSERT_ADDR6(addr6, &bib.ipv6.l3, "IPv6 address"); success &= ASSERT_UINT(port6, bib.ipv6.l4, "IPv6 port"); success &= ASSERT_ADDR4(addr4, &bib.ipv4.l3, "IPv4 address"); /* The IPv4 port is unpredictable. */ success &= ASSERT_BOOL(proto, bib.l4_proto, "BIB proto"); return success; }
static bool test_last_no_subheaders(void) { bool success = true; struct hdr_iterator iterator; /* Init */ struct ipv6hdr *hdr6; unsigned char *payload; hdr6 = kmalloc_packet(4, NEXTHDR_UDP); if (!hdr6) return false; payload = add_payload(hdr6, HDR6_LEN); /* Test */ hdr_iterator_init(&iterator, hdr6); hdr_iterator_last(&iterator); success &= ASSERT_PTR(payload, iterator.data, "Last:data"); success &= ASSERT_UINT(NEXTHDR_UDP, iterator.hdr_type, "Last:type"); /* End */ kfree(hdr6); return success; }
static bool test_foreach(void) { struct unit_iteration_args args; struct session_foreach_func func = { .cb = cb, .arg = &args, }; struct session_foreach_offset offset; int error; bool success = true; offset.offset.src.l3.s_addr = cpu_to_be32(0xcb007102u);/* 203.0.113.2 */ offset.offset.src.l4 = 200; offset.offset.dst.l3.s_addr = cpu_to_be32(0xc0000202u);/* 192.0.2.2 */ offset.offset.dst.l4 = 1200; /* Empty table, no offset. */ args.i = 0; args.offset = 0; error = bib_foreach_session(db, L4PROTO_UDP, &func, NULL); success &= ASSERT_INT(0, error, "call 1 result"); success &= ASSERT_UINT(0, args.i, "call 1 counter"); /* Empty table, offset, include offset, offset not found. */ args.i = 0; args.offset = 0; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 2 result"); success &= ASSERT_UINT(0, args.i, "call 2 counter"); /* Empty table, offset, do not include offset, offset not found. */ args.i = 0; args.offset = 0; offset.include_offset = false; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 3 result"); success &= ASSERT_UINT(0, args.i, "call 3 counter"); /* ----------------------------------- */ if (!insert_test_sessions()) return false; /* Populated table, no offset. */ args.i = 0; args.offset = 0; error = bib_foreach_session(db, L4PROTO_UDP, &func, NULL); success &= ASSERT_INT(0, error, "call 4 result"); success &= ASSERT_UINT(9, args.i, "call 4 counter"); /* Populated table, offset, include offset, offset found. */ args.i = 0; args.offset = 4; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 5 result"); success &= ASSERT_UINT(5, args.i, "call 5 counter"); /* Populated table, offset, include offset, offset not found. */ args.i = 0; args.offset = 5; offset.include_offset = true; offset.offset.dst.l4 = 1250; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 6 result"); success &= ASSERT_UINT(4, args.i, "call 6 counter"); /* Populated table, offset, do not include offset, offset found. */ args.i = 0; args.offset = 5; offset.include_offset = false; offset.offset.dst.l4 = 1200; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 7 result"); success &= ASSERT_UINT(4, args.i, "call 7 counter"); /* Populated table, offset, do not include offset, offset not found. */ args.i = 0; args.offset = 5; offset.include_offset = false; offset.offset.dst.l4 = 1250; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 8 result"); success &= ASSERT_UINT(4, args.i, "call 8 counter"); /* ----------------------------------- */ /* Offset is before first, include offset. */ offset.offset.src.l3.s_addr = cpu_to_be32(0xcb007101u);/* 203.0.113.1 */ offset.offset.src.l4 = 300; offset.offset.dst.l3.s_addr = cpu_to_be32(0xc0000203u);/* 192.0.2.3 */ offset.offset.dst.l4 = 1200; args.i = 0; args.offset = 0; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 9 result"); success &= ASSERT_UINT(9, args.i, "call 9 counter"); /* Offset is before first, do not include offset. */ args.i = 0; offset.include_offset = false; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 10 result"); success &= ASSERT_UINT(9, args.i, "call 10 counter"); /* Offset is first, include offset. */ offset.offset.dst.l4 = 1300; args.i = 0; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 11 result"); success &= ASSERT_UINT(9, args.i, "call 11 counter"); /* Offset is first, do not include offset. */ args.i = 0; args.offset = 1; offset.include_offset = false; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 12 result"); success &= ASSERT_UINT(8, args.i, "call 12 counter"); /* Offset is last, include offset. */ offset.offset.src.l3.s_addr = cpu_to_be32(0xcb007103u); /* 203.0.113.3 */ offset.offset.src.l4 = 100; offset.offset.dst.l3.s_addr = cpu_to_be32(0xc0000201u); /* 192.0.2.1 */ offset.offset.dst.l4 = 1100; args.i = 0; args.offset = 8; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 13 result"); success &= ASSERT_UINT(1, args.i, "call 13 counter"); /* Offset is last, do not include offset. */ args.i = 0; offset.include_offset = false; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 14 result"); success &= ASSERT_UINT(0, args.i, "call 14 counter"); /* Offset is after last, include offset. */ offset.offset.src.l4 = 1200; args.i = 0; offset.include_offset = true; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 15 result"); success &= ASSERT_UINT(0, args.i, "call 15 counter"); /* Offset is after last, do not include offset. */ args.i = 0; offset.include_offset = false; error = bib_foreach_session(db, L4PROTO_UDP, &func, &offset); success &= ASSERT_INT(0, error, "call 16 result"); success &= ASSERT_UINT(0, args.i, "call 16 counter"); return success; }
static bool test_foreach(void) { struct ipv4_transport_addr local; struct ipv4_transport_addr remote; struct unit_iteration_args args; int error; bool success = true; local.l3.s_addr = cpu_to_be32(0xcb007102u); /* 203.0.113.2 */ local.l4 = 200; remote.l3.s_addr = cpu_to_be32(0xc0000202u); /* 192.0.2.2 */ remote.l4 = 1200; /* Empty table, no offset. */ args.i = 0; args.offset = 0; error = __foreach(&table, cb, &args, NULL, NULL, 0); success &= ASSERT_INT(0, error, "call 1 result"); success &= ASSERT_UINT(0, args.i, "call 1 counter"); /* Empty table, offset, include offset, offset not found. */ args.i = 0; args.offset = 0; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 2 result"); success &= ASSERT_UINT(0, args.i, "call 2 counter"); /* Empty table, offset, do not include offset, offset not found. */ args.i = 0; args.offset = 0; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 3 result"); success &= ASSERT_UINT(0, args.i, "call 3 counter"); /* ----------------------------------- */ if (!insert_test_sessions()) return false; /* Populated table, no offset. */ args.i = 0; args.offset = 0; error = __foreach(&table, cb, &args, NULL, NULL, 0); success &= ASSERT_INT(0, error, "call 4 result"); success &= ASSERT_UINT(9, args.i, "call 4 counter"); /* Populated table, offset, include offset, offset found. */ args.i = 0; args.offset = 4; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 5 result"); success &= ASSERT_UINT(5, args.i, "call 5 counter"); /* Populated table, offset, include offset, offset not found. */ args.i = 0; args.offset = 5; remote.l4 = 1250; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 6 result"); success &= ASSERT_UINT(4, args.i, "call 6 counter"); /* Populated table, offset, do not include offset, offset found. */ args.i = 0; args.offset = 5; remote.l4 = 1200; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 7 result"); success &= ASSERT_UINT(4, args.i, "call 7 counter"); /* Populated table, offset, do not include offset, offset not found. */ args.i = 0; args.offset = 5; remote.l4 = 1250; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 8 result"); success &= ASSERT_UINT(4, args.i, "call 8 counter"); /* ----------------------------------- */ /* Offset is before first, include offset. */ local.l3.s_addr = cpu_to_be32(0xcb007101u); /* 203.0.113.1 */ local.l4 = 300; remote.l3.s_addr = cpu_to_be32(0xc0000203u); /* 192.0.2.3 */ remote.l4 = 1200; args.i = 0; args.offset = 0; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 9 result"); success &= ASSERT_UINT(9, args.i, "call 9 counter"); /* Offset is before first, do not include offset. */ args.i = 0; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 10 result"); success &= ASSERT_UINT(9, args.i, "call 10 counter"); /* Offset is first, include offset. */ remote.l4 = 1300; args.i = 0; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 11 result"); success &= ASSERT_UINT(9, args.i, "call 11 counter"); /* Offset is first, do not include offset. */ args.i = 0; args.offset = 1; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 12 result"); success &= ASSERT_UINT(8, args.i, "call 12 counter"); /* Offset is last, include offset. */ local.l3.s_addr = cpu_to_be32(0xcb007103u); /* 203.0.113.3 */ local.l4 = 100; remote.l3.s_addr = cpu_to_be32(0xc0000201u); /* 192.0.2.1 */ remote.l4 = 1100; args.i = 0; args.offset = 8; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 13 result"); success &= ASSERT_UINT(1, args.i, "call 13 counter"); /* Offset is last, do not include offset. */ args.i = 0; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 14 result"); success &= ASSERT_UINT(0, args.i, "call 14 counter"); /* Offset is after last, include offset. */ remote.l4 = 1200; args.i = 0; error = __foreach(&table, cb, &args, &remote, &local, true); success &= ASSERT_INT(0, error, "call 15 result"); success &= ASSERT_UINT(0, args.i, "call 15 counter"); /* Offset is after last, do not include offset. */ args.i = 0; error = __foreach(&table, cb, &args, &remote, &local, false); success &= ASSERT_INT(0, error, "call 16 result"); success &= ASSERT_UINT(0, args.i, "call 16 counter"); return success; }
static bool compare_global_configs(struct global_config *expected, struct global_config *actual) { bool success = true; __u16 i; success &= ASSERT_UINT(expected->is_disable, actual->is_disable, "is_disable"); success &= ASSERT_UINT(expected->reset_traffic_class, actual->reset_traffic_class, "reset_traffic_class"); success &= ASSERT_UINT(expected->reset_tos, actual->reset_tos, "reset_tos"); success &= ASSERT_UINT(expected->new_tos, actual->new_tos, "new_tos"); success &= ASSERT_UINT(expected->atomic_frags.df_always_on, actual->atomic_frags.df_always_on, "df_always_on"); success &= ASSERT_UINT(expected->atomic_frags.build_ipv6_fh, actual->atomic_frags.build_ipv6_fh, "build_ipv6_fh"); success &= ASSERT_UINT(expected->atomic_frags.build_ipv4_id, actual->atomic_frags.build_ipv4_id, "build_ipv4_id"); success &= ASSERT_UINT(expected->atomic_frags.lower_mtu_fail, actual->atomic_frags.lower_mtu_fail, "lower_mtu_fail"); success &= ASSERT_UINT(expected->mtu_plateau_count, actual->mtu_plateau_count, "mtu_plateau_count"); if (success) { for (i = 0; i < expected->mtu_plateau_count; i++) { success &= ASSERT_UINT(expected->mtu_plateaus[i], actual->mtu_plateaus[i], "mtu_plateaus"); } } success &= ASSERT_U64(expected->nat64.ttl.udp, actual->nat64.ttl.udp, "ttl.udp"); success &= ASSERT_U64(expected->nat64.ttl.icmp, actual->nat64.ttl.icmp, "ttl.icmp"); success &= ASSERT_U64(expected->nat64.ttl.tcp_est, actual->nat64.ttl.tcp_est, "ttl.tcp_est"); success &= ASSERT_U64(expected->nat64.ttl.tcp_trans, actual->nat64.ttl.tcp_trans, "ttl.tcp_trans"); success &= ASSERT_U64(expected->nat64.ttl.frag, actual->nat64.ttl.frag, "ttl.frag"); success &= ASSERT_UINT(expected->nat64.drop_by_addr, actual->nat64.drop_by_addr, "drop_by_addr equals"); success &= ASSERT_UINT(expected->nat64.drop_external_tcp, actual->nat64.drop_external_tcp, "drop_external_tcp equals"); success &= ASSERT_UINT(expected->nat64.drop_icmp6_info, actual->nat64.drop_icmp6_info, "drop_icmp6_info equals"); success &= ASSERT_U64(expected->nat64.max_stored_pkts, actual->nat64.max_stored_pkts, "max_pkts equals test"); return success; }
static bool test_function_icmp6_minimum_mtu(void) { struct xlation state = { .jool.global = config }; int i; bool success = true; /* * I'm assuming the default plateaus list has 3 elements or more. * (so I don't have to reallocate mtu_plateaus) */ config->cfg.mtu_plateaus[0] = 5000; config->cfg.mtu_plateaus[1] = 4000; config->cfg.mtu_plateaus[2] = 500; config->cfg.mtu_plateau_count = 2; /* Simple tests */ success &= ASSERT_UINT(1320, min_mtu(1300, 3000, 3000, 2000), "min(1300, 3000, 3000)"); success &= ASSERT_UINT(1321, min_mtu(3001, 1301, 3001, 2001), "min(3001, 1301, 3001)"); success &= ASSERT_UINT(1302, min_mtu(3002, 3002, 1302, 2002), "min(3002, 3002, 1302)"); if (!success) return false; /* Lowest MTU is illegal on IPv6. */ success &= ASSERT_UINT(1280, min_mtu(100, 200, 200, 150), "min(100, 200, 200)"); success &= ASSERT_UINT(1280, min_mtu(200, 100, 200, 150), "min(200, 100, 200)"); success &= ASSERT_UINT(1280, min_mtu(200, 200, 100, 150), "min(200, 200, 100)"); /* Test plateaus (pkt is min). */ for (i = 5500; i > 5000 && success; --i) success &= ASSERT_UINT(5020, min_mtu(0, 6000, 6000, i), "min(%d, 6000, 6000)", i); for (i = 5000; i > 4000 && success; --i) success &= ASSERT_UINT(4020, min_mtu(0, 6000, 6000, i), "min(%d, 6000, 6000)", i); for (i = 4000; i >= 0 && success; --i) success &= ASSERT_UINT(1280, min_mtu(0, 6000, 6000, i), "min(%d, 6000, 6000)", i); /* Test plateaus (in/out is min). */ success &= ASSERT_UINT(1420, min_mtu(0, 1400, 5500, 4500), "min(4000,1400,5500)"); success &= ASSERT_UINT(1400, min_mtu(0, 5500, 1400, 4500), "min(4000,5500,1400)"); /* Plateaus and illegal MTU at the same time. */ success &= ASSERT_UINT(1280, min_mtu(0, 700, 700, 1000), "min(500, 700, 700)"); success &= ASSERT_UINT(1280, min_mtu(0, 1, 700, 1000), "min(500, 1, 700)"); success &= ASSERT_UINT(1280, min_mtu(0, 700, 1, 1000), "min(500, 700, 1)"); return success; } #undef min_mtu static bool test_function_icmp4_to_icmp6_param_prob(void) { struct icmphdr hdr4; struct icmp6hdr hdr6; bool success = true; hdr4.type = ICMP_PARAMETERPROB; hdr4.code = ICMP_PTR_INDICATES_ERROR; hdr4.icmp4_unused = cpu_to_be32(0x08000000U); success &= ASSERT_INT(0, icmp4_to_icmp6_param_prob(&hdr4, &hdr6), "func result 1"); success &= ASSERT_UINT(ICMPV6_HDR_FIELD, hdr6.icmp6_code, "code"); success &= ASSERT_UINT(7, be32_to_cpu(hdr6.icmp6_pointer), "pointer"); hdr4.icmp4_unused = cpu_to_be32(0x05000000U); success &= ASSERT_INT(-EINVAL, icmp4_to_icmp6_param_prob(&hdr4, &hdr6), "func result 2"); return success; } static bool test_function_generate_ipv4_id(void) { struct frag_hdr hdr; __be16 attempt_1, attempt_2, attempt_3; bool success = true; attempt_1 = generate_ipv4_id(NULL); attempt_2 = generate_ipv4_id(NULL); attempt_3 = generate_ipv4_id(NULL); /* * At least one of the attempts should be nonzero, * otherwise the random would be sucking major ****. */ success &= ASSERT_BOOL(true, (attempt_1 | attempt_2 | attempt_3) != 0, "No frag"); hdr.identification = 0; success &= ASSERT_BE16(0, generate_ipv4_id(&hdr), "Simplest id"); hdr.identification = cpu_to_be32(0x0000abcdU); success &= ASSERT_BE16(0xabcd, generate_ipv4_id(&hdr), "No overflow"); hdr.identification = cpu_to_be32(0x12345678U); success &= ASSERT_BE16(0x5678, generate_ipv4_id(&hdr), "Overflow"); return success; } static bool test_function_generate_df_flag(void) { struct packet pkt; struct sk_buff *skb; bool success = true; skb = alloc_skb(1500, GFP_ATOMIC); if (!skb) return false; pkt.skb = skb; skb_put(skb, 1000); success &= ASSERT_UINT(0, generate_df_flag(&pkt), "Len < 1260"); skb_put(skb, 260); success &= ASSERT_UINT(0, generate_df_flag(&pkt), "Len = 1260"); skb_put(skb, 200); success &= ASSERT_UINT(1, generate_df_flag(&pkt), "Len > 1260"); kfree_skb(skb); return success; } /** * By the way. This test kind of looks like it should test more combinations of headers. * But that'd be testing the header iterator, not the build_protocol_field() function. * Please look elsewhere for that. */ static bool test_function_build_protocol_field(void) { struct ipv6hdr *ip6_hdr; struct ipv6_opt_hdr *hop_by_hop_hdr; struct ipv6_opt_hdr *routing_hdr; struct ipv6_opt_hdr *dest_options_hdr; struct icmp6hdr *icmp6_hdr; ip6_hdr = kmalloc(sizeof(*ip6_hdr) + 8 + 16 + 24 + sizeof(struct tcphdr), GFP_ATOMIC); if (!ip6_hdr) { log_err("Could not allocate a test packet."); goto failure; } /* Just ICMP. */ ip6_hdr->nexthdr = NEXTHDR_ICMP; ip6_hdr->payload_len = cpu_to_be16(sizeof(*icmp6_hdr)); if (!ASSERT_UINT(IPPROTO_ICMP, ttp64_xlat_proto(ip6_hdr), "Just ICMP")) goto failure; /* Skippable headers then ICMP. */ ip6_hdr->nexthdr = NEXTHDR_HOP; ip6_hdr->payload_len = cpu_to_be16(8 + 16 + 24 + sizeof(*icmp6_hdr)); hop_by_hop_hdr = (struct ipv6_opt_hdr *) (ip6_hdr + 1); hop_by_hop_hdr->nexthdr = NEXTHDR_ROUTING; hop_by_hop_hdr->hdrlen = 0; /* the hdrlen field does not include the first 8 octets. */ routing_hdr = (struct ipv6_opt_hdr *) (((unsigned char *) hop_by_hop_hdr) + 8); routing_hdr->nexthdr = NEXTHDR_DEST; routing_hdr->hdrlen = 1; dest_options_hdr = (struct ipv6_opt_hdr *) (((unsigned char *) routing_hdr) + 16); dest_options_hdr->nexthdr = NEXTHDR_ICMP; dest_options_hdr->hdrlen = 2; if (!ASSERT_UINT(IPPROTO_ICMP, ttp64_xlat_proto(ip6_hdr), "Skippable then ICMP")) goto failure; /* Skippable headers then something else */ dest_options_hdr->nexthdr = NEXTHDR_TCP; ip6_hdr->payload_len = cpu_to_be16(8 + 16 + 24 + sizeof(struct tcphdr)); if (!ASSERT_UINT(IPPROTO_TCP, ttp64_xlat_proto(ip6_hdr), "Skippable then TCP")) goto failure; kfree(ip6_hdr); return true; failure: kfree(ip6_hdr); return false; } static bool test_function_has_nonzero_segments_left(void) { struct ipv6hdr *ip6_hdr; struct ipv6_rt_hdr *routing_hdr; struct frag_hdr *fragment_hdr; __u32 offset; bool success = true; ip6_hdr = kmalloc(sizeof(*ip6_hdr) + sizeof(*fragment_hdr) + sizeof(*routing_hdr), GFP_ATOMIC); if (!ip6_hdr) { log_err("Could not allocate a test packet."); return false; } ip6_hdr->payload_len = cpu_to_be16(sizeof(*fragment_hdr) + sizeof(*routing_hdr)); /* No extension headers. */ ip6_hdr->nexthdr = NEXTHDR_TCP; success &= ASSERT_BOOL(false, has_nonzero_segments_left(ip6_hdr, &offset), "No extension headers"); if (!success) goto end; /* Routing header with nonzero segments left. */ ip6_hdr->nexthdr = NEXTHDR_ROUTING; routing_hdr = (struct ipv6_rt_hdr *) (ip6_hdr + 1); routing_hdr->segments_left = 12; success &= ASSERT_BOOL(true, has_nonzero_segments_left(ip6_hdr, &offset), "Nonzero left - result"); success &= ASSERT_UINT(40 + 3, offset, "Nonzero left - offset"); if (!success) goto end; /* Routing header with zero segments left. */ routing_hdr->segments_left = 0; success &= ASSERT_BOOL(false, has_nonzero_segments_left(ip6_hdr, &offset), "Zero left"); if (!success) goto end; /* * Fragment header, then routing header with nonzero segments left * (further test the out parameter). */ ip6_hdr->nexthdr = NEXTHDR_FRAGMENT; fragment_hdr = (struct frag_hdr *) (ip6_hdr + 1); fragment_hdr->nexthdr = NEXTHDR_ROUTING; routing_hdr = (struct ipv6_rt_hdr *) (fragment_hdr + 1); routing_hdr->segments_left = 24; success &= ASSERT_BOOL(true, has_nonzero_segments_left(ip6_hdr, &offset), "Two headers - result"); success &= ASSERT_UINT(40 + 8 + 3, offset, "Two headers - offset"); /* Fall through. */ end: kfree(ip6_hdr); return success; } static bool test_function_icmp4_minimum_mtu(void) { bool success = true; success &= ASSERT_UINT(2, be16_to_cpu(minimum(2, 4, 6)), "First is min"); success &= ASSERT_UINT(8, be16_to_cpu(minimum(10, 8, 12)), "Second is min"); success &= ASSERT_UINT(14, be16_to_cpu(minimum(16, 18, 14)), "Third is min"); return success; }