void pktio_test_mac(void) { unsigned char mac_addr[ODPH_ETHADDR_LEN]; int mac_len; int ret; odp_pktio_t pktio; pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED, ODP_PKTOUT_MODE_SEND); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); printf("testing mac for %s\n", iface_name[0]); mac_len = odp_pktio_mac_addr(pktio, mac_addr, sizeof(mac_addr)); CU_ASSERT(ODPH_ETHADDR_LEN == mac_len); printf(" %X:%X:%X:%X:%X:%X ", mac_addr[0], mac_addr[1], mac_addr[2], mac_addr[3], mac_addr[4], mac_addr[5]); /* Fail case: wrong addr_size. Expected <0. */ mac_len = odp_pktio_mac_addr(pktio, mac_addr, 2); CU_ASSERT(mac_len < 0); ret = odp_pktio_close(pktio); CU_ASSERT(0 == ret); }
static void pktio_pkt_set_macs(odp_packet_t pkt, odp_pktio_t src, odp_pktio_t dst) { uint32_t len; odph_ethhdr_t *eth = (odph_ethhdr_t *)odp_packet_l2_ptr(pkt, &len); int ret; ret = odp_pktio_mac_addr(src, ð->src, sizeof(eth->src)); CU_ASSERT(ret == ODPH_ETHADDR_LEN); ret = odp_pktio_mac_addr(dst, ð->dst, sizeof(eth->dst)); CU_ASSERT(ret == ODPH_ETHADDR_LEN); }
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; }
/** * 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); }
static int test_init(void) { odp_pool_param_t params; const char *iface; int schedule; 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; transmit_pkt_pool = odp_pool_create("pkt_pool_transmit", ¶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); 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; }
/** * 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(¶ms); 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", ¶ms); 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; }
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(¶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; transmit_pkt_pool = odp_pool_create("pkt_pool_transmit", ¶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); 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; }