/** * 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 test_init(void) { odp_pool_param_t params; odp_queue_param_t qparam; odp_queue_t inq_def; char inq_name[ODP_QUEUE_NAME_LEN]; 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; transmit_pkt_pool = odp_pool_create("pkt_pool_transmit", ODP_SHM_NULL, ¶ms); 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); /* create pktios and associate input/output queues */ gbl_args->pktio_tx = create_pktio(gbl_args->args.ifaces[0]); if (gbl_args->args.num_ifaces > 1) gbl_args->pktio_rx = create_pktio(gbl_args->args.ifaces[1]); else gbl_args->pktio_rx = gbl_args->pktio_tx; 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 */ qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_NONE; qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; 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; return 0; }
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; }
/** * 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 odp_pktio_recv(odp_pktio_t id, odp_packet_t pkt_table[], unsigned len) { pktio_entry_t *pktio_entry = get_entry(id); unsigned pkts = 0; odp_buffer_t buf; if (pktio_entry == NULL) return -1; lock_entry(pktio_entry); if (pktio_entry->s.inq_default == ODP_QUEUE_INVALID) { char name[ODP_QUEUE_NAME_LEN]; odp_queue_param_t qparam; odp_queue_t inq_def; /* * Create a default input queue. * FIXME: IT is a kind of WA for current ODP API usage. * It should be revised. */ ODP_DBG("Creating default input queue\n"); qparam.sched.prio = ODP_SCHED_PRIO_DEFAULT; qparam.sched.sync = ODP_SCHED_SYNC_NONE; qparam.sched.group = ODP_SCHED_GROUP_DEFAULT; snprintf(name, sizeof(name), "%i-pktio_inq_default", (int)id); name[ODP_QUEUE_NAME_LEN-1] = '\0'; inq_def = odp_queue_create(name, ODP_QUEUE_TYPE_PKTIN, &qparam); if (inq_def == ODP_QUEUE_INVALID) { ODP_ERR("pktio queue creation failed\n"); goto unlock; } if (odp_pktio_inq_setdef(id, inq_def)) { ODP_ERR("default input-Q setup\n"); goto unlock; } } for (pkts = 0; pkts < len; pkts++) { buf = odp_queue_deq(pktio_entry->s.inq_default); if (!odp_buffer_is_valid(buf)) break; pkt_table[pkts] = odp_packet_from_buffer(buf); } unlock: unlock_entry(pktio_entry); return pkts; }
/** * 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; }
static int create_inq(odp_pktio_t pktio, odp_queue_type_t qtype) { odp_queue_param_t qparam; odp_queue_t inq_def; char inq_name[ODP_QUEUE_NAME_LEN]; 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), "inq-pktio-%" PRIu64, odp_pktio_to_u64(pktio)); inq_def = odp_queue_lookup(inq_name); if (inq_def == ODP_QUEUE_INVALID) inq_def = odp_queue_create( inq_name, ODP_QUEUE_TYPE_PKTIN, qtype == ODP_QUEUE_TYPE_POLL ? NULL : &qparam); CU_ASSERT(inq_def != ODP_QUEUE_INVALID); return odp_pktio_inq_setdef(pktio, inq_def); }
/** * 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 */ }
int odp_pktio_inq_remdef(odp_pktio_t id) { return odp_pktio_inq_setdef(id, ODP_QUEUE_INVALID); }