aboutsummaryrefslogtreecommitdiff
path: root/example/generator/odp_generator.c
diff options
context:
space:
mode:
Diffstat (limited to 'example/generator/odp_generator.c')
-rw-r--r--example/generator/odp_generator.c304
1 files changed, 219 insertions, 85 deletions
diff --git a/example/generator/odp_generator.c b/example/generator/odp_generator.c
index 02282e814..7319224f6 100644
--- a/example/generator/odp_generator.c
+++ b/example/generator/odp_generator.c
@@ -47,6 +47,7 @@
typedef struct {
odp_pktio_t pktio;
+ odp_pktio_config_t config;
odp_pktout_queue_t pktout[MAX_WORKERS];
unsigned pktout_count;
} interface_t;
@@ -92,7 +93,16 @@ static struct {
/** * Thread specific arguments
*/
typedef struct {
- odp_pktout_queue_t pktout; /**< Packet output queue to use*/
+ union {
+ struct {
+ odp_pktout_queue_t pktout; /**< Packet output queue */
+ odp_pktout_config_opt_t *pktout_cfg; /**< Packet output config*/
+ } tx;
+ struct {
+ interface_t *ifs; /**< Interfaces array */
+ int ifs_count; /**< Interfaces array size */
+ } rx;
+ };
odp_pool_t pool; /**< Pool for packet IO */
odp_timer_pool_t tp; /**< Timer pool handle */
odp_queue_t tq; /**< Queue for timeouts */
@@ -117,6 +127,11 @@ static args_t *args;
/** Barrier to sync threads execution */
static odp_barrier_t barrier;
+/** Packet processing function types */
+typedef odp_packet_t (*setup_pkt_ref_fn_t)(odp_pool_t,
+ odp_pktout_config_opt_t *);
+typedef int (*setup_pkt_fn_t)(odp_packet_t, odp_pktout_config_opt_t *);
+
/* helper funcs */
static void parse_args(int argc, char *argv[], appl_args_t *appl_args);
static void print_info(char *progname, appl_args_t *appl_args);
@@ -137,6 +152,7 @@ static void millisleep(uint32_t ms,
uint64_t ticks = odp_timer_ns_to_tick(tp, 1000000ULL * ms);
odp_event_t ev = odp_timeout_to_event(tmo);
int rc = odp_timer_set_rel(tim, ticks, &ev);
+
if (rc != ODP_TIMER_SUCCESS)
EXAMPLE_ABORT("odp_timer_set_rel() failed\n");
/* Spin waiting for timeout event */
@@ -187,14 +203,84 @@ static int scan_ip(char *buf, unsigned int *paddr)
}
/**
+ * Setup array of reference packets
+ *
+ * @param pool Packet pool
+ * @param pktout_cfg Interface output configuration
+ * @param pkt_ref_array Packet array
+ * @param pkt_ref_array_size Packet array size
+ * @param setup_ref Packet setup function
+ * @return 0 success, -1 failed
+*/
+static int setup_pkt_ref_array(odp_pool_t pool,
+ odp_pktout_config_opt_t *pktout_cfg,
+ odp_packet_t *pkt_ref_array,
+ int pkt_ref_array_size,
+ setup_pkt_ref_fn_t setup_ref)
+{
+ int i;
+
+ for (i = 0; i < pkt_ref_array_size; i++) {
+ pkt_ref_array[i] = (*setup_ref)(pool, pktout_cfg);
+ if (pkt_ref_array[i] == ODP_PACKET_INVALID)
+ break;
+ }
+
+ if (i < pkt_ref_array_size) {
+ odp_packet_free_multi(pkt_ref_array, i);
+ return -1;
+ }
+ return 0;
+}
+
+/**
+ * Setup array of packets
+ *
+ * @param pktout_cfg Interface output configuration
+ * @param pkt_ref_array Reference packet array
+ * @param pkt_array Packet array
+ * @param pkt_array_size Packet array size
+ * @param setup_pkt Packet setup function
+ * @return 0 success, -1 failed
+*/
+static int setup_pkt_array(odp_pktout_config_opt_t *pktout_cfg,
+ odp_packet_t *pkt_ref_array,
+ odp_packet_t *pkt_array,
+ int pkt_array_size,
+ setup_pkt_fn_t setup_pkt)
+{
+ int i;
+
+ for (i = 0; i < pkt_array_size; i++) {
+ if ((*setup_pkt)(pkt_ref_array[i], pktout_cfg))
+ break;
+
+ pkt_array[i] = odp_packet_ref_static(pkt_ref_array[i]);
+ if (pkt_array[i] == ODP_PACKET_INVALID)
+ break;
+ }
+ if (i < pkt_array_size) {
+ if (i)
+ odp_packet_free_multi(pkt_array, i - 1);
+
+ return -1;
+ }
+ return 0;
+}
+
+/**
* set up an udp packet reference
*
* @param pool Buffer pool to create packet in
+ * @param pktout_cfg Interface output configuration
*
- * @return Handle of created packet
+ *
+ * @retval Handle of created packet
* @retval ODP_PACKET_INVALID Packet could not be created
+ *
*/
-static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
+static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool,
+ odp_pktout_config_opt_t *pktout_cfg)
{
odp_packet_t pkt;
char *buf;
@@ -238,8 +324,10 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
udp->src_port = odp_cpu_to_be_16(args->appl.srcport);
udp->dst_port = odp_cpu_to_be_16(args->appl.dstport);
udp->length = odp_cpu_to_be_16(args->appl.payload + ODPH_UDPHDR_LEN);
- udp->chksum = 0;
- udp->chksum = odph_ipv4_udp_chksum(pkt);
+ if (!pktout_cfg->bit.udp_chksum) {
+ udp->chksum = 0;
+ udp->chksum = odph_ipv4_udp_chksum(pkt);
+ }
return pkt;
}
@@ -247,48 +335,49 @@ static odp_packet_t setup_udp_pkt_ref(odp_pool_t pool)
/**
* set up an udp packet
*
- * @param pool Buffer pool to create packet in
- * @param pkt_ref Reference UDP packet
+ * @param pkt Reference UDP packet
+ * @param pktout_cfg Interface output configuration
*
- * @return Handle of created packet
- * @retval ODP_PACKET_INVALID Packet could not be created
+ * @return Success/Failed
+ * @retval 0 on success, -1 on fail
*/
-static odp_packet_t pack_udp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
+static int setup_udp_pkt(odp_packet_t pkt, odp_pktout_config_opt_t *pktout_cfg)
{
- odp_packet_t pkt;
char *buf;
odph_ipv4hdr_t *ip;
unsigned short seq;
- pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_UDPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
-
- if (pkt == ODP_PACKET_INVALID)
- return pkt;
-
buf = (char *)odp_packet_data(pkt);
- odp_memcpy(buf, odp_packet_data(pkt_ref),
- args->appl.payload + ODPH_UDPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
/*Update IP ID and checksum*/
ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xFFFF;
ip->id = odp_cpu_to_be_16(seq);
- ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ if (!pktout_cfg->bit.ipv4_chksum) {
+ ip->chksum = 0;
+ ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ }
- return pkt;
+ if (pktout_cfg->bit.ipv4_chksum || pktout_cfg->bit.udp_chksum) {
+ odp_packet_l2_offset_set(pkt, 0);
+ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
+ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
+ ODPH_IPV4HDR_LEN);
+ }
+ return 0;
}
/**
* Set up an icmp packet reference
*
* @param pool Buffer pool to create packet in
+ * @param pktout_cfg Interface output configuration
*
* @return Handle of created packet
* @retval ODP_PACKET_INVALID Packet could not be created
*/
-static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool)
+static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool,
+ odp_pktout_config_opt_t *pktout_cfg)
{
odp_packet_t pkt;
char *buf;
@@ -296,6 +385,8 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool)
odph_ipv4hdr_t *ip;
odph_icmphdr_t *icmp;
+ (void)pktout_cfg;
+
args->appl.payload = 56;
pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN +
ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
@@ -338,15 +429,15 @@ static odp_packet_t setup_icmp_pkt_ref(odp_pool_t pool)
/**
* Set up an icmp packet
*
- * @param pool Buffer pool to create packet in
- * @param pkt_ref Reference ICMP packet
+ * @param pkt Reference ICMP packet
+ * @param pktout_cfg Interface output configuration
*
- * @return Handle of created packet
- * @retval ODP_PACKET_INVALID Packet could not be created
+ * @return Success/Failed
+ * @retval 0 on success, -1 on fail
*/
-static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
+static int setup_icmp_pkt(odp_packet_t pkt,
+ odp_pktout_config_opt_t *pktout_cfg)
{
- odp_packet_t pkt;
char *buf;
odph_ipv4hdr_t *ip;
odph_icmphdr_t *icmp;
@@ -354,22 +445,16 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
uint8_t *tval_d;
unsigned short seq;
- pkt = odp_packet_alloc(pool, args->appl.payload + ODPH_ICMPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
-
- if (pkt == ODP_PACKET_INVALID)
- return pkt;
-
buf = (char *)odp_packet_data(pkt);
- odp_memcpy(buf, odp_packet_data(pkt_ref),
- args->appl.payload + ODPH_ICMPHDR_LEN +
- ODPH_IPV4HDR_LEN + ODPH_ETHHDR_LEN);
/* ip */
ip = (odph_ipv4hdr_t *)(buf + ODPH_ETHHDR_LEN);
seq = odp_atomic_fetch_add_u64(&counters.seq, 1) % 0xffff;
ip->id = odp_cpu_to_be_16(seq);
- ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ if (!pktout_cfg->bit.ipv4_chksum) {
+ ip->chksum = 0;
+ ip->chksum = odph_chksum(ip, ODPH_IPV4HDR_LEN);
+ }
/* icmp */
icmp = (odph_icmphdr_t *)(buf + ODPH_ETHHDR_LEN + ODPH_IPV4HDR_LEN);
@@ -383,7 +468,14 @@ static odp_packet_t pack_icmp_pkt(odp_pool_t pool, odp_packet_t pkt_ref)
icmp->chksum = 0;
icmp->chksum = odph_chksum(icmp, args->appl.payload + ODPH_ICMPHDR_LEN);
- return pkt;
+ if (pktout_cfg->bit.ipv4_chksum) {
+ odp_packet_l2_offset_set(pkt, 0);
+ odp_packet_l3_offset_set(pkt, ODPH_ETHHDR_LEN);
+ odp_packet_l4_offset_set(pkt, ODPH_ETHHDR_LEN +
+ ODPH_IPV4HDR_LEN);
+ }
+
+ return 0;
}
/**
@@ -423,6 +515,22 @@ static int create_pktio(const char *dev, odp_pool_t pool,
dev);
return -1;
}
+ odp_pktio_config_init(&itf->config);
+ itf->config.pktin.bit.ipv4_chksum = capa.config.pktin.bit.ipv4_chksum;
+ itf->config.pktin.bit.udp_chksum = capa.config.pktin.bit.udp_chksum;
+ itf->config.pktin.bit.drop_ipv4_err =
+ capa.config.pktin.bit.drop_ipv4_err;
+ itf->config.pktin.bit.drop_udp_err = capa.config.pktin.bit.drop_udp_err;
+
+ itf->config.pktout.bit.ipv4_chksum = capa.config.pktout.bit.ipv4_chksum;
+ itf->config.pktout.bit.udp_chksum = capa.config.pktout.bit.udp_chksum;
+
+ if (odp_pktio_config(itf->pktio, &itf->config)) {
+ EXAMPLE_ERR("Error: Failed to set interface configuration %s\n",
+ dev);
+ return -1;
+ }
+
if (num_rx_queues > capa.max_input_queues)
num_rx_queues = capa.max_input_queues;
@@ -480,33 +588,42 @@ static int create_pktio(const char *dev, odp_pool_t pool,
static int gen_send_thread(void *arg)
{
int thr;
- int ret, i;
+ int ret = 0;
thread_args_t *thr_args;
odp_pktout_queue_t pktout;
+ odp_pktout_config_opt_t *pktout_cfg;
+ odp_packet_t pkt_ref_array[MAX_UDP_TX_BURST];
odp_packet_t pkt_array[MAX_UDP_TX_BURST];
int pkt_array_size;
int burst_start, burst_size;
- odp_packet_t pkt_ref = ODP_PACKET_INVALID;
+ setup_pkt_ref_fn_t setup_pkt_ref = NULL;
+ setup_pkt_fn_t setup_pkt = NULL;
thr = odp_thread_id();
thr_args = arg;
+ pktout = thr_args->tx.pktout;
+ pktout_cfg = thr_args->tx.pktout_cfg;
- pktout = thr_args->pktout;
-
+ /* Create reference packets*/
if (args->appl.mode == APPL_MODE_UDP) {
- pkt_ref = setup_udp_pkt_ref(thr_args->pool);
pkt_array_size = args->appl.udp_tx_burst;
+ setup_pkt_ref = setup_udp_pkt_ref;
+ setup_pkt = setup_udp_pkt;
} else if (args->appl.mode == APPL_MODE_PING) {
- pkt_ref = setup_icmp_pkt_ref(thr_args->pool);
pkt_array_size = 1;
+ setup_pkt_ref = setup_icmp_pkt_ref;
+ setup_pkt = setup_icmp_pkt;
} else {
EXAMPLE_ERR(" [%02i] Error: invalid processing mode %d\n",
thr, args->appl.mode);
return -1;
}
- if (pkt_ref == ODP_PACKET_INVALID) {
- EXAMPLE_ERR(" [%2i] Error: reference packet creation failed\n",
- thr);
+
+ if (setup_pkt_ref_array(thr_args->pool, pktout_cfg,
+ pkt_ref_array, pkt_array_size,
+ setup_pkt_ref)) {
+ EXAMPLE_ERR("[%02i] Error: failed to create"
+ " reference packets\n", thr);
return -1;
}
@@ -520,30 +637,15 @@ static int gen_send_thread(void *arg)
(unsigned int)args->appl.number)
break;
- if (args->appl.mode == APPL_MODE_UDP) {
- for (i = 0; i < pkt_array_size; i++) {
- pkt_array[i] = pack_udp_pkt(thr_args->pool,
- pkt_ref);
- if (!odp_packet_is_valid(pkt_array[i]))
- break;
- }
- if (i != pkt_array_size) {
- EXAMPLE_ERR(" [%2i] alloc_multi failed\n",
- thr);
- odp_packet_free_multi(pkt_array, i);
- break;
- }
- } else if (args->appl.mode == APPL_MODE_PING) {
- pkt_array[0] = pack_icmp_pkt(thr_args->pool, pkt_ref);
- if (!odp_packet_is_valid(pkt_array[0])) {
- EXAMPLE_ERR(" [%2i] alloc_single failed\n",
- thr);
- break;
- }
- } else {
+ /* Setup TX burst*/
+ if (setup_pkt_array(pktout_cfg, pkt_ref_array, pkt_array,
+ pkt_array_size, setup_pkt)) {
+ EXAMPLE_ERR("[%02i] Error: failed to setup packets\n",
+ thr);
break;
}
+ /* Send TX burst*/
for (burst_start = 0, burst_size = pkt_array_size;;) {
ret = odp_pktout_send(pktout, &pkt_array[burst_start],
burst_size);
@@ -573,7 +675,6 @@ static int gen_send_thread(void *arg)
thr_args->tim,
thr_args->tq,
thr_args->tmo_ev);
-
}
}
@@ -591,7 +692,8 @@ static int gen_send_thread(void *arg)
args->appl.timeout--;
}
}
- odp_packet_free(pkt_ref);
+
+ odp_packet_free_multi(pkt_ref_array, pkt_array_size);
return 0;
}
@@ -682,12 +784,15 @@ static void print_pkts(int thr, odp_packet_t pkt_tbl[], unsigned len)
static int gen_recv_thread(void *arg)
{
int thr;
+ thread_args_t *thr_args;
odp_packet_t pkts[MAX_RX_BURST], pkt;
odp_event_t events[MAX_RX_BURST];
int pkt_cnt, ev_cnt, i;
+ interface_t *itfs, *itf;
thr = odp_thread_id();
- (void)arg;
+ thr_args = (thread_args_t *)arg;
+ itfs = thr_args->rx.ifs;
printf(" [%02i] created mode: RECEIVE\n", thr);
odp_barrier_wait(&barrier);
@@ -706,6 +811,21 @@ static int gen_recv_thread(void *arg)
continue;
for (i = 0, pkt_cnt = 0; i < ev_cnt; i++) {
pkt = odp_packet_from_event(events[i]);
+ itf = &itfs[odp_pktio_index(odp_packet_input(pkt))];
+
+ if (odp_packet_has_ipv4(pkt)) {
+ if (itf->config.pktin.bit.ipv4_chksum) {
+ if (odp_packet_has_l3_error(pkt))
+ printf("HW detected L3 error\n");
+ }
+ }
+
+ if (odp_packet_has_udp(pkt)) {
+ if (itf->config.pktin.bit.udp_chksum) {
+ if (odp_packet_has_l4_error(pkt))
+ printf("HW detected L4 error\n");
+ }
+ }
/* Drop packets with errors */
if (odp_unlikely(odp_packet_has_error(pkt))) {
@@ -715,9 +835,11 @@ static int gen_recv_thread(void *arg)
pkts[pkt_cnt++] = pkt;
}
- print_pkts(thr, pkts, pkt_cnt);
+ if (pkt_cnt) {
+ print_pkts(thr, pkts, pkt_cnt);
- odp_packet_free_multi(pkts, pkt_cnt);
+ odp_packet_free_multi(pkts, pkt_cnt);
+ }
}
return 0;
@@ -729,11 +851,12 @@ static int gen_recv_thread(void *arg)
*/
static void print_global_stats(int num_workers)
{
- odp_time_t cur, wait, next;
+ odp_time_t cur, wait, next, left;
uint64_t pkts_snd = 0, pkts_snd_prev = 0;
uint64_t pps_snd = 0, maximum_pps_snd = 0;
uint64_t pkts_rcv = 0, pkts_rcv_prev = 0;
uint64_t pps_rcv = 0, maximum_pps_rcv = 0;
+ uint64_t stall;
int verbose_interval = 20;
odp_thrmask_t thrd_mask;
@@ -750,8 +873,15 @@ static void print_global_stats(int num_workers)
}
cur = odp_time_local();
- if (odp_time_cmp(next, cur) > 0)
+ if (odp_time_cmp(next, cur) > 0) {
+ left = odp_time_diff(next, cur);
+ stall = odp_time_to_ns(left);
+ if (stall / ODP_TIME_SEC_IN_NS)
+ sleep(1);
+ else
+ usleep(stall / ODP_TIME_USEC_IN_NS);
continue;
+ }
next = odp_time_sum(cur, wait);
switch (args->appl.mode) {
@@ -978,7 +1108,8 @@ int main(int argc, char *argv[])
EXAMPLE_ERR("queue_create failed\n");
abort();
}
- (void)args->thread[1].pktout; /* Not used*/
+ args->thread[1].rx.ifs = ifs;
+ args->thread[1].rx.ifs_count = args->appl.if_count;
args->thread[1].pool = pool;
args->thread[1].tp = tp;
args->thread[1].tq = tq;
@@ -1007,7 +1138,8 @@ int main(int argc, char *argv[])
EXAMPLE_ERR("queue_create failed\n");
abort();
}
- args->thread[0].pktout = ifs[0].pktout[0];
+ args->thread[0].tx.pktout = ifs[0].pktout[0];
+ args->thread[0].tx.pktout_cfg = &ifs[0].config.pktout;
args->thread[0].pool = pool;
args->thread[0].tp = tp;
args->thread[0].tq = tq;
@@ -1039,15 +1171,19 @@ int main(int argc, char *argv[])
int (*thr_run_func)(void *);
int if_idx, pktout_idx;
- if (args->appl.mode == APPL_MODE_RCV)
- (void)args->thread[i].pktout; /*not used*/
- else {
+ if (args->appl.mode == APPL_MODE_RCV) {
+ args->thread[i].rx.ifs = ifs;
+ args->thread[i].rx.ifs_count =
+ args->appl.if_count;
+ } else {
if_idx = i % args->appl.if_count;
pktout_idx = (i / args->appl.if_count) %
ifs[if_idx].pktout_count;
- args->thread[i].pktout =
+ args->thread[i].tx.pktout =
ifs[if_idx].pktout[pktout_idx];
+ args->thread[i].tx.pktout_cfg =
+ &ifs[if_idx].config.pktout;
}
tq = odp_queue_create("", NULL);
if (tq == ODP_QUEUE_INVALID) {
@@ -1091,7 +1227,6 @@ int main(int argc, char *argv[])
odph_odpthreads_create(&thread_tbl[i],
&thd_mask, &thr_params);
cpu = odp_cpumask_next(&cpumask, cpu);
-
}
}
@@ -1139,7 +1274,6 @@ int main(int argc, char *argv[])
return 0;
}
-
/**
* Parse and store the command line arguments
*