コード例 #1
0
ファイル: pool4_test.c プロジェクト: edygarza/NAT64
/**
 * The return function cannot be tested on its own, so here's also the rest of the get_any test.
 *
 * Purpose is to test get returns address/ports in the expected order, given different combinations
 * of return calls.
 * We only use the lower even range of ports, since the rest was tested during
 * test_get_any_function().
 */
static bool test_return_function(void)
{
	bool success = true;
	int i;

	memset(&results1, 0, sizeof(results1));
	memset(&results2, 0, sizeof(results2));

	// Borrow the entire first address.
	for (i = 0; i < 1024; i += 2) {
		success &= assert_true(pool4_get_any(IPPROTO_UDP, i, &results1[i]), "Borrow Addr1-res");
		success &= assert_tuple_addr(&expected_ips[0], i, &results1[i], "Borrow Addr1-out");
	}

	// Borrow the first port of the second address.
	success &= assert_true(pool4_get_any(IPPROTO_UDP, 0, &results2[0]), "Borrow Addr2-res-port0");
	success &= assert_tuple_addr(&expected_ips[1], 0, &results2[0], "Borrow Addr2-out-port0");

	// Return the last one.
	success &= assert_true(pool4_return(IPPROTO_UDP, &results2[0]), "Return Addr2-port0");
	if (!success)
		return success;

	// Reborrow it.
	success &= assert_true(pool4_get_any(IPPROTO_UDP, 0, &results2[0]), "Reborrow Addr2-res-port0");
	success &= assert_tuple_addr(&expected_ips[1], 0, &results2[0], "Reborrow Addr2-out-port0");
	if (!success)
		return success;

	// Return some more stuff.
	success &= assert_true(pool4_return(IPPROTO_UDP, &results1[46]), "Return Addr1-port46");
	success &= assert_true(pool4_return(IPPROTO_UDP, &results1[1000]), "Return Addr1-port1000");
	success &= assert_true(pool4_return(IPPROTO_UDP, &results2[0]), "ReReturn Addr2-port0");
	if (!success)
		return success;

	// Reborrow it.
	success &= assert_true(pool4_get_any(IPPROTO_UDP, 24, &results1[46]),
			"Reborrow Addr1-res-port46");
	success &= assert_true(pool4_get_any(IPPROTO_UDP, 1010, &results1[1000]),
			"Reborrow Addr1-res-port1000");
	success &= assert_true(pool4_get_any(IPPROTO_UDP, 56, &results2[0]),
			"ReReborrow Addr2-res-port0");
	success &= assert_tuple_addr(&expected_ips[0], 46, &results1[46],
			"Reborrow Addr1-out-port46");
	success &= assert_tuple_addr(&expected_ips[0], 1000, &results1[1000],
			"Reborrow Addr1-out-port1000");
	success &= assert_tuple_addr(&expected_ips[1], 0, &results2[0],
			"ReReborrow Addr2-out-port0");

	return success;
}
コード例 #2
0
ファイル: static_routes.c プロジェクト: patybarron/NAT64
int add_static_route(struct request_bib *req)
{
	struct bib_entry *bib = NULL;
	int error;

	error = pool4_get(req->l4_proto, &req->add.addr4);
	if (error) {
		log_err("The IPv4 address and port could not be reserved from the pool. "
				"Maybe the IPv4 address you provided does not belong to the pool. "
				"Or maybe they're being used by some other BIB entry?");
		return error;
	}

	bib = bib_create(&req->add.addr4, &req->add.addr6, true, req->l4_proto);
	if (!bib) {
		log_err("Could not allocate the BIB entry.");
		error = -ENOMEM;
		goto bib_error;
	}

	error = bibdb_add(bib);
	if (error) {
		log_err("The BIB entry could not be added to the database. Maybe an entry with the "
				"same IPv4 and/or IPv6 transport address already exists?");
		bib_kfree(bib);
		goto bib_error;
	}

	/*
	 * We do not call bib_return(bib) here, because we want the entry to hold a fake user so the
	 * timer doesn't delete it.
	 */

	return 0;

bib_error:
	pool4_return(req->l4_proto, &req->add.addr4);
	return error;
}
コード例 #3
0
ファイル: pool4_test.c プロジェクト: kuldeepin/NAT64
/**
 * Only UDP and its lower even range of ports is tested here.
 */
static bool test_return_function(void)
{
    struct ipv4_tuple_address query, result;
    bool success = true;
    int addr_ctr, port_ctr;

    /* Try to return the entire pool, even though we haven't borrowed anything. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        result.address = expected_ips[addr_ctr];
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            result.l4_id = port_ctr;
            success &= assert_false(pool4_return(IPPROTO_UDP, &result), "");
        }
    }

    /* Borrow the entire pool. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            success &= assert_true(pool4_get_any(IPPROTO_UDP, port_ctr, &result), "Borrow-result");
            success &= assert_equals_ipv4(&expected_ips[addr_ctr], &result.address, "Borrow-addr");
            success &= assert_false(ports[addr_ctr][result.l4_id], "Borrow-port");
            ports[addr_ctr][result.l4_id] = true;
        }
    }
    success &= assert_false(pool4_get_any(IPPROTO_UDP, 0, &result), "Pool should be exhausted.");

    if (!success)
        return success;

    /* Return something from the first address. */
    result.address = expected_ips[0];
    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return");
    ports[0][result.l4_id] = false;

    if (!success)
        return success;

    /* Re-borrow it, assert it's the same one. */
    success &= assert_true(pool4_get_any(IPPROTO_UDP, 0, &result), "");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;
    success &= assert_false(pool4_get_any(IPPROTO_UDP, 0, &result), "");

    if (!success)
        return success;

    /*
     * Do the same to the second address. Use get_similar() instead of get_any() to add some quick
     * noise.
     */
    result.address = expected_ips[1];
    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return");
    ports[1][result.l4_id] = false;

    if (!success)
        return success;

    query.address = expected_ips[1];
    query.l4_id = 0;
    success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &result), "");
    success &= assert_equals_ipv4(&expected_ips[1], &result.address, "");
    success &= assert_false(ports[1][result.l4_id], "");
    ports[1][result.l4_id] = true;
    success &= assert_false(pool4_get_similar(IPPROTO_UDP, &query, &result), "");

    if (!success)
        return success;

    /* Return some more stuff at once. */
    result.address = expected_ips[0];
    result.l4_id = 46;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return Addr1-port46");
    ports[0][46] = false;

    result.l4_id = 1000;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "Return Addr1-port1000");
    ports[0][1000] = false;

    result.address = expected_ips[1];
    result.l4_id = 0;
    success &= assert_true(pool4_return(IPPROTO_UDP, &result), "ReReturn Addr2-port0");
    ports[1][0] = false;

    if (!success)
        return success;

    /* Reborrow it. */
    success &= assert_true(pool4_get_any(IPPROTO_UDP, 24, &result), "Reborrow Addr1-res-port24");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;

    query.address = expected_ips[0];
    query.l4_id = 100;
    success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &result), "Reborrow Addr1-res-port100");
    success &= assert_equals_ipv4(&expected_ips[0], &result.address, "");
    success &= assert_false(ports[0][result.l4_id], "");
    ports[0][result.l4_id] = true;

    success &= assert_true(pool4_get_any(IPPROTO_UDP, 56, &result), "ReReborrow Addr2-res-port56");
    success &= assert_equals_ipv4(&expected_ips[1], &result.address, "");
    success &= assert_false(ports[1][result.l4_id], "");
    ports[1][result.l4_id] = true;

    success &= assert_false(pool4_get_any(IPPROTO_UDP, 12, &result), "");

    if (!success)
        return success;

    /* Now return everything. */
    for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
        result.address = expected_ips[addr_ctr];
        for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
            result.l4_id = port_ctr;
            success &= assert_true(pool4_return(IPPROTO_UDP, &result), "");
            ports[addr_ctr][port_ctr] = false;
        }
    }
    success &= assert_false(pool4_return(IPPROTO_UDP, &result), "");

    return success;
}
コード例 #4
0
ファイル: pool4_test.c プロジェクト: zhulianhai/NAT64
/**
 * Only UDP and its lower even range of ports is tested here.
 */
static bool test_return_function(void)
{
	struct ipv4_transport_addr tuple_addr;
	__u16 l4_id;
	bool success = true;
	int addr_ctr, port_ctr;

	/* Try to return the entire pool, even though we haven't borrowed anything. */
	for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
		tuple_addr.l3 = expected_ips[addr_ctr];
		for (port_ctr = 0; port_ctr < 1024; port_ctr += 2) {
			tuple_addr.l4 = port_ctr;
			success &= assert_equals_int(-EINVAL, pool4_return(L4PROTO_UDP, &tuple_addr),
					"Returning first");
		}
	}

	/* Borrow the entire pool. */
	for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
		tuple_addr.l3 = expected_ips[addr_ctr];
		for (port_ctr = 2; port_ctr < 1024; port_ctr += 2) {
			tuple_addr.l4 = port_ctr;
			success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
					"Borrow everything-result");
			success &= assert_false(ports[addr_ctr][l4_id], "Borrow everything-port");
			ports[addr_ctr][l4_id] = true;
		}
		success &= assert_equals_int(-ESRCH, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
				"Pool should be exhausted 1");
	}

	if (!success)
		return success;

	/* Return something from the first address. */
	tuple_addr.l3 = expected_ips[0];
	tuple_addr.l4 = 1000;
	success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr), "Return 0-1000 1");

	if (!success)
		return success;

	/* Re-borrow it, assert it's the same one. */
	success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Borrow 0-1000");
	success &= assert_equals_u16(1000, l4_id, "Confirm 0-1000");
	success &= assert_equals_int(-ESRCH, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Reborrow 0-1000");

	if (!success)
		return success;

	/* Do the same to the second address. */
	tuple_addr.l3 = expected_ips[1];
	tuple_addr.l4 = 1000;
	success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr), "Return 1-1000");

	if (!success)
		return success;

	success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Borrow 1-1000");
	success &= assert_equals_u16(1000, l4_id, "Confirm 1-1000");
	success &= assert_equals_int(-ESRCH, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Reborrow 1-1000");

	if (!success)
		return success;

	/* Return some more stuff at once. */
	tuple_addr.l3 = expected_ips[0];
	tuple_addr.l4 = 46;
	success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr), "Return 0-46");

	tuple_addr.l4 = 1000;
	success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr), "Return 0-1000 2");

	tuple_addr.l3 = expected_ips[1];
	tuple_addr.l4 = 0;
	success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr), "Return 1-0");

	if (!success)
		return success;

	/* Reborrow it. */
	tuple_addr.l3 = expected_ips[0];
	tuple_addr.l4 = 24;
	success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Borrow 0-24");
	success &= assert_true(l4_id == 46 || l4_id == 1000, "Confirm 0-24");

	tuple_addr.l4 = 100;
	success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Borrow 1-100");
	success &= assert_true(l4_id == 46 || l4_id == 1000, "Confirm 1-100");

	tuple_addr.l3 = expected_ips[1];
	tuple_addr.l4 = 56;
	success &= assert_equals_int(0, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Reborrow 2-56");
	success &= assert_equals_u16(0, l4_id, "Confirm 2-56");

	success &= assert_equals_int(-ESRCH, pool4_get_match(L4PROTO_UDP, &tuple_addr, &l4_id),
			"Pool should be exhausted 2");

	if (!success)
		return success;

	/* Now return everything. */
	for (addr_ctr = 0; addr_ctr < ARRAY_SIZE(expected_ips); addr_ctr++) {
		tuple_addr.l3 = expected_ips[addr_ctr];
		for (port_ctr = 2; port_ctr < 1024; port_ctr += 2) {
			tuple_addr.l4 = port_ctr;
			success &= assert_equals_int(0, pool4_return(L4PROTO_UDP, &tuple_addr),
					"Returning everything");
		}
	}
	success &= assert_equals_int(-EINVAL, pool4_return(L4PROTO_UDP, &tuple_addr), "Return fail");

	return success;
}
コード例 #5
0
ファイル: pool4_test.c プロジェクト: edygarza/NAT64
static bool test_get_similar_function(void)
{
	struct ipv4_tuple_address query;
	struct ipv4_tuple_address null_result;
	bool success = true;
	int i;

	memset(&results1, 0, sizeof(results1));
	memset(&results2, 0, sizeof(results2));

	// Borrow the entire first address.
	query.address = expected_ips[0];
	query.l4_id = 24;
	for (i = 0; i < 1024; i += 2) {
		success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results1[i]),
				"Borrow Addr1-res");
		success &= assert_tuple_addr(&expected_ips[0], i, &results1[i], "Borrow Addr1-out");
	}

	success &= assert_false(pool4_get_similar(IPPROTO_UDP, &query, &null_result),
			"Borrow Addr1-Exhausted (1)");
	success &= assert_false(pool4_get_similar(IPPROTO_UDP, &query, &null_result),
			"Borrow Addr1-Exhausted (2)");

	if (!success)
		return success;

	// Borrow some from the second address.
	query.address = expected_ips[1];
	query.l4_id = 888;
	for (i = 0; i < 512; i += 2) {
		success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results2[i]),
				"Borrow Addr2-res");
		success &= assert_tuple_addr(&expected_ips[1], i, &results2[i], "Borrow Addr2-out");
	}

	if (!success)
		return success;

	// Now return stuff in some disorganized manner.
	success &= assert_true(pool4_return(IPPROTO_UDP, &results2[64]), "Return Addr2-port64");
	success &= assert_true(pool4_return(IPPROTO_UDP, &results1[128]), "Return Addr1-port128");
	success &= assert_true(pool4_return(IPPROTO_UDP, &results1[32]), "Return Addr2-port32");
	success &= assert_true(pool4_return(IPPROTO_UDP, &results2[256]), "Return Addr1-port256");

	// Reborrow it.
	query.l4_id = 334;

	query.address = expected_ips[0];
	success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results1[128]),
			"Get-Return mix (res), 128");
	query.address = expected_ips[1];
	success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results2[64]),
			"Get-Return mix, (res) 64");
	query.address = expected_ips[0];
	success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results1[32]),
			"Get-Return mix, (res) 32");
	query.address = expected_ips[1];
	success &= assert_true(pool4_get_similar(IPPROTO_UDP, &query, &results2[256]),
			"Get-Return mix, (res) 256");
	query.address = expected_ips[0];
	success &= assert_false(pool4_get_similar(IPPROTO_UDP, &query, &null_result),
			"Borrow Addr1-Exhausted (3)");

	success &= assert_tuple_addr(&expected_ips[0], 128, &results1[128],
			"Get-Return mix (out), 128");
	success &= assert_tuple_addr(&expected_ips[1], 64, &results2[64],
			"Get-Return mix (out), 64");
	success &= assert_tuple_addr(&expected_ips[0], 32, &results1[32],
			"Get-Return mix (out), 32");
	success &= assert_tuple_addr(&expected_ips[1], 256, &results2[256],
			"Get-Return mix (out), 256");

	return success;
}
コード例 #6
0
ファイル: static_routes.c プロジェクト: alphadx/NAT64
int delete_static_route(struct request_bib *req)
{
	struct bib_entry *bib;
	struct session_entry *session;
	int error = 0;

	spin_lock_bh(&bib_session_lock);

	switch (req->remove.l3_proto) {
	case L3PROTO_IPV6:
		error = bib_get_by_ipv6(&req->remove.ipv6, req->l4_proto, &bib);
		if (error)
			goto end;
		break;
	case L3PROTO_IPV4:
		error = bib_get_by_ipv4(&req->remove.ipv4, req->l4_proto, &bib);
		if (error)
			goto end;
		break;
	default:
		log_err(ERR_L3PROTO, "Unsupported network protocol: %u.", req->remove.l3_proto);
		error = -EINVAL;
		goto end;
	}

	if (!bib) {
		log_err(ERR_BIB_NOT_FOUND, "Could not find the BIB entry requested by the user.");
		error = -ENOENT;
		goto end;
	}

	/*
	 * I'm tempted to assert that the entry is static here. Would that serve a purpose?
	 * Nah.
	 */

	while (!list_empty(&bib->sessions)) {
		session = container_of(bib->sessions.next, struct session_entry, bib_list_hook);
		error = session_remove(session);
		if (error) {
			log_err(ERR_UNKNOWN_ERROR,
					"Session [%pI6c#%u, %pI6c#%u, %pI4#%u, %pI4#%u] refused to die.",
					&session->ipv6.remote.address, session->ipv6.remote.l4_id,
					&session->ipv6.local.address, session->ipv6.local.l4_id,
					&session->ipv4.local.address, session->ipv4.local.l4_id,
					&session->ipv4.remote.address, session->ipv4.remote.l4_id);
			goto end;
		}
		list_del(&session->bib_list_hook);
		list_del(&session->expire_list_hook);
		session_kfree(session);
	}

	error = bib_remove(bib, req->l4_proto);
	if (error) {
		log_err(ERR_UNKNOWN_ERROR, "Remove bib entry call ended with error code %d, "
				"despite validations.", error);
		goto end;
	}

	pool4_return(req->l4_proto, &bib->ipv4);
	bib_kfree(bib);
	/* Fall through. */

end:
	spin_unlock_bh(&bib_session_lock);
	return error;
}