static int setup_test() { odp_pool_param_t params; odp_pktio_param_t pktio_param = {0}; odp_pktio_t tmp; memset(¶ms, 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, ¶ms); 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; }
/* * This is a pre-condition check that the pktio_test_send_failure() * test case can be run. If the TX interface MTU is larger that the * biggest packet we can allocate then the test won't be able to * attempt to send packets larger than the MTU, so skip the test. */ int pktio_check_send_failure(void) { odp_pktio_t pktio_tx; int mtu; odp_pktio_param_t pktio_param; int iface_idx = 0; const char *iface = iface_name[iface_idx]; memset(&pktio_param, 0, sizeof(pktio_param)); pktio_param.in_mode = ODP_PKTIN_MODE_RECV; pktio_tx = odp_pktio_open(iface, pool[iface_idx], &pktio_param); if (pktio_tx == ODP_PKTIO_INVALID) { fprintf(stderr, "%s: failed to open pktio\n", __func__); return 0; } /* read the MTU from the transmit interface */ mtu = odp_pktio_mtu(pktio_tx); odp_pktio_close(pktio_tx); return (mtu <= ODP_CONFIG_PACKET_BUF_LEN_MAX - 32); }
static odp_pktio_t create_pktio(int iface_idx, odp_pktio_input_mode_t imode, odp_pktio_output_mode_t omode) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; const char *iface = iface_name[iface_idx]; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = imode; pktio_param.out_mode = omode; pktio = odp_pktio_open(iface, pool[iface_idx], &pktio_param); if (pktio == ODP_PKTIO_INVALID) pktio = odp_pktio_lookup(iface); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_to_u64(pktio) != odp_pktio_to_u64(ODP_PKTIO_INVALID)); /* Print pktio debug info and test that the odp_pktio_print() function * is implemented. */ if (pktio != ODP_PKTIO_INVALID) odp_pktio_print(pktio); if (wait_for_network) spin_wait(ODP_TIME_SEC_IN_NS / 4); return pktio; }
/** * Create a pktio handle, optionally associating a default input queue. * * @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. * @retval ODP_PKTIO_INVALID if the create fails. */ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool) { char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; odp_queue_t inq_def; odp_pktio_t pktio; int ret; odp_pktio_param_t pktio_param; odp_schedule_sync_t sync_mode; odp_pktio_param_init(&pktio_param); if (gbl_args->appl.mode == DIRECT_RECV) pktio_param.in_mode = ODP_PKTIN_MODE_RECV; else pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) { LOG_ERR("Error: failed to open %s\n", dev); return ODP_PKTIO_INVALID; } printf("created pktio %" PRIu64 " (%s)\n", odp_pktio_to_u64(pktio), dev); /* no further setup needed for direct receive mode */ if (gbl_args->appl.mode == DIRECT_RECV) return pktio; if (gbl_args->appl.mode == SCHED_ATOMIC) sync_mode = ODP_SCHED_SYNC_ATOMIC; else if (gbl_args->appl.mode == SCHED_ORDERED) sync_mode = ODP_SCHED_SYNC_ORDERED; else sync_mode = ODP_SCHED_SYNC_NONE; odp_queue_param_init(&qparam); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = sync_mode; 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) { LOG_ERR("Error: pktio queue creation failed\n"); return ODP_PKTIO_INVALID; } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) { LOG_ERR("Error: default input-Q setup\n"); return ODP_PKTIO_INVALID; } return pktio; }
static int run_test(void) { int ret = 1; int i; odp_cpumask_t txmask, rxmask; test_status_t status = { .pps_curr = gbl_args->args.pps, .pps_pass = 0, .pps_fail = 0, }; if (setup_txrx_masks(&txmask, &rxmask) != 0) return -1; printf("Starting test with params:\n"); printf("\tTransmit workers: \t%d\n", odp_cpumask_count(&txmask)); printf("\tReceive workers: \t%d\n", odp_cpumask_count(&rxmask)); printf("\tDuration (seconds): \t%d\n", gbl_args->args.duration); printf("\tTransmit batch length:\t%" PRIu32 "\n", gbl_args->args.tx_batch_len); printf("\tReceive batch length: \t%" PRIu32 "\n", gbl_args->args.rx_batch_len); printf("\tPacket receive method:\t%s\n", gbl_args->args.schedule ? "schedule" : "poll"); printf("\tInterface(s): \t"); for (i = 0; i < gbl_args->args.num_ifaces; ++i) printf("%s ", gbl_args->args.ifaces[i]); printf("\n"); while (ret > 0) ret = run_test_single(&txmask, &rxmask, &status); return ret; } static odp_pktio_t create_pktio(const char *iface) { odp_pool_t pool; odp_pktio_t pktio; char pool_name[ODP_POOL_NAME_LEN]; odp_pool_param_t params; memset(¶ms, 0, sizeof(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; snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", iface); pool = odp_pool_create(pool_name, ODP_SHM_NULL, ¶ms); if (pool == ODP_POOL_INVALID) return ODP_PKTIO_INVALID; pktio = odp_pktio_open(iface, pool); return pktio; }
int classification_suite_init(void) { odp_pool_t pool; odp_pool_param_t param; odp_queue_t inq_def; odp_queue_param_t qparam; char queuename[ODP_QUEUE_NAME_LEN]; int i; int ret; memset(¶m, 0, sizeof(param)); param.pkt.seg_len = SHM_PKT_BUF_SIZE; param.pkt.len = SHM_PKT_BUF_SIZE; param.pkt.num = SHM_PKT_NUM_BUFS; param.type = ODP_POOL_PACKET; pool = odp_pool_create("classification_pool", ¶m); if (ODP_POOL_INVALID == pool) { fprintf(stderr, "Packet pool creation failed.\n"); return -1; } pool_default = odp_pool_lookup("classification_pool"); if (pool_default == ODP_POOL_INVALID) return -1; pktio_loop = odp_pktio_open("loop", pool_default); if (pktio_loop == ODP_PKTIO_INVALID) { ret = odp_pool_destroy(pool_default); if (ret) fprintf(stderr, "unable to destroy pool.\n"); return -1; } qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; sprintf(queuename, "%s", "inq_loop"); inq_def = odp_queue_create(queuename, ODP_QUEUE_TYPE_PKTIN, &qparam); odp_pktio_inq_setdef(pktio_loop, inq_def); for (i = 0; i < CLS_ENTRIES; i++) cos_list[i] = ODP_COS_INVALID; for (i = 0; i < CLS_ENTRIES; i++) pmr_list[i] = ODP_PMR_INVAL; for (i = 0; i < CLS_ENTRIES; i++) queue_list[i] = ODP_QUEUE_INVALID; odp_atomic_init_u32(&seq, 0); return 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; }
void pktio_test_lookup(void) { odp_pktio_t pktio, pktio_inval; odp_pktio_param_t pktio_param; odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open(iface_name[0], default_pkt_pool, &pktio_param); CU_ASSERT(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_lookup(iface_name[0]) == pktio); pktio_inval = odp_pktio_open(iface_name[0], default_pkt_pool, &pktio_param); CU_ASSERT(odp_errno() != 0); CU_ASSERT(pktio_inval == ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); CU_ASSERT(odp_pktio_lookup(iface_name[0]) == ODP_PKTIO_INVALID); }
/** * 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; }
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, ¶m); 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; }
/** * Create a pktio handle, optionally associating a default input queue. * * @param dev Name of device to open * @param pool Pool to associate with device for packet RX/TX * @param mode Packet processing mode for this device (BURST or QUEUE) * * @return The handle of the created pktio object. * @retval ODP_PKTIO_INVALID if the create fails. */ static odp_pktio_t create_pktio(const char *dev, odp_pool_t pool, int mode) { char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; odp_queue_t inq_def; odp_pktio_t pktio; int ret; pktio = odp_pktio_open(dev, pool); if (pktio == ODP_PKTIO_INVALID) { LOG_ERR("Error: failed to open %s\n", dev); return ODP_PKTIO_INVALID; } printf("created pktio %" PRIu64 " (%s)\n", odp_pktio_to_u64(pktio), dev); /* no further setup needed for burst mode */ if (mode == APPL_MODE_PKT_BURST) return pktio; qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; 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) { LOG_ERR("Error: pktio queue creation failed\n"); return ODP_PKTIO_INVALID; } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) { LOG_ERR("Error: default input-Q setup\n"); return ODP_PKTIO_INVALID; } return pktio; }
void pktio_test_open(void) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; int i; /* test the sequence open->close->open->close() */ for (i = 0; i < 2; ++i) { pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED, ODP_PKTOUT_MODE_SEND); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); CU_ASSERT(odp_pktio_close(pktio) == 0); } odp_pktio_param_init(&pktio_param); pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; pktio = odp_pktio_open("nothere", default_pkt_pool, &pktio_param); CU_ASSERT(pktio == ODP_PKTIO_INVALID); }
/** * 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); }
/** * 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); }
/** * Packet IO loopback worker thread using ODP queues * * @param arg thread arguments of type 'thread_args_t *' */ static void *pktio_queue_thread(void *arg) { int thr; odp_buffer_pool_t pkt_pool; odp_pktio_t pktio; thread_args_t *thr_args; odp_queue_t outq_def; odp_queue_t inq_def; char inq_name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; odp_packet_t pkt; odp_buffer_t buf; int ret; unsigned long pkt_cnt = 0; unsigned long err_cnt = 0; odp_pktio_params_t params; socket_params_t *sock_params = ¶ms.sock_params; thr = odp_thread_id(); thr_args = arg; printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr, thr_args->pktio_dev); /* Lookup the packet pool */ pkt_pool = odp_buffer_pool_lookup("packet_pool"); if (pkt_pool == ODP_BUFFER_POOL_INVALID || pkt_pool != thr_args->pool) { ODP_ERR(" [%02i] Error: pkt_pool not found\n", thr); return NULL; } /* Open a packet IO instance for this thread */ sock_params->type = thr_args->type; sock_params->fanout = thr_args->fanout; pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, ¶ms); if (pktio == ODP_PKTIO_INVALID) { ODP_ERR(" [%02i] Error: pktio create failed\n", thr); return NULL; } /* * Create and set the default INPUT queue associated with the 'pktio' * resource */ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_ATOMIC; qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; snprintf(inq_name, sizeof(inq_name), "%i-pktio_inq_def", (int)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) { ODP_ERR(" [%02i] Error: pktio queue creation failed\n", thr); return NULL; } ret = odp_pktio_inq_setdef(pktio, inq_def); if (ret != 0) { ODP_ERR(" [%02i] Error: default input-Q setup\n", thr); return NULL; } printf(" [%02i] created pktio:%02i, queue mode (ATOMIC queues)\n" " default pktio%02i-INPUT queue:%u\n", thr, pktio, pktio, inq_def); /* Loop packets */ for (;;) { odp_pktio_t pktio_tmp; #if 1 /* Use schedule to get buf from any input queue */ buf = odp_schedule(NULL, ODP_SCHED_WAIT); #else /* Always dequeue from the same input queue */ buf = odp_queue_deq(inq_def); if (!odp_buffer_is_valid(buf)) continue; #endif pkt = odp_packet_from_buffer(buf); /* Drop packets with errors */ if (odp_unlikely(drop_err_pkts(&pkt, 1) == 0)) { ODP_ERR("Drop frame - err_cnt:%lu\n", ++err_cnt); continue; } pktio_tmp = odp_pktio_get_input(pkt); outq_def = odp_pktio_outq_getdef(pktio_tmp); if (outq_def == ODP_QUEUE_INVALID) { ODP_ERR(" [%02i] Error: def output-Q query\n", thr); return NULL; } /* Swap Eth MACs and possibly IP-addrs before sending back */ swap_pkt_addrs(&pkt, 1); /* Enqueue the packet for output */ odp_queue_enq(outq_def, buf); /* Print packet counts every once in a while */ if (odp_unlikely(pkt_cnt++ % 100000 == 0)) { printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); fflush(NULL); } } /* unreachable */ }
/** * Packet IO loopback worker thread using bursts from/to IO resources * * @param arg thread arguments of type 'thread_args_t *' */ static void *pktio_ifburst_thread(void *arg) { int thr; odp_buffer_pool_t pkt_pool; odp_pktio_t pktio; thread_args_t *thr_args; int pkts, pkts_ok; odp_packet_t pkt_tbl[MAX_PKT_BURST]; unsigned long pkt_cnt = 0; unsigned long err_cnt = 0; unsigned long tmp = 0; odp_pktio_params_t params; socket_params_t *sock_params = ¶ms.sock_params; thr = odp_thread_id(); thr_args = arg; printf("Pktio thread [%02i] starts, pktio_dev:%s\n", thr, thr_args->pktio_dev); /* Lookup the packet pool */ pkt_pool = odp_buffer_pool_lookup("packet_pool"); if (pkt_pool == ODP_BUFFER_POOL_INVALID || pkt_pool != thr_args->pool) { ODP_ERR(" [%02i] Error: pkt_pool not found\n", thr); return NULL; } /* Open a packet IO instance for this thread */ sock_params->type = thr_args->type; sock_params->fanout = thr_args->fanout; pktio = odp_pktio_open(thr_args->pktio_dev, pkt_pool, ¶ms); if (pktio == ODP_PKTIO_INVALID) { ODP_ERR(" [%02i] Error: pktio create failed.\n", thr); return NULL; } printf(" [%02i] created pktio:%02i, burst mode\n", thr, pktio); /* Loop packets */ for (;;) { pkts = odp_pktio_recv(pktio, pkt_tbl, MAX_PKT_BURST); if (pkts > 0) { /* Drop packets with errors */ pkts_ok = drop_err_pkts(pkt_tbl, pkts); if (pkts_ok > 0) { /* Swap Eth MACs and IP-addrs */ swap_pkt_addrs(pkt_tbl, pkts_ok); odp_pktio_send(pktio, pkt_tbl, pkts_ok); } if (odp_unlikely(pkts_ok != pkts)) ODP_ERR("Dropped frames:%u - err_cnt:%lu\n", pkts-pkts_ok, ++err_cnt); /* Print packet counts every once in a while */ tmp += pkts_ok; if (odp_unlikely((tmp >= 100000) || /* OR first print:*/ ((pkt_cnt == 0) && ((tmp-1) < MAX_PKT_BURST)))) { pkt_cnt += tmp; printf(" [%02i] pkt_cnt:%lu\n", thr, pkt_cnt); fflush(NULL); tmp = 0; } } } /* unreachable */ }
/** * Create a pktio handle * * @param dev Name of device to open * @param index Pktio index * @param num_rx Number of RX queues * @param num_tx Number of TX queues * @param pool Pool to associate with device for packet RX/TX * * @retval 0 on success * @retval -1 on failure */ static int create_pktio(const char *dev, int idx, int num_rx, int num_tx, odp_pool_t pool) { odp_pktio_t pktio; odp_pktio_param_t pktio_param; odp_pktio_capability_t capa; odp_pktin_queue_param_t pktin_param; odp_pktout_queue_param_t pktout_param; odp_pktio_op_mode_t mode_rx; odp_pktio_op_mode_t mode_tx; odp_pktio_param_init(&pktio_param); pktio = odp_pktio_open(dev, pool, &pktio_param); if (pktio == ODP_PKTIO_INVALID) { printf("Error: failed to open %s\n", dev); return -1; } printf("created pktio %" PRIu64 " (%s)\n", odp_pktio_to_u64(pktio), dev); if (odp_pktio_capability(pktio, &capa)) { printf("Error: capability query failed %s\n", dev); return -1; } odp_pktin_queue_param_init(&pktin_param); odp_pktout_queue_param_init(&pktout_param); mode_tx = ODP_PKTIO_OP_MT_UNSAFE; mode_rx = ODP_PKTIO_OP_MT_UNSAFE; if (num_rx > (int)capa.max_input_queues) { printf("Sharing %i input queues between %i workers\n", capa.max_input_queues, num_rx); num_rx = capa.max_input_queues; mode_rx = ODP_PKTIO_OP_MT; } if (num_tx > (int)capa.max_output_queues) { printf("Sharing %i output queues between %i workers\n", capa.max_output_queues, num_tx); num_tx = capa.max_output_queues; mode_tx = ODP_PKTIO_OP_MT; } pktin_param.hash_enable = 1; pktin_param.hash_proto.proto.ipv4 = 1; pktin_param.hash_proto.proto.ipv4_tcp = 1; pktin_param.hash_proto.proto.ipv4_udp = 1; pktin_param.num_queues = num_rx; pktin_param.op_mode = mode_rx; pktout_param.op_mode = mode_tx; pktout_param.num_queues = num_tx; if (odp_pktin_queue_config(pktio, &pktin_param)) { printf("Error: input queue config failed %s\n", dev); return -1; } if (odp_pktout_queue_config(pktio, &pktout_param)) { printf("Error: output queue config failed %s\n", dev); return -1; } if (odp_pktin_queue(pktio, gbl_args->pktios[idx].pktin, num_rx) != num_rx) { printf("Error: pktin queue query failed %s\n", dev); return -1; } if (odp_pktout_queue(pktio, gbl_args->pktios[idx].pktout, num_tx) != num_tx) { printf("Error: pktout queue query failed %s\n", dev); return -1; } printf("created %i input and %i output queues on (%s)\n", num_rx, num_tx, dev); gbl_args->pktios[idx].num_rx_queue = num_rx; gbl_args->pktios[idx].num_tx_queue = num_tx; gbl_args->pktios[idx].pktio = pktio; return 0; }
static int run_test(void) { int ret; int i; odp_cpumask_t txmask, rxmask; test_status_t status = { .pps_curr = gbl_args->args.pps, .pps_pass = 0, .pps_fail = 0, .warmup = 1, }; ret = setup_txrx_masks(&txmask, &rxmask); if (ret) return ret; printf("Starting test with params:\n"); printf("\tTransmit workers: \t%d\n", odp_cpumask_count(&txmask)); printf("\tReceive workers: \t%d\n", odp_cpumask_count(&rxmask)); printf("\tDuration (seconds): \t%d\n", gbl_args->args.duration); printf("\tTransmit batch length:\t%" PRIu32 "\n", gbl_args->args.tx_batch_len); printf("\tReceive batch length: \t%" PRIu32 "\n", gbl_args->args.rx_batch_len); printf("\tPacket receive method:\t%s\n", gbl_args->args.schedule ? "schedule" : "plain"); printf("\tInterface(s): \t"); for (i = 0; i < gbl_args->args.num_ifaces; ++i) printf("%s ", gbl_args->args.ifaces[i]); printf("\n"); /* first time just run the test but throw away the results */ run_test_single(&txmask, &rxmask, &status); status.warmup = 0; while (1) { ret = run_test_single(&txmask, &rxmask, &status); if (ret <= 0) break; } return ret; } static odp_pktio_t create_pktio(const char *iface, int schedule) { odp_pool_t pool; odp_pktio_t pktio; char pool_name[ODP_POOL_NAME_LEN]; odp_pool_param_t params; odp_pktio_param_t pktio_param; odp_pool_param_init(¶ms); 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; snprintf(pool_name, sizeof(pool_name), "pkt_pool_%s", iface); pool = odp_pool_create(pool_name, ¶ms); if (pool == ODP_POOL_INVALID) return ODP_PKTIO_INVALID; odp_pktio_param_init(&pktio_param); if (schedule) pktio_param.in_mode = ODP_PKTIN_MODE_SCHED; else pktio_param.in_mode = ODP_PKTIN_MODE_QUEUE; pktio = odp_pktio_open(iface, pool, &pktio_param); return pktio; }