Example #1
0
static void test_arp(void)
{
	struct ofp_ifnet mock_ifnet;
	struct in_addr ip;
	uint8_t mac[OFP_ETHER_ADDR_LEN] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, };

	/* The buffer passed into ofp_ipv4_lookup_mac() must be 8 bytes since
	 * a 64-bit operation is currently being used to copy a MAC address.
	 */
	uint8_t mac_result[OFP_ETHER_ADDR_LEN + 2];

	CU_ASSERT(0 == ofp_init_local());

	memset(&mock_ifnet, 0, sizeof(mock_ifnet));
	CU_ASSERT(0 != inet_aton("1.1.1.1", &ip));

	/* Test entry insert, lookup, and remove. */
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));

	memset(mac_result, 0xFF, OFP_ETHER_ADDR_LEN);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	CU_ASSERT(0 == memcmp(mac, mac_result, OFP_ETHER_ADDR_LEN));

	CU_ASSERT(0 == ofp_arp_ipv4_remove(ip.s_addr, &mock_ifnet));
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out after a few hits. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
}
Example #2
0
static int
init_suite(void)
{
	odp_pool_param_t pool_params;
	ofp_pkt_hook pkt_hook[OFP_HOOK_MAX];
	odp_pool_t pool;
	odp_instance_t instance;

	/* Init ODP before calling anything else */
	if (odp_init_global(&instance, NULL, NULL)) {
		OFP_ERR("Error: ODP global init failed.\n");
		return -1;
	}

	/* Init this thread */
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		OFP_ERR("Error: ODP local init failed.\n");
		return -1;
	}

	memset(pkt_hook, 0, sizeof(pkt_hook));
	pkt_hook[OFP_HOOK_OUT_IPv4] = fastpath_hook_out_IPv4;
#ifdef INET6
	pkt_hook[OFP_HOOK_OUT_IPv6] = fastpath_hook_out_IPv6;
#endif /* INET6 */

	pool_params.pkt.seg_len = SHM_PKT_POOL_BUFFER_SIZE;
	pool_params.pkt.len     = SHM_PKT_POOL_BUFFER_SIZE;
	pool_params.pkt.num     = SHM_PKT_POOL_NB_PKTS;
	pool_params.type        = ODP_POOL_PACKET;

	(void) ofp_init_pre_global(pool_name, &pool_params, pkt_hook, &pool,
				   ARP_AGE_INTERVAL, ARP_ENTRY_TIMEOUT);

	ofp_arp_init_local();

	init_ifnet();

	ofp_arp_ipv4_insert(tun_rem_ip, tun_rem_mac, dev);

	return 0;
}
Example #3
0
static int
init_suite(void)
{
    odp_pool_param_t pool_params;
    ofp_pkt_hook pkt_hook[OFP_HOOK_MAX];
    odp_instance_t instance;

    /* Init ODP before calling anything else */
    if (odp_init_global(&instance, NULL, NULL)) {
        OFP_ERR("Error: ODP global init failed.\n");
        return -1;
    }

    /* Init this thread */
    if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
        OFP_ERR("Error: ODP local init failed.\n");
        return -1;
    }

    memset(pkt_hook, 0, sizeof(pkt_hook));

    pool_params.pkt.seg_len = SHM_PKT_POOL_BUFFER_SIZE;
    pool_params.pkt.len     = SHM_PKT_POOL_BUFFER_SIZE;
    pool_params.pkt.num     = SHM_PKT_POOL_SIZE / SHM_PKT_POOL_BUFFER_SIZE;
    pool_params.type        = ODP_POOL_PACKET;

    (void) ofp_init_pre_global("packet_pool", &pool_params,
                               pkt_hook, &ofp_packet_pool,
                               ARP_AGE_INTERVAL, ARP_ENTRY_TIMEOUT);

    ofp_arp_init_local();

    init_ifnet();

    ofp_arp_ipv4_insert(dst_ipaddr, dst_mac, dev);

    nexthop.gw = dst_ipaddr;
    nexthop.vlan = vlan;
    nexthop.port = port;

    return 0;
}
Example #4
0
void *pp_thread(void *arg)
{
	ALLOW_UNUSED_LOCAL(arg);

#if ODP_VERSION >= 102
	if (odp_init_local(ODP_THREAD_WORKER)) {
#else
	if (odp_init_local()) {
#endif
		OFP_ERR("odp_init_local failed");
		return NULL;
	}
	if (ofp_init_local()) {
		OFP_ERR("ofp_init_local failed");
		return NULL;
	}

	while (odp_atomic_load_u32(&still_running)) {
		odp_event_t event;
		odp_queue_t source_queue;

		event = odp_schedule(&source_queue, ODP_SCHED_WAIT);

		if (odp_event_type(event) != ODP_EVENT_TIMEOUT) {
			OFP_ERR("Unexpected event type %d",
				odp_event_type(event));
			continue;
		}

		ofp_timer_handle(event);
	}
	return NULL;
}

static void test_arp(void)
{
	struct ofp_ifnet mock_ifnet;
	struct in_addr ip;
	uint8_t mac[OFP_ETHER_ADDR_LEN] = { 0x00, 0xFF, 0x00, 0x00, 0xFF, 0x00, };

	/* The buffer passed into ofp_ipv4_lookup_mac() must be 8 bytes since
	 * a 64-bit operation is currently being used to copy a MAC address.
	 */
	uint8_t mac_result[OFP_ETHER_ADDR_LEN + 2];

	CU_ASSERT(0 == ofp_init_local());

	memset(&mock_ifnet, 0, sizeof(mock_ifnet));
	CU_ASSERT(0 != inet_aton("1.1.1.1", &ip));

	/* Test entry insert, lookup, and remove. */
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));

	memset(mac_result, 0xFF, OFP_ETHER_ADDR_LEN);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	CU_ASSERT(0 == memcmp(mac, mac_result, OFP_ETHER_ADDR_LEN));

	CU_ASSERT(0 == ofp_arp_ipv4_remove(ip.s_addr, &mock_ifnet));
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));

	/* Test entry is aged out after a few hits. */
	CU_ASSERT(0 == ofp_arp_ipv4_insert(ip.s_addr, mac, &mock_ifnet));
	OFP_INFO("Inserted ARP entry");
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL);
	CU_ASSERT(0 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
	sleep(ARP_AGE_INTERVAL + ARP_ENTRY_TIMEOUT);
	CU_ASSERT(-1 == ofp_ipv4_lookup_mac(ip.s_addr, mac_result, &mock_ifnet));
}

int main(void)
{
	CU_pSuite ptr_suite = NULL;
	int nr_of_failed_tests = 0;
	int nr_of_failed_suites = 0;

	/* Initialize the CUnit test registry */
	if (CUE_SUCCESS != CU_initialize_registry())
		return CU_get_error();

	/* add a suite to the registry */
	ptr_suite = CU_add_suite("ofp errno", init_suite, end_suite);
	if (NULL == ptr_suite) {
		CU_cleanup_registry();
		return CU_get_error();
	}
	if (NULL == CU_ADD_TEST(ptr_suite, test_arp)) {
		CU_cleanup_registry();
		return CU_get_error();
	}

#if defined(OFP_TESTMODE_AUTO)
	CU_set_output_filename("CUnit-Util");
	CU_automated_run_tests();
#else
	/* Run all tests using the CUnit Basic interface */
	CU_basic_set_mode(CU_BRM_VERBOSE);
	CU_basic_run_tests();
#endif

	nr_of_failed_tests = CU_get_number_of_tests_failed();
	nr_of_failed_suites = CU_get_number_of_suites_failed();
	CU_cleanup_registry();

	return (nr_of_failed_suites > 0 ?
		nr_of_failed_suites : nr_of_failed_tests);
}
static void
test_ofp_packet_input_gre_processed_inner_pkt_forwarded(void)
{
    odp_packet_t pkt;
    odp_event_t ev;
    int res;
    struct ofp_ether_header *eth;
    struct ofp_ip *ip;
    struct ofp_ip *ip_encap;
    uint32_t dst_ip;
    uint8_t dst_mac_addr[6] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66};

    my_test_val = TEST_LOCAL_HOOK_GRE;
    /* Call ofp_packet_input using a GRE pkt with destination ip
     * that matches the local ip on ifnet, tunnel found, GRE processed.
     * Inner packet does not match local ip, route found,
     * packet forwarded */

    ifnet->ip_addr = local_ip;
    if (create_odp_packet_ip4(&pkt, gre_frame, sizeof(gre_frame),
                              local_ip, tun_rem_ip)) {
        CU_FAIL("Fail to create packet");
        return;
    }

    ip_encap = (struct ofp_ip *)&in_pkt_data[38];

    dst_ip = local_ip + 10;
    test_ofp_add_route(port, vrf, vlan, ip_encap->ip_dst.s_addr, 24, 4,
                       dst_ip);
    ofp_arp_ipv4_insert(dst_ip, dst_mac_addr, ifnet);

    res = ofp_packet_input(pkt, interface_queue[port],
                           ofp_eth_vlan_processing);

    CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED);

    CU_ASSERT_NOT_EQUAL_FATAL(ev = odp_queue_deq(ifnet->outq_def),
                              ODP_EVENT_INVALID);
#ifdef SP
    CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID);
#endif
    CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID);

    pkt = odp_packet_from_event(ev);
    eth = odp_packet_data(pkt);
    ip = odp_packet_l3_ptr(pkt, NULL);

    if (memcmp(eth->ether_dhost, dst_mac_addr, OFP_ETHER_ADDR_LEN))
        CU_FAIL("Bad destination mac address.");
    if (memcmp(eth->ether_shost, ifnet->mac, OFP_ETHER_ADDR_LEN))
        CU_FAIL("Bad source mac address.");

    CU_ASSERT_EQUAL(ip->ip_src.s_addr, ip_encap->ip_src.s_addr);
    CU_ASSERT_EQUAL(ip->ip_dst.s_addr, ip_encap->ip_dst.s_addr);

    if (memcmp(ip + (ip->ip_hl << 2), ip_encap + (ip->ip_hl << 2),
               odp_be_to_cpu_16(ip_encap->ip_len) - (ip->ip_hl << 2)))
        CU_FAIL("corrupt l3 + data");

    odp_packet_free(odp_packet_from_event(ev));
    ifnet->ip_addr = 0;
    CU_PASS("ofp_packet_input_gre_processed_inner_pkt_to_sp");
}
static void
test_ofp_packet_input_forwarding_to_output(void)
{
    odp_packet_t pkt;
    odp_event_t ev;
    int res;

    /* Call ofp_packet_input using a pkt with destination ip
     * that does NOT match the local ip on ifnet and a route is found.
     * ARP is found for gateway IP.
     * Function returns OFP_PKT_PROCESSED and
     * packet is forwarded to ofp_ip_output.*/
    unsigned char ll_addr[13] = "123456789012";

    my_test_val = TEST_FORWARD_HOOK;

    CU_ASSERT_EQUAL(
        ofp_ipv4_lookup_mac(dst_ipaddr + 1, ll_addr, ifnet), -1);
    CU_ASSERT_EQUAL(
        ofp_arp_ipv4_insert(dst_ipaddr + 1, ll_addr, ifnet), 0);

    if (create_odp_packet_ip4(&pkt, test_frame, sizeof(test_frame),
                              dst_ipaddr, 0)) {
        CU_FAIL("Fail to create packet");
        return;
    }

    res = ofp_packet_input(pkt, interface_queue[port],
                           ofp_eth_vlan_processing);
    CU_ASSERT_EQUAL(res, OFP_PKT_PROCESSED);
    CU_ASSERT_NOT_EQUAL(ev = odp_queue_deq(ifnet->outq_def),
                        ODP_EVENT_INVALID);
    CU_ASSERT_EQUAL(odp_queue_deq(ifnet->outq_def), ODP_EVENT_INVALID);

#ifdef SP
    CU_ASSERT_EQUAL(odp_queue_deq(ifnet->spq_def), ODP_EVENT_INVALID);
#endif /* SP */

    CU_ASSERT_EQUAL(odp_packet_len(pkt), sizeof(test_frame));

    pkt = odp_packet_from_event(ev);
    struct ofp_ip *ip_in_pkt_data =
        (struct ofp_ip *)(in_pkt_data + OFP_ETHER_HDR_LEN);
    ip_in_pkt_data->ip_ttl--;

#ifdef OFP_PERFORMANCE
    /*checksum is not filled on ip_output*/
    ip_in_pkt_data->ip_sum =
        ((struct ofp_ip *)odp_packet_l3_ptr(pkt, NULL))->ip_sum;
#else
    ip_in_pkt_data->ip_sum = 0;
    ip_in_pkt_data->ip_sum = ofp_cksum_buffer((uint16_t *)ip_in_pkt_data,
                             ip_in_pkt_data->ip_hl<<2);

#endif

    if (memcmp((uint8_t *)odp_packet_data(pkt) + odp_packet_l3_offset(pkt),
               in_pkt_data + OFP_ETHER_HDR_LEN,
               sizeof(test_frame) - OFP_ETHER_HDR_LEN))
        CU_FAIL("corrupt l3 + data forwarded");
    struct ofp_ether_header *eth =
        (struct ofp_ether_header *)odp_packet_l2_ptr(pkt, NULL);

    if (memcmp(eth->ether_dhost, ll_addr, OFP_ETHER_ADDR_LEN))
        CU_FAIL("Bad destination mac address on the forwarded packet");
    CU_ASSERT_EQUAL(eth->ether_type, odp_cpu_to_be_16(OFP_ETHERTYPE_IP));

    CU_PASS("ofp_packet_input_forwarding_to_output");
}