static int test_term(void) { char pool_name[ODP_POOL_NAME_LEN]; odp_pool_t pool; int i; int ret = 0; if (gbl_args->pktio_tx != gbl_args->pktio_rx) { if (odp_pktio_stop(gbl_args->pktio_tx)) { LOG_ERR("Failed to stop pktio_tx\n"); return -1; } if (odp_pktio_close(gbl_args->pktio_tx)) { LOG_ERR("Failed to close pktio_tx\n"); ret = -1; } } empty_inq(gbl_args->pktio_rx); if (odp_pktio_stop(gbl_args->pktio_rx)) { LOG_ERR("Failed to stop pktio_rx\n"); return -1; } if (odp_pktio_close(gbl_args->pktio_rx) != 0) { LOG_ERR("Failed to close pktio_rx\n"); ret = -1; } for (i = 0; i < gbl_args->args.num_ifaces; ++i) { snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", gbl_args->args.ifaces[i]); pool = odp_pool_lookup(pool_name); if (pool == ODP_POOL_INVALID) continue; if (odp_pool_destroy(pool) != 0) { LOG_ERR("Failed to destroy pool %s\n", pool_name); ret = -1; } } if (odp_pool_destroy(transmit_pkt_pool) != 0) { LOG_ERR("Failed to destroy transmit pool\n"); ret = -1; } free(gbl_args->args.if_str); if (odp_shm_free(odp_shm_lookup("test_globals")) != 0) { LOG_ERR("Failed to free test_globals\n"); ret = -1; } return ret; }
int destroy_inq(odp_pktio_t pktio) { odp_queue_t inq; odp_event_t ev; inq = odp_pktio_inq_getdef(pktio); if (inq == ODP_QUEUE_INVALID) { CU_FAIL("attempting to destroy invalid inq"); return -1; } if (0 > odp_pktio_stop(pktio)) return -1; if (0 > odp_pktio_inq_remdef(pktio)) return -1; while (1) { ev = odp_schedule(NULL, ODP_SCHED_NO_WAIT); if (ev != ODP_EVENT_INVALID) odp_event_free(ev); else break; } return odp_queue_destroy(inq); }
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); }
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); }
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); } }
int ofp_term_global(void) { int rc = 0; uint16_t i; struct ofp_ifnet *ifnet; ofp_stop(); /* Terminate CLI thread*/ CHECK_ERROR(ofp_stop_cli_thread(), rc); #ifdef SP /* Terminate Netlink thread*/ if (shm->nl_thread_is_running) { odph_linux_pthread_join(&shm->nl_thread, 1); shm->nl_thread_is_running = 0; } #endif /* SP */ /* Cleanup interfaces: queues and pktios*/ for (i = 0; i < VXLAN_PORTS; i++) { ifnet = ofp_get_ifnet((uint16_t)i, 0); if (!ifnet) { OFP_ERR("Failed to locate interface for port %d", i); rc = -1; continue; } if (ifnet->if_state == OFP_IFT_STATE_FREE) continue; if (ifnet->pktio == ODP_PKTIO_INVALID) continue; OFP_INFO("Cleaning device '%s' addr %s", ifnet->if_name, ofp_print_mac((uint8_t *)ifnet->mac)); CHECK_ERROR(odp_pktio_stop(ifnet->pktio), rc); #ifdef SP close(ifnet->fd); odph_linux_pthread_join(ifnet->rx_tbl, 1); odph_linux_pthread_join(ifnet->tx_tbl, 1); ifnet->fd = -1; #endif /*SP*/ /* Multicasting. */ ofp_igmp_domifdetach(ifnet); ifnet->ii_inet.ii_igmp = NULL; if (ifnet->loopq_def != ODP_QUEUE_INVALID) { if (odp_queue_destroy(ifnet->loopq_def) < 0) { OFP_ERR("Failed to destroy loop queue for %s", ifnet->if_name); rc = -1; } ifnet->loopq_def = ODP_QUEUE_INVALID; } #ifdef SP if (ifnet->spq_def != ODP_QUEUE_INVALID) { cleanup_pkt_queue(ifnet->spq_def); if (odp_queue_destroy(ifnet->spq_def) < 0) { OFP_ERR("Failed to destroy slow path " "queue for %s", ifnet->if_name); rc = -1; } ifnet->spq_def = ODP_QUEUE_INVALID; } #endif /*SP*/ ifnet->outq_def = ODP_QUEUE_INVALID; if (ifnet->pktio != ODP_PKTIO_INVALID) { if (odp_pktio_close(ifnet->pktio) < 0) { OFP_ERR("Failed to destroy pktio for %s", ifnet->if_name); rc = -1; } ifnet->pktio = ODP_PKTIO_INVALID; } if (ifnet->inq_def != ODP_QUEUE_INVALID) { cleanup_pkt_queue(ifnet->inq_def); if (odp_queue_destroy(ifnet->inq_def) < 0) { OFP_ERR("Failed to destroy default input " "queue for %s", ifnet->if_name); rc = -1; } ifnet->inq_def = ODP_QUEUE_INVALID; } } CHECK_ERROR(ofp_clean_vxlan_interface_queue(), rc); if (ofp_term_post_global(SHM_PACKET_POOL_NAME)) { OFP_ERR("Failed to cleanup resources\n"); rc = -1; } return rc; }
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(¶ms, 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", ¶ms); 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; }
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); } }