Пример #1
0
void pktio_test_send_on_ronly(void)
{
	odp_pktio_t pktio;
	odp_packet_t pkt;
	int ret;

	pktio = create_pktio(0, ODP_PKTIN_MODE_RECV,
			     ODP_PKTOUT_MODE_DISABLED);

	if (pktio == ODP_PKTIO_INVALID) {
		CU_FAIL("failed to open pktio");
		return;
	}

	ret = odp_pktio_start(pktio);
	CU_ASSERT_FATAL(ret == 0);

	pkt = odp_packet_alloc(default_pkt_pool, packet_len);
	CU_ASSERT_FATAL(pkt != ODP_PACKET_INVALID)

	pktio_init_packet(pkt);

	ret = odp_pktio_send(pktio, &pkt, 1);
	CU_ASSERT(ret < 0);

	if (ret <= 0)
		odp_packet_free(pkt);

	ret = odp_pktio_stop(pktio);
	CU_ASSERT_FATAL(ret == 0);

	ret = odp_pktio_close(pktio);
	CU_ASSERT_FATAL(ret == 0);
}
Пример #2
0
static int setup_test()
{
	odp_pool_param_t params;
	odp_pktio_param_t pktio_param = {0};
	odp_pktio_t tmp;

	memset(&params, 0, sizeof(params));
	params.pkt.seg_len = PKT_BUF_SIZE;
	params.pkt.len     = PKT_BUF_SIZE;
	params.pkt.num     = PKT_BUF_NUM;
	params.type        = ODP_POOL_PACKET;

	pool = odp_pool_create(pool_name, &params);
	if (ODP_POOL_INVALID == pool) {
		fprintf(stderr, "unable to create pool\n");
		return 1;
	}

	pktio_param.in_mode = ODP_PKTIN_MODE_POLL;

	unsigned i;
	for ( i = 0; i < sizeof(pktio_invalid_names)/sizeof(pktio_invalid_names[0]); ++i ) {
		tmp = odp_pktio_open(pktio_invalid_names[i], pool, &pktio_param);
		test_assert_ret(tmp == ODP_PKTIO_INVALID);
	}

	pktio = odp_pktio_open(pktio_valid_name, pool, &pktio_param);
	test_assert_ret(pktio != ODP_PKTIO_INVALID);

	test_assert_ret(odp_pktio_start(pktio) == 0);

	printf("Setup ok\n");
	return 0;
}
Пример #3
0
void pktio_test_recv_on_wonly(void)
{
	odp_pktio_t pktio;
	odp_packet_t pkt;
	int ret;

	pktio = create_pktio(0, ODP_PKTIN_MODE_DISABLED,
			     ODP_PKTOUT_MODE_SEND);

	if (pktio == ODP_PKTIO_INVALID) {
		CU_FAIL("failed to open pktio");
		return;
	}

	ret = odp_pktio_start(pktio);
	CU_ASSERT_FATAL(ret == 0);

	ret = odp_pktio_recv(pktio, &pkt, 1);
	CU_ASSERT(ret < 0);

	if (ret > 0)
		odp_packet_free(pkt);

	ret = odp_pktio_stop(pktio);
	CU_ASSERT_FATAL(ret == 0);

	ret = odp_pktio_close(pktio);
	CU_ASSERT_FATAL(ret == 0);
}
Пример #4
0
static void test_txrx(odp_pktio_input_mode_t in_mode, int num_pkts)
{
	int ret, i, if_b;
	pktio_info_t pktios[MAX_NUM_IFACES];
	pktio_info_t *io;
	uint32_t mtu, min_mtu = UINT32_MAX;

	/* create pktios and associate input/output queues */
	for (i = 0; i < num_ifaces; ++i) {
		io = &pktios[i];

		io->name = iface_name[i];
		io->id   = create_pktio(i, in_mode, ODP_PKTOUT_MODE_SEND);
		if (io->id == ODP_PKTIO_INVALID) {
			CU_FAIL("failed to open iface");
			return;
		}
		io->outq = odp_pktio_outq_getdef(io->id);
		io->in_mode = in_mode;

		if (in_mode == ODP_PKTIN_MODE_POLL) {
			create_inq(io->id, ODP_QUEUE_TYPE_POLL);
			io->inq = odp_pktio_inq_getdef(io->id);
		} else if (in_mode == ODP_PKTIN_MODE_SCHED) {
			create_inq(io->id, ODP_QUEUE_TYPE_SCHED);
			io->inq = ODP_QUEUE_INVALID;
		}

	}
	for (i = 0; i < num_ifaces; ++i) {
		io = &pktios[i];
		ret = odp_pktio_start(io->id);
		CU_ASSERT(ret == 0);

		mtu = odp_pktio_mtu(io->id);
		if (mtu < min_mtu)
			min_mtu = mtu;
	}

	/* Skip test if packet len is larger than the MTU */
	if (min_mtu >= packet_len) {
		/* if we have two interfaces then send through one and receive
		 * on another but if there's only one assume it's a loopback */
		if_b = (num_ifaces == 1) ? 0 : 1;
		pktio_txrx_multi(&pktios[0], &pktios[if_b], num_pkts);
	}

	for (i = 0; i < num_ifaces; ++i) {
		ret = odp_pktio_stop(pktios[i].id);
		CU_ASSERT(ret == 0);
		if (in_mode != ODP_PKTIN_MODE_RECV)
			destroy_inq(pktios[i].id);
		ret = odp_pktio_close(pktios[i].id);
		CU_ASSERT(ret == 0);
	}
}
Пример #5
0
odp_pktio_t open_nic(const char* dev,odp_pool_t pool){
	odp_pktio_t pktio;
	//odp_queue_t inq_def;
	//odp_queue_param_t qparam;
	odp_pktio_param_t pktio_param;

	pktio_param.in_mode = ODP_PKTIN_MODE_RECV;
	pktio_param.out_mode = ODP_PKTOUT_MODE_SEND;
	pktio = odp_pktio_open(dev, pool, &pktio_param);
	odp_pktio_start(pktio);
	return pktio;
}
Пример #6
0
/**
 * Create a pktio object
 *
 * @param dev Name of device to open
 * @param pool Pool to associate with device for packet RX/TX
 *
 * @return The handle of the created pktio object.
 * @warning This routine aborts if the create is unsuccessful.
 */
static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool)
{
	odp_queue_param_t qparam;
	char inq_name[ODP_QUEUE_NAME_LEN];
	odp_pktio_t pktio;
	int ret;
	odp_queue_t inq_def;
	odp_pktio_param_t pktio_param;

	odp_pktio_param_init(&pktio_param);
	pktio_param.in_mode = ODP_PKTIN_MODE_DISABLED;

	/* Open a packet IO instance */
	pktio = odp_pktio_open(dev, pool, &pktio_param);

	if (pktio == ODP_PKTIO_INVALID)
		EXAMPLE_ABORT("Error: pktio create failed for %s\n", dev);

	/*
	 * Create and set the default INPUT queue associated with the 'pktio'
	 * resource
	 */
	odp_queue_param_init(&qparam);
	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
	qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
	qparam.sched.group = ODP_SCHED_GROUP_ALL;
	snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def",
		 odp_pktio_to_u64(pktio));
	inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';

	inq_def = odp_queue_create(inq_name, ODP_QUEUE_TYPE_PKTIN, &qparam);
	if (inq_def == ODP_QUEUE_INVALID)
		EXAMPLE_ABORT("Error: pktio inq create failed for %s\n", dev);

	ret = odp_pktio_inq_setdef(pktio, inq_def);
	if (ret != 0)
		EXAMPLE_ABORT("Error: default input-Q setup for %s\n", dev);

	ret = odp_pktio_start(pktio);
	if (ret)
		EXAMPLE_ABORT("Error: unable to start %s\n", dev);

	printf("  created pktio:%02" PRIu64
	       ", dev:%s, queue mode (ATOMIC queues)\n"
	       "          default pktio%02" PRIu64
	       "-INPUT queue:%" PRIu64 "\n",
	       odp_pktio_to_u64(pktio), dev,
	       odp_pktio_to_u64(pktio), odp_queue_to_u64(inq_def));

	return pktio;
}
Пример #7
0
int init_all_if(odp_pool_t pkt_pool)
{
    odp_pktio_param_t param;
    odp_pktio_t hdl;
    int i;
    uint8_t mac[6];
    uint32_t mtu;

    param.in_mode = ODP_PKTIN_MODE_RECV;
    param.out_mode = ODP_PKTOUT_MODE_SEND;

    for(i = 0; i < glb_param.nic.num; i++)
    {
        hdl = odp_pktio_open(glb_param.nic.names[i], pkt_pool, &param);
        if(hdl == ODP_PKTIO_INVALID)
        {
            return -1;
        }
        if(odp_pktio_mac_addr(hdl, mac, 6) < 0)
        {
            return -1;
        }
        if((mtu = odp_pktio_mtu(hdl)) < 0)
        {
            return -1;
        }
        if(odp_pktio_promisc_mode_set(hdl, 1) < 0)
        {
            return -1;
        }
        if(odp_pktio_start(hdl) < 0)
        {
            return -1;
        }
        thr_data.nic_hdl[i] = hdl;
        printf("NIC: %s (MAC:%2x-%2x-%2x-%2x-%2x-%2x, MTU:%u)\n",
                glb_param.nic.names[i],
                mac[0], mac[1], mac[2],
                mac[3], mac[4], mac[5],
                mtu);
    }
    return 0;
}
Пример #8
0
/**
 * Initialize interface
 *
 * Initialize ODP pktio and queues, query MAC address and update
 * forwarding database.
 *
 * @param intf     Interface name string
 */
static
void initialize_intf(char *intf)
{
	odp_pktio_t pktio;
	odp_pktout_queue_t pktout;
	odp_queue_t inq;
	int ret;
	uint8_t src_mac[ODPH_ETHADDR_LEN];
	char src_mac_str[MAX_STRING];
	odp_pktio_param_t pktio_param;
	odp_pktin_queue_param_t pktin_param;

	odp_pktio_param_init(&pktio_param);

	if (getenv("ODP_IPSEC_USE_POLL_QUEUES"))
		pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE;
	else
		pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;

	/*
	 * Open a packet IO instance for thread and get default output queue
	 */
	pktio = odp_pktio_open(intf, pkt_pool, &pktio_param);
	if (ODP_PKTIO_INVALID == pktio) {
		EXAMPLE_ERR("Error: pktio create failed for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	odp_pktin_queue_param_init(&pktin_param);
	pktin_param.queue_param.sched.sync = ODP_SCHED_SYNC_ATOMIC;

	if (odp_pktin_queue_config(pktio, &pktin_param)) {
		EXAMPLE_ERR("Error: pktin config failed for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	if (odp_pktout_queue_config(pktio, NULL)) {
		EXAMPLE_ERR("Error: pktout config failed for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	if (odp_pktin_event_queue(pktio, &inq, 1) != 1) {
		EXAMPLE_ERR("Error: failed to get input queue for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	if (odp_pktout_queue(pktio, &pktout, 1) != 1) {
		EXAMPLE_ERR("Error: failed to get pktout queue for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	ret = odp_pktio_start(pktio);
	if (ret) {
		EXAMPLE_ERR("Error: unable to start %s\n", intf);
		exit(EXIT_FAILURE);
	}

	/* Read the source MAC address for this interface */
	ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac));
	if (ret <= 0) {
		EXAMPLE_ERR("Error: failed during MAC address get for %s\n",
			    intf);
		exit(EXIT_FAILURE);
	}

	printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n"
	       "          default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n"
	       "          source mac address %s\n",
	       odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio),
	       odp_queue_to_u64(inq),
	       mac_addr_str(src_mac_str, src_mac));

	/* Resolve any routes using this interface for output */
	resolve_fwd_db(intf, pktout, src_mac);
}
Пример #9
0
/**
 * Initialize interface
 *
 * Initialize ODP pktio and queues, query MAC address and update
 * forwarding database.
 *
 * @param intf     Interface name string
 */
static
void initialize_intf(char *intf)
{
	odp_pktio_t pktio;
	odp_queue_t outq_def;
	odp_queue_t inq_def;
	char inq_name[ODP_QUEUE_NAME_LEN];
	odp_queue_param_t qparam;
	int ret;
	uint8_t src_mac[ODPH_ETHADDR_LEN];
	char src_mac_str[MAX_STRING];
	odp_pktio_param_t pktio_param;

	odp_pktio_param_init(&pktio_param);

	if (getenv("ODP_IPSEC_USE_POLL_QUEUES"))
		pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE;
	else
		pktio_param.in_mode = ODP_PKTIN_MODE_SCHED;

	/*
	 * Open a packet IO instance for thread and get default output queue
	 */
	pktio = odp_pktio_open(intf, pkt_pool, &pktio_param);
	if (ODP_PKTIO_INVALID == pktio) {
		EXAMPLE_ERR("Error: pktio create failed for %s\n", intf);
		exit(EXIT_FAILURE);
	}
	outq_def = odp_pktio_outq_getdef(pktio);

	/*
	 * Create and set the default INPUT queue associated with the 'pktio'
	 * resource
	 */
	odp_queue_param_init(&qparam);
	qparam.type        = ODP_QUEUE_TYPE_PKTIN;
	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
	qparam.sched.sync  = ODP_SCHED_SYNC_ATOMIC;
	qparam.sched.group = ODP_SCHED_GROUP_ALL;
	snprintf(inq_name, sizeof(inq_name), "%" PRIu64 "-pktio_inq_def",
		 odp_pktio_to_u64(pktio));
	inq_name[ODP_QUEUE_NAME_LEN - 1] = '\0';

	inq_def = queue_create(inq_name, &qparam);
	if (ODP_QUEUE_INVALID == inq_def) {
		EXAMPLE_ERR("Error: pktio queue creation failed for %s\n",
			    intf);
		exit(EXIT_FAILURE);
	}

	ret = odp_pktio_inq_setdef(pktio, inq_def);
	if (ret) {
		EXAMPLE_ERR("Error: default input-Q setup for %s\n", intf);
		exit(EXIT_FAILURE);
	}

	ret = odp_pktio_start(pktio);
	if (ret) {
		EXAMPLE_ERR("Error: unable to start %s\n", intf);
		exit(EXIT_FAILURE);
	}

	/* Read the source MAC address for this interface */
	ret = odp_pktio_mac_addr(pktio, src_mac, sizeof(src_mac));
	if (ret <= 0) {
		EXAMPLE_ERR("Error: failed during MAC address get for %s\n",
			    intf);
		exit(EXIT_FAILURE);
	}

	printf("Created pktio:%02" PRIu64 ", queue mode (ATOMIC queues)\n"
	       "          default pktio%02" PRIu64 "-INPUT queue:%" PRIu64 "\n"
	       "          source mac address %s\n",
	       odp_pktio_to_u64(pktio), odp_pktio_to_u64(pktio),
	       odp_queue_to_u64(inq_def),
	       mac_addr_str(src_mac_str, src_mac));

	/* Resolve any routes using this interface for output */
	resolve_fwd_db(intf, outq_def, src_mac);
}
Пример #10
0
static int ipc_second_process(void)
{
	odp_pktio_t ipc_pktio;
	odp_pool_param_t params;
	odp_pool_t pool;
	odp_packet_t pkt_tbl[MAX_PKT_BURST];
	odp_packet_t alloc_pkt;
	int pkts;
	int ret;
	int i;
	odp_time_t start_cycle;
	odp_time_t cycle;
	odp_time_t diff;
	odp_time_t wait;
	uint64_t stat_pkts = 0;
	odp_pktin_queue_t pktin;

	/* Create packet pool */
	memset(&params, 0, sizeof(params));
	params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.num     = SHM_PKT_POOL_SIZE;
	params.type        = ODP_POOL_PACKET;

	pool = odp_pool_create("packet_pool2", &params);
	if (pool == ODP_POOL_INVALID) {
		EXAMPLE_ERR("Error: packet pool create failed.\n");
		exit(EXIT_FAILURE);
	}

	ipc_pktio = create_pktio(pool);

	wait = odp_time_local_from_ns(run_time_sec * ODP_TIME_SEC_IN_NS);
	start_cycle = odp_time_local();

	if (odp_pktin_queue(ipc_pktio, &pktin, 1) != 1) {
		EXAMPLE_ERR("no input queue\n");
		return -1;
	}

	/* start ipc pktio, i.e. wait until other process connects */
	for (;;) {
		/* 1. exit loop if time specified */
		if (run_time_sec) {
			cycle = odp_time_local();
			diff = odp_time_diff(cycle, start_cycle);
			if (odp_time_cmp(wait, diff) < 0) {
				printf("timeout exit, run_time_sec %d\n",
				       run_time_sec);
				goto not_started;
			}
		}

		ret = odp_pktio_start(ipc_pktio);
		if (!ret)
			break;
	}

	for (;;) {
		/* exit loop if time specified */
		if (run_time_sec) {
			cycle = odp_time_local();
			diff = odp_time_diff(cycle, start_cycle);
			if (odp_time_cmp(wait, diff) < 0) {
				EXAMPLE_DBG("exit after %d seconds\n",
					    run_time_sec);
				break;
			}
		}

		/* recv some packets and change MAGIC to MAGIC_2 */
		pkts = odp_pktin_recv(pktin, pkt_tbl, MAX_PKT_BURST);
		if (pkts <= 0)
			continue;

		for (i = 0; i < pkts; i++) {
			odp_packet_t pkt = pkt_tbl[i];
			pkt_head_t head;
			size_t off;

			off = odp_packet_l4_offset(pkt);
			if (off ==  ODP_PACKET_OFFSET_INVALID)
				EXAMPLE_ABORT("invalid l4 offset\n");

			off += ODPH_UDPHDR_LEN;
			ret = odp_packet_copy_to_mem(pkt, off, sizeof(head),
						     &head);
			if (ret)
				EXAMPLE_ABORT("unable copy out head data");

			if (head.magic != TEST_SEQ_MAGIC)
				EXAMPLE_ABORT("Wrong head magic!");

			/* Modify magic number in packet */
			head.magic = TEST_SEQ_MAGIC_2;
			ret = odp_packet_copy_from_mem(pkt, off, sizeof(head),
						       &head);
			if (ret)
				EXAMPLE_ABORT("unable to copy in head data");
		}

		/* send all packets back */
		ret = ipc_odp_packet_send_or_free(ipc_pktio, pkt_tbl, pkts);
		if (ret < 0)
			EXAMPLE_ABORT("can not send packets\n");

		stat_pkts += ret;

		/* alloc packet from local pool, set magic to ALLOC_MAGIC,
		 * and send it.*/
		alloc_pkt = odp_packet_alloc(pool, SHM_PKT_POOL_BUF_SIZE);
		if (alloc_pkt != ODP_PACKET_INVALID) {
			pkt_head_t head;
			size_t off;

			odp_packet_l4_offset_set(alloc_pkt, 30);

			head.magic = TEST_ALLOC_MAGIC;

			off = odp_packet_l4_offset(alloc_pkt);
			off += ODPH_UDPHDR_LEN;
			ret = odp_packet_copy_from_mem(alloc_pkt, off,
						       sizeof(head),
						       &head);
			if (ret)
				EXAMPLE_ABORT("unable to copy in head data");

			pkt_tbl[0] = alloc_pkt;
			ret = ipc_odp_packet_send_or_free(ipc_pktio,
							  pkt_tbl, 1);
			if (ret < 0)
				EXAMPLE_ABORT("can not send packets\n");
			stat_pkts += 1;
		}
	}

	/* cleanup and exit */
	ret = odp_pktio_stop(ipc_pktio);
	if (ret) {
		EXAMPLE_DBG("ipc2: odp_pktio_stop error %d\n", ret);
		return -1;
	}

not_started:
	ret = odp_pktio_close(ipc_pktio);
	if (ret) {
		EXAMPLE_DBG("ipc2: odp_pktio_close error %d\n", ret);
		return -1;
	}

	ret = odp_pool_destroy(pool);
	if (ret)
		EXAMPLE_DBG("ipc2: pool_destroy error %d\n", ret);

	return stat_pkts > 1000 ? 0 : -1;
}
Пример #11
0
static int test_init(void)
{
	odp_pool_param_t params;
	const char *iface;
	int schedule;

	odp_pool_param_init(&params);
	params.pkt.len     = PKT_HDR_LEN + gbl_args->args.pkt_len;
	params.pkt.seg_len = params.pkt.len;
	params.pkt.num     = PKT_BUF_NUM;
	params.type        = ODP_POOL_PACKET;

	transmit_pkt_pool = odp_pool_create("pkt_pool_transmit", &params);
	if (transmit_pkt_pool == ODP_POOL_INVALID)
		LOG_ABORT("Failed to create transmit pool\n");

	odp_atomic_init_u32(&ip_seq, 0);
	odp_atomic_init_u32(&shutdown, 0);

	iface    = gbl_args->args.ifaces[0];
	schedule = gbl_args->args.schedule;

	/* create pktios and associate input/output queues */
	gbl_args->pktio_tx = create_pktio(iface, schedule);
	if (gbl_args->args.num_ifaces > 1) {
		iface = gbl_args->args.ifaces[1];
		gbl_args->pktio_rx = create_pktio(iface, schedule);
	} else {
		gbl_args->pktio_rx = gbl_args->pktio_tx;
	}

	odp_pktio_mac_addr(gbl_args->pktio_tx, gbl_args->src_mac,
			   ODPH_ETHADDR_LEN);
	odp_pktio_mac_addr(gbl_args->pktio_rx, gbl_args->dst_mac,
			   ODPH_ETHADDR_LEN);

	if (gbl_args->pktio_rx == ODP_PKTIO_INVALID ||
	    gbl_args->pktio_tx == ODP_PKTIO_INVALID) {
		LOG_ERR("failed to open pktio\n");
		return -1;
	}

	/* Create single queue with default parameters */
	if (odp_pktout_queue_config(gbl_args->pktio_tx, NULL)) {
		LOG_ERR("failed to configure pktio_tx queue\n");
		return -1;
	}

	/* Configure also input side (with defaults) */
	if (odp_pktin_queue_config(gbl_args->pktio_tx, NULL)) {
		LOG_ERR("failed to configure pktio_tx queue\n");
		return -1;
	}

	if (gbl_args->args.num_ifaces > 1) {
		if (odp_pktout_queue_config(gbl_args->pktio_rx, NULL)) {
			LOG_ERR("failed to configure pktio_rx queue\n");
			return -1;
		}

		if (odp_pktin_queue_config(gbl_args->pktio_rx, NULL)) {
			LOG_ERR("failed to configure pktio_rx queue\n");
			return -1;
		}
	}

	if (odp_pktio_start(gbl_args->pktio_tx) != 0)
		return -1;
	if (gbl_args->args.num_ifaces > 1 &&
	    odp_pktio_start(gbl_args->pktio_rx))
		return -1;

	return 0;
}
Пример #12
0
/**
 * ODP L2 forwarding main function
 */
int main(int argc, char *argv[])
{
	odph_linux_pthread_t thread_tbl[MAX_WORKERS];
	odp_pool_t pool;
	int i;
	int cpu;
	int num_workers;
	odp_shm_t shm;
	odp_cpumask_t cpumask;
	char cpumaskstr[ODP_CPUMASK_STR_SIZE];
	odph_ethaddr_t new_addr;
	odp_pktio_t pktio;
	odp_pool_param_t params;
	int ret;
	stats_t *stats;

	/* Init ODP before calling anything else */
	if (odp_init_global(NULL, NULL)) {
		LOG_ERR("Error: ODP global init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Init this thread */
	if (odp_init_local(ODP_THREAD_CONTROL)) {
		LOG_ERR("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Reserve memory for args from shared mem */
	shm = odp_shm_reserve("shm_args", sizeof(args_t),
			      ODP_CACHE_LINE_SIZE, 0);
	gbl_args = odp_shm_addr(shm);

	if (gbl_args == NULL) {
		LOG_ERR("Error: shared mem alloc failed.\n");
		exit(EXIT_FAILURE);
	}
	memset(gbl_args, 0, sizeof(*gbl_args));

	/* Parse and store the application arguments */
	parse_args(argc, argv, &gbl_args->appl);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &gbl_args->appl);

	/* Default to system CPU count unless user specified */
	num_workers = MAX_WORKERS;
	if (gbl_args->appl.cpu_count)
		num_workers = gbl_args->appl.cpu_count;

	/* Get default worker cpumask */
	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	(void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	printf("num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	if (num_workers < gbl_args->appl.if_count) {
		LOG_ERR("Error: CPU count %d less than interface count\n",
			num_workers);
		exit(EXIT_FAILURE);
	}

	/* Create packet pool */
	odp_pool_param_init(&params);
	params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.num     = SHM_PKT_POOL_SIZE/SHM_PKT_POOL_BUF_SIZE;
	params.type        = ODP_POOL_PACKET;

	pool = odp_pool_create("packet pool", &params);

	if (pool == ODP_POOL_INVALID) {
		LOG_ERR("Error: packet pool create failed.\n");
		exit(EXIT_FAILURE);
	}
	odp_pool_print(pool);

	for (i = 0; i < gbl_args->appl.if_count; ++i) {
		pktio = create_pktio(gbl_args->appl.if_names[i], pool);
		if (pktio == ODP_PKTIO_INVALID)
			exit(EXIT_FAILURE);
		gbl_args->pktios[i] = pktio;

		/* Save interface ethernet address */
		if (odp_pktio_mac_addr(pktio, gbl_args->port_eth_addr[i].addr,
				       ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
			LOG_ERR("Error: interface ethernet address unknown\n");
			exit(EXIT_FAILURE);
		}

		/* Save destination eth address */
		if (gbl_args->appl.dst_change) {
			/* 02:00:00:00:00:XX */
			memset(&new_addr, 0, sizeof(odph_ethaddr_t));
			new_addr.addr[0] = 0x02;
			new_addr.addr[5] = i;
			gbl_args->dst_eth_addr[i] = new_addr;
		}

		/* Save interface destination port */
		gbl_args->dst_port[i] = find_dest_port(i);
	}

	gbl_args->pktios[i] = ODP_PKTIO_INVALID;

	memset(thread_tbl, 0, sizeof(thread_tbl));

	stats = gbl_args->stats;

	odp_barrier_init(&barrier, num_workers + 1);

	/* Create worker threads */
	cpu = odp_cpumask_first(&cpumask);
	for (i = 0; i < num_workers; ++i) {
		odp_cpumask_t thd_mask;
		void *(*thr_run_func) (void *);

		if (gbl_args->appl.mode == DIRECT_RECV)
			thr_run_func = pktio_direct_recv_thread;
		else /* SCHED_NONE / SCHED_ATOMIC / SCHED_ORDERED */
			thr_run_func = pktio_queue_thread;

		gbl_args->thread[i].src_idx = i % gbl_args->appl.if_count;
		gbl_args->thread[i].stats = &stats[i];

		odp_cpumask_zero(&thd_mask);
		odp_cpumask_set(&thd_mask, cpu);
		odph_linux_pthread_create(&thread_tbl[i], &thd_mask,
					  thr_run_func,
					  &gbl_args->thread[i],
					  ODP_THREAD_WORKER);
		cpu = odp_cpumask_next(&cpumask, cpu);
	}

	/* Start packet receive and transmit */
	for (i = 0; i < gbl_args->appl.if_count; ++i) {
		pktio = gbl_args->pktios[i];
		ret   = odp_pktio_start(pktio);
		if (ret) {
			LOG_ERR("Error: unable to start %s\n",
				gbl_args->appl.if_names[i]);
			exit(EXIT_FAILURE);
		}
	}

	ret = print_speed_stats(num_workers, stats, gbl_args->appl.time,
				gbl_args->appl.accuracy);
	exit_threads = 1;

	/* Master thread waits for other threads to exit */
	odph_linux_pthread_join(thread_tbl, num_workers);

	free(gbl_args->appl.if_names);
	free(gbl_args->appl.if_str);
	printf("Exit\n\n");

	return ret;
}
Пример #13
0
void pktio_test_send_failure(void)
{
	odp_pktio_t pktio_tx, pktio_rx;
	odp_packet_t pkt_tbl[TX_BATCH_LEN];
	uint32_t pkt_seq[TX_BATCH_LEN];
	int ret, mtu, i, alloc_pkts;
	odp_pool_param_t pool_params;
	odp_pool_t pkt_pool;
	int long_pkt_idx = TX_BATCH_LEN / 2;
	pktio_info_t info_rx;

	pktio_tx = create_pktio(0, ODP_PKTIN_MODE_RECV,
				ODP_PKTOUT_MODE_SEND);
	if (pktio_tx == ODP_PKTIO_INVALID) {
		CU_FAIL("failed to open pktio");
		return;
	}

	/* read the MTU from the transmit interface */
	mtu = odp_pktio_mtu(pktio_tx);

	ret = odp_pktio_start(pktio_tx);
	CU_ASSERT_FATAL(ret == 0);

	/* configure the pool so that we can generate test packets larger
	 * than the interface MTU */
	memset(&pool_params, 0, sizeof(pool_params));
	pool_params.pkt.len     = mtu + 32;
	pool_params.pkt.seg_len = pool_params.pkt.len;
	pool_params.pkt.num     = TX_BATCH_LEN + 1;
	pool_params.type        = ODP_POOL_PACKET;
	pkt_pool = odp_pool_create("pkt_pool_oversize", &pool_params);
	CU_ASSERT_FATAL(pkt_pool != ODP_POOL_INVALID);

	if (num_ifaces > 1) {
		pktio_rx = create_pktio(1, ODP_PKTIN_MODE_RECV,
					ODP_PKTOUT_MODE_SEND);
		ret = odp_pktio_start(pktio_rx);
		CU_ASSERT_FATAL(ret == 0);
	} else {
		pktio_rx = pktio_tx;
	}

	/* generate a batch of packets with a single overly long packet
	 * in the middle */
	for (i = 0; i < TX_BATCH_LEN; ++i) {
		uint32_t pkt_len;

		if (i == long_pkt_idx)
			pkt_len = pool_params.pkt.len;
		else
			pkt_len = PKT_LEN_NORMAL;

		pkt_tbl[i] = odp_packet_alloc(pkt_pool, pkt_len);
		if (pkt_tbl[i] == ODP_PACKET_INVALID)
			break;

		pkt_seq[i] = pktio_init_packet(pkt_tbl[i]);

		pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx);
		if (pktio_fixup_checksums(pkt_tbl[i]) != 0) {
			odp_packet_free(pkt_tbl[i]);
			break;
		}

		if (pkt_seq[i] == TEST_SEQ_INVALID) {
			odp_packet_free(pkt_tbl[i]);
			break;
		}
	}
	alloc_pkts = i;

	if (alloc_pkts == TX_BATCH_LEN) {
		/* try to send the batch with the long packet in the middle,
		 * the initial short packets should be sent successfully */
		odp_errno_zero();
		ret = odp_pktio_send(pktio_tx, pkt_tbl, TX_BATCH_LEN);
		CU_ASSERT(ret == long_pkt_idx);
		CU_ASSERT(odp_errno() == 0);

		info_rx.id   = pktio_rx;
		info_rx.outq = ODP_QUEUE_INVALID;
		info_rx.inq  = ODP_QUEUE_INVALID;
		info_rx.in_mode = ODP_PKTIN_MODE_RECV;

		for (i = 0; i < ret; ++i) {
			pkt_tbl[i] = wait_for_packet(&info_rx, pkt_seq[i],
						     ODP_TIME_SEC_IN_NS);
			if (pkt_tbl[i] == ODP_PACKET_INVALID)
				break;
		}

		if (i == ret) {
			/* now try to send starting with the too-long packet
			 * and verify it fails */
			odp_errno_zero();
			ret = odp_pktio_send(pktio_tx,
					     &pkt_tbl[long_pkt_idx],
					     TX_BATCH_LEN - long_pkt_idx);
			CU_ASSERT(ret == -1);
			CU_ASSERT(odp_errno() != 0);
		} else {
			CU_FAIL("failed to receive transmitted packets\n");
		}

		/* now reduce the size of the long packet and attempt to send
		 * again - should work this time */
		i = long_pkt_idx;
		odp_packet_pull_tail(pkt_tbl[i],
				     odp_packet_len(pkt_tbl[i]) -
				     PKT_LEN_NORMAL);
		pkt_seq[i] = pktio_init_packet(pkt_tbl[i]);

		pktio_pkt_set_macs(pkt_tbl[i], pktio_tx, pktio_rx);
		ret = pktio_fixup_checksums(pkt_tbl[i]);
		CU_ASSERT_FATAL(ret == 0);

		CU_ASSERT_FATAL(pkt_seq[i] != TEST_SEQ_INVALID);
		ret = odp_pktio_send(pktio_tx, &pkt_tbl[i], TX_BATCH_LEN - i);
		CU_ASSERT_FATAL(ret == (TX_BATCH_LEN - i));

		for (; i < TX_BATCH_LEN; ++i) {
			pkt_tbl[i] = wait_for_packet(&info_rx,
						     pkt_seq[i],
						     ODP_TIME_SEC_IN_NS);
			if (pkt_tbl[i] == ODP_PACKET_INVALID)
				break;
		}
		CU_ASSERT(i == TX_BATCH_LEN);
	} else {
		CU_FAIL("failed to generate test packets\n");
	}

	for (i = 0; i < alloc_pkts; ++i) {
		if (pkt_tbl[i] != ODP_PACKET_INVALID)
			odp_packet_free(pkt_tbl[i]);
	}

	if (pktio_rx != pktio_tx)
		CU_ASSERT(odp_pktio_close(pktio_rx) == 0);
	CU_ASSERT(odp_pktio_close(pktio_tx) == 0);
	CU_ASSERT(odp_pool_destroy(pkt_pool) == 0);
}
Пример #14
0
void pktio_test_start_stop(void)
{
	odp_pktio_t pktio[MAX_NUM_IFACES];
	odp_packet_t pkt;
	odp_event_t tx_ev[100];
	odp_event_t ev;
	int i, pkts, ret, alloc = 0;
	odp_queue_t outq;
	uint64_t wait = odp_schedule_wait_time(ODP_TIME_MSEC_IN_NS);

	for (i = 0; i < num_ifaces; i++) {
		pktio[i] = create_pktio(i, ODP_PKTIN_MODE_SCHED,
					ODP_PKTOUT_MODE_SEND);
		CU_ASSERT_FATAL(pktio[i] != ODP_PKTIO_INVALID);
		create_inq(pktio[i],  ODP_QUEUE_TYPE_SCHED);
	}

	outq = odp_pktio_outq_getdef(pktio[0]);

	/* Interfaces are stopped by default,
	 * Check that stop when stopped generates an error */
	ret = odp_pktio_stop(pktio[0]);
	CU_ASSERT(ret <= 0);

	/* start first */
	ret = odp_pktio_start(pktio[0]);
	CU_ASSERT(ret == 0);
	/* Check that start when started generates an error */
	ret = odp_pktio_start(pktio[0]);
	CU_ASSERT(ret < 0);

	/* Test Rx on a stopped interface. Only works if there are 2 */
	if (num_ifaces > 1) {
		for (alloc = 0; alloc < 100; alloc++) {
			pkt = odp_packet_alloc(default_pkt_pool, packet_len);
			if (pkt == ODP_PACKET_INVALID)
				break;
			pktio_init_packet(pkt);

			pktio_pkt_set_macs(pkt, pktio[0], pktio[1]);
			if (pktio_fixup_checksums(pkt) != 0) {
				odp_packet_free(pkt);
				break;
			}

			tx_ev[alloc] = odp_packet_to_event(pkt);
		}

		for (pkts = 0; pkts != alloc; ) {
			ret = odp_queue_enq_multi(outq, &tx_ev[pkts],
						  alloc - pkts);
			if (ret < 0) {
				CU_FAIL("unable to enqueue packet\n");
				break;
			}
			pkts += ret;
		}
		/* check that packets did not arrive */
		for (i = 0, pkts = 0; i < 1000; i++) {
			ev = odp_schedule(NULL, wait);
			if (ev == ODP_EVENT_INVALID)
				continue;

			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
				pkt = odp_packet_from_event(ev);
				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
					pkts++;
			}
			odp_event_free(ev);
		}
		if (pkts)
			CU_FAIL("pktio stopped, received unexpected events");

		/* start both, send and get packets */
		/* 0 already started */
		ret = odp_pktio_start(pktio[1]);
		CU_ASSERT(ret == 0);

		/* flush packets with magic number in pipes */
		for (i = 0; i < 1000; i++) {
			ev = odp_schedule(NULL, wait);
			if (ev != ODP_EVENT_INVALID)
				odp_event_free(ev);
		}
	}

	/* alloc */
	for (alloc = 0; alloc < 100; alloc++) {
		pkt = odp_packet_alloc(default_pkt_pool, packet_len);
		if (pkt == ODP_PACKET_INVALID)
			break;
		pktio_init_packet(pkt);
		if (num_ifaces > 1) {
			pktio_pkt_set_macs(pkt, pktio[0], pktio[1]);
			if (pktio_fixup_checksums(pkt) != 0) {
				odp_packet_free(pkt);
				break;
			}
		}
		tx_ev[alloc] = odp_packet_to_event(pkt);
	}

	/* send */
	for (pkts = 0; pkts != alloc; ) {
		ret = odp_queue_enq_multi(outq, &tx_ev[pkts], alloc - pkts);
		if (ret < 0) {
			CU_FAIL("unable to enqueue packet\n");
			break;
		}
		pkts += ret;
	}

	/* get */
	for (i = 0, pkts = 0; i < 100; i++) {
		ev = odp_schedule(NULL, wait);
		if (ev != ODP_EVENT_INVALID) {
			if (odp_event_type(ev) == ODP_EVENT_PACKET) {
				pkt = odp_packet_from_event(ev);
				if (pktio_pkt_seq(pkt) != TEST_SEQ_INVALID)
					pkts++;
			}
			odp_event_free(ev);
		}
	}
	CU_ASSERT(pkts == alloc);

	for (i = 0; i < num_ifaces; i++) {
		CU_ASSERT(odp_pktio_stop(pktio[i]) == 0);
		destroy_inq(pktio[i]);
		CU_ASSERT(odp_pktio_close(pktio[i]) == 0);
	}
}
Пример #15
0
int main(int argc, char **argv)
{
	odph_odpthread_t thread_tbl[MAX_WORKERS];
	int i, j;
	int cpu;
	int num_workers;
	odp_shm_t shm;
	odp_cpumask_t cpumask;
	char cpumaskstr[ODP_CPUMASK_STR_SIZE];
	odp_pool_param_t params;
	int ret;
	stats_t (*stats)[MAX_PKTIOS];
	int if_count;
	odp_instance_t instance;
	odph_odpthread_params_t thr_params;

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

	/* Init this thread */
	if (odp_init_local(instance, ODP_THREAD_CONTROL)) {
		printf("Error: ODP local init failed.\n");
		exit(EXIT_FAILURE);
	}

	/* Reserve memory for args from shared mem */
	shm = odp_shm_reserve("shm_args", sizeof(args_t),
			      ODP_CACHE_LINE_SIZE, 0);
	gbl_args = odp_shm_addr(shm);

	if (gbl_args == NULL) {
		printf("Error: shared mem alloc failed.\n");
		exit(EXIT_FAILURE);
	}
	gbl_args_init(gbl_args);

	for (i = 0; (unsigned)i < MAC_TBL_SIZE; i++)
		odp_atomic_init_u64(&gbl_args->mac_tbl[i], 0);

	/* Parse and store the application arguments */
	parse_args(argc, argv, &gbl_args->appl);

	/* Print both system and application information */
	print_info(NO_PATH(argv[0]), &gbl_args->appl);

	/* Default to system CPU count unless user specified */
	num_workers = MAX_WORKERS;
	if (gbl_args->appl.cpu_count)
		num_workers = gbl_args->appl.cpu_count;

	/* Get default worker cpumask */
	num_workers = odp_cpumask_default_worker(&cpumask, num_workers);
	(void)odp_cpumask_to_str(&cpumask, cpumaskstr, sizeof(cpumaskstr));

	gbl_args->appl.num_workers = num_workers;

	if_count = gbl_args->appl.if_count;

	printf("num worker threads: %i\n", num_workers);
	printf("first CPU:          %i\n", odp_cpumask_first(&cpumask));
	printf("cpu mask:           %s\n", cpumaskstr);

	/* Create packet pool */
	odp_pool_param_init(&params);
	params.pkt.seg_len = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.len     = SHM_PKT_POOL_BUF_SIZE;
	params.pkt.num     = SHM_PKT_POOL_SIZE;
	params.type        = ODP_POOL_PACKET;

	gbl_args->pool = odp_pool_create("packet pool", &params);
	if (gbl_args->pool == ODP_POOL_INVALID) {
		printf("Error: packet pool create failed.\n");
		exit(EXIT_FAILURE);
	}
	odp_pool_print(gbl_args->pool);

	bind_workers();

	for (i = 0; i < if_count; ++i) {
		const char *dev = gbl_args->appl.if_names[i];
		int num_rx;

		/* An RX queue per assigned worker and a private TX queue for
		 * each worker */
		num_rx = gbl_args->pktios[i].num_rx_thr;

		if (create_pktio(dev, i, num_rx, num_workers, gbl_args->pool))
			exit(EXIT_FAILURE);

		ret = odp_pktio_promisc_mode_set(gbl_args->pktios[i].pktio, 1);
		if (ret != 0) {
			printf("Error: failed to set port to promiscuous mode.\n");
			exit(EXIT_FAILURE);
		}
	}
	gbl_args->pktios[i].pktio = ODP_PKTIO_INVALID;

	bind_queues();

	print_port_mapping();

	memset(thread_tbl, 0, sizeof(thread_tbl));

	odp_barrier_init(&barrier, num_workers + 1);

	stats = gbl_args->stats;

	memset(&thr_params, 0, sizeof(thr_params));
	thr_params.thr_type = ODP_THREAD_WORKER;
	thr_params.instance = instance;
	thr_params.start    = run_worker;

	/* Create worker threads */
	cpu = odp_cpumask_first(&cpumask);
	for (i = 0; i < num_workers; ++i) {
		odp_cpumask_t thd_mask;

		for (j = 0; j < MAX_PKTIOS; j++)
			gbl_args->thread[i].stats[j] = &stats[i][j];

		thr_params.arg      = &gbl_args->thread[i];

		odp_cpumask_zero(&thd_mask);
		odp_cpumask_set(&thd_mask, cpu);
		odph_odpthreads_create(&thread_tbl[i], &thd_mask, &thr_params);
		cpu = odp_cpumask_next(&cpumask, cpu);
	}

	/* Start packet receive and transmit */
	for (i = 0; i < if_count; ++i) {
		odp_pktio_t pktio;

		pktio = gbl_args->pktios[i].pktio;
		ret   = odp_pktio_start(pktio);
		if (ret) {
			printf("Error: unable to start %s\n",
			       gbl_args->appl.if_names[i]);
			exit(EXIT_FAILURE);
		}
	}

	ret = print_speed_stats(num_workers, gbl_args->stats,
				gbl_args->appl.time, gbl_args->appl.accuracy);
	exit_threads = 1;

	/* Master thread waits for other threads to exit */
	for (i = 0; i < num_workers; ++i)
		odph_odpthreads_join(&thread_tbl[i]);

	free(gbl_args->appl.if_names);
	free(gbl_args->appl.if_str);

	if (odp_pool_destroy(gbl_args->pool)) {
		printf("Error: pool destroy\n");
		exit(EXIT_FAILURE);
	}

	if (odp_term_local()) {
		printf("Error: term local\n");
		exit(EXIT_FAILURE);
	}

	if (odp_term_global(instance)) {
		printf("Error: term global\n");
		exit(EXIT_FAILURE);
	}

	printf("Exit: %d\n\n", ret);
	return ret;
}
Пример #16
0
static int test_init(void)
{
	odp_pool_param_t params;
	odp_queue_param_t qparam;
	odp_queue_t inq_def;
	const char *iface;
	int schedule;
	char inq_name[ODP_QUEUE_NAME_LEN];

	odp_pool_param_init(&params);
	params.pkt.len     = PKT_HDR_LEN + gbl_args->args.pkt_len;
	params.pkt.seg_len = params.pkt.len;
	params.pkt.num     = PKT_BUF_NUM;
	params.type        = ODP_POOL_PACKET;

	transmit_pkt_pool = odp_pool_create("pkt_pool_transmit", &params);
	if (transmit_pkt_pool == ODP_POOL_INVALID)
		LOG_ABORT("Failed to create transmit pool\n");

	odp_atomic_init_u32(&ip_seq, 0);
	odp_atomic_init_u32(&shutdown, 0);

	iface    = gbl_args->args.ifaces[0];
	schedule = gbl_args->args.schedule;

	/* create pktios and associate input/output queues */
	gbl_args->pktio_tx = create_pktio(iface, schedule);
	if (gbl_args->args.num_ifaces > 1) {
		iface = gbl_args->args.ifaces[1];
		gbl_args->pktio_rx = create_pktio(iface, schedule);
	} else {
		gbl_args->pktio_rx = gbl_args->pktio_tx;
	}

	odp_pktio_mac_addr(gbl_args->pktio_tx, gbl_args->src_mac,
			   ODPH_ETHADDR_LEN);
	odp_pktio_mac_addr(gbl_args->pktio_rx, gbl_args->dst_mac,
			   ODPH_ETHADDR_LEN);

	if (gbl_args->pktio_rx == ODP_PKTIO_INVALID ||
	    gbl_args->pktio_tx == ODP_PKTIO_INVALID) {
		LOG_ERR("failed to open pktio\n");
		return -1;
	}

	/* create and associate an input queue for the RX side */
	odp_queue_param_init(&qparam);
	qparam.sched.prio  = ODP_SCHED_PRIO_DEFAULT;
	qparam.sched.sync  = ODP_SCHED_SYNC_NONE;
	qparam.sched.group = ODP_SCHED_GROUP_ALL;

	snprintf(inq_name, sizeof(inq_name), "inq-pktio-%" PRIu64,
		 odp_pktio_to_u64(gbl_args->pktio_rx));
	inq_def = odp_queue_lookup(inq_name);
	if (inq_def == ODP_QUEUE_INVALID)
		inq_def = odp_queue_create(inq_name,
				ODP_QUEUE_TYPE_PKTIN, &qparam);

	if (inq_def == ODP_QUEUE_INVALID)
		return -1;

	if (odp_pktio_inq_setdef(gbl_args->pktio_rx, inq_def) != 0)
		return -1;

	if (odp_pktio_start(gbl_args->pktio_tx) != 0)
		return -1;
	if (gbl_args->args.num_ifaces > 1 &&
	    odp_pktio_start(gbl_args->pktio_rx))
		return -1;

	return 0;
}