예제 #1
0
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;
}
예제 #2
0
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;
}
예제 #3
0
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;
}
예제 #4
0
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;
}
예제 #5
0
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;
}
예제 #6
0
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;
}
예제 #7
0
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;
}
예제 #8
0
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;
}
예제 #9
0
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;
}
예제 #10
0
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;
}
예제 #11
0
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;
}
예제 #12
0
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;
}
예제 #13
0
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;
}