/* * 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 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); } }
void pktio_test_mtu(void) { int ret; int mtu; odp_pktio_t pktio = create_pktio(0, ODP_PKTIN_MODE_SCHED, ODP_PKTOUT_MODE_SEND); CU_ASSERT_FATAL(pktio != ODP_PKTIO_INVALID); mtu = odp_pktio_mtu(pktio); CU_ASSERT(mtu > 0); printf(" %d ", mtu); ret = odp_pktio_close(pktio); CU_ASSERT(ret == 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, ¶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; }
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); }