23 #include <odp/helper/odph_api.h>
26 #define MAX_PKTIO_NAME 255
27 #define MAX_PKT_NUM 1024
28 #define MAX_FILTERS 32
30 typedef struct test_options_t {
36 char pktio_name[MAX_PKTIOS][MAX_PKTIO_NAME + 1];
38 int filter_l3[MAX_FILTERS];
40 int filter_l4[MAX_FILTERS];
44 typedef struct test_global_t {
57 static test_global_t test_global;
59 static void sig_handler(
int signo)
66 static void print_usage(
void)
69 "Print received packets\n"
72 " -i, --interface <name> Packet IO interfaces (comma-separated, no spaces)\n"
73 " -n, --num_packet <number> Exit after this many packets. Use 0 to run infinitely. Default 0.\n"
74 " -o, --data_offset <number> Data print start offset in bytes. Default 0.\n"
75 " -l, --data_length <number> Data print length in bytes. Default 0.\n"
76 " --filter_l3 <type> Print only packets with matching L3 type. Comma-separated\n"
77 " list (no spaces) of ODP L3 type values (e.g. value of ODP_PROTO_L3_TYPE_IPV4).\n"
78 " --filter_l4 <type> Print only packets with matching L4 type. Comma-separated\n"
79 " list (no spaces) of ODP L4 type values (e.g. value of ODP_PROTO_L4_TYPE_TCP).\n"
80 " -v, --verbose Print extra packet information.\n"
81 " -h, --help Display help and exit.\n\n");
84 static int parse_int_list(
char *str,
int integer[],
int max_num)
89 str_len = strlen(str);
92 len = strcspn(str,
",");
96 ODPH_ERR(
"Maximum number of options is %i\n", max_num);
100 integer[i] = atoi(str);
110 static int parse_options(
int argc,
char *argv[], test_global_t *global)
114 int len, str_len, num;
116 const struct option longopts[] = {
117 {
"interface", required_argument, NULL,
'i'},
118 {
"num_packet", required_argument, NULL,
'n'},
119 {
"data_offset", required_argument, NULL,
'o'},
120 {
"data_length", required_argument, NULL,
'l'},
121 {
"verbose", no_argument, NULL,
'v'},
122 {
"help", no_argument, NULL,
'h'},
123 {
"filter_l3", required_argument, NULL, 0 },
124 {
"filter_l4", required_argument, NULL, 1 },
127 const char *shortopts =
"+i:n:o:l:vh";
131 opt = getopt_long(argc, argv, shortopts, longopts, NULL);
139 num = parse_int_list(optarg, global->opt.filter_l3,
141 global->opt.num_filter_l3 = num;
148 num = parse_int_list(optarg, global->opt.filter_l4,
150 global->opt.num_filter_l4 = num;
158 str_len = strlen(str);
160 while (str_len > 0) {
161 len = strcspn(str,
",");
164 if (i == MAX_PKTIOS) {
165 ODPH_ERR(
"Too many interfaces\n");
170 if (len > MAX_PKTIO_NAME) {
171 ODPH_ERR(
"Too long interface name %s\n", str);
176 name = global->opt.pktio_name[i];
177 memcpy(name, str, len);
182 global->opt.num_pktio = i;
186 global->opt.data_offset = atoi(optarg);
189 global->opt.data_len = atoi(optarg);
192 global->opt.num_packet = atoll(optarg);
195 global->opt.verbose = 1;
204 if (global->opt.num_pktio == 0) {
205 ODPH_ERR(
"At least one pktio interface needed\n");
212 static int open_pktios(test_global_t *global)
224 uint32_t num_pkt = MAX_PKT_NUM;
226 num_pktio = global->opt.num_pktio;
229 ODPH_ERR(
"Pool capability failed\n");
237 pool_param.
pkt.
num = num_pkt;
245 ODPH_ERR(
"Pool create failed\n");
253 for (i = 0; i < num_pktio; i++)
257 for (i = 0; i < num_pktio; i++) {
258 name = global->opt.pktio_name[i];
262 ODPH_ERR(
"Pktio open failed for %s\n", name);
266 global->pktio[i].pktio = pktio;
269 ODPH_ERR(
"Pktio capability failed for %s\n", name);
289 ODPH_ERR(
"Pktin config failed for %s\n", name);
297 static int start_pktios(test_global_t *global)
301 for (i = 0; i < global->opt.num_pktio; i++) {
303 ODPH_ERR(
"Pktio start failed for %s\n", global->opt.pktio_name[i]);
308 global->pktio[i].started = 1;
314 static int stop_pktios(test_global_t *global)
319 for (i = 0; i < global->opt.num_pktio; i++) {
320 pktio = global->pktio[i].pktio;
326 ODPH_ERR(
"Pktio stop failed for %s\n", global->opt.pktio_name[i]);
334 static void empty_queues(
void)
350 static int close_pktios(test_global_t *global)
356 for (i = 0; i < global->opt.num_pktio; i++) {
357 pktio = global->pktio[i].pktio;
363 ODPH_ERR(
"Pktio close failed for %s\n", global->opt.pktio_name[i]);
374 ODPH_ERR(
"Pool destroy failed\n");
381 static void print_mac_addr(uint8_t *addr)
383 printf(
"%02x:%02x:%02x:%02x:%02x:%02x\n",
384 addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
387 static void print_ipv4_addr(uint8_t *addr)
389 printf(
"%u.%u.%u.%u\n",
390 addr[0], addr[1], addr[2], addr[3]);
393 static void print_port(uint8_t *ptr)
395 uint16_t *port = (uint16_t *)(uintptr_t)ptr;
400 static void print_data(
odp_packet_t pkt, uint32_t offset, uint32_t len)
402 const uint32_t bytes_per_row = 16;
403 const uint32_t num_char = 1 + (bytes_per_row * 3) + 1;
404 uint8_t data[bytes_per_row];
406 uint32_t copy_len, i, j;
409 if (offset > data_len)
412 if (offset + len > data_len)
413 len = data_len - offset;
418 if (len > bytes_per_row)
419 copy_len = bytes_per_row;
425 i += snprintf(&row[i], num_char - i,
" ");
427 for (j = 0; j < copy_len; j++)
428 i += snprintf(&row[i], num_char - i,
" %02x", data[j]);
438 static int print_packet(test_global_t *global,
odp_packet_t pkt,
447 int num_filter_l3 = global->opt.num_filter_l3;
448 int num_filter_l4 = global->opt.num_filter_l4;
472 for (i = 0; i < num_filter_l3; i++) {
473 type = global->opt.filter_l3[i];
489 for (i = 0; i < num_filter_l4; i++) {
490 type = global->opt.filter_l4[i];
507 ODPH_ERR(
"Pktio info failed\n");
511 printf(
"PACKET [%" PRIu64
"]\n", num_packet);
512 printf(
" time: %" PRIu64
".%09" PRIu64
" sec\n", sec, nsec);
518 printf(
" pktio time: %" PRIu64
".%09" PRIu64
" sec\n", sec, nsec);
519 printf(
" input delay: %" PRIu64
" nsec\n",
odp_time_diff_ns(pktio_time, time));
522 printf(
" interface name: %s\n", pktio_info.
name);
527 uint8_t *eth = data + l2_offset;
529 printf(
" Ethernet offset: %u bytes\n", l2_offset);
530 if (l2_offset + 6 <= seg_len) {
531 printf(
" dst address: ");
535 if (l2_offset + 12 <= seg_len) {
536 printf(
" src address: ");
537 print_mac_addr(eth + 6);
543 uint16_t *tpid = (uint16_t *)(uintptr_t)(eth + 12);
544 uint16_t *tci = tpid + 1;
547 printf(
" VLAN (outer):\n");
551 if (l2_offset + 14 <= seg_len) {
552 printf(
" TPID: 0x%04x\n",
556 if (l2_offset + 16 <= seg_len) {
557 printf(
" TCI: 0x%04x (VID: %u)\n",
563 printf(
" VLAN (inner):\n");
567 if (l2_offset + 18 <= seg_len) {
568 printf(
" TPID: 0x%04x\n",
572 if (l2_offset + 20 <= seg_len) {
573 printf(
" TCI: 0x%04x (VID: %u)\n",
581 printf(
" L2 (%i) offset: %u bytes\n",
587 printf(
" IPv4 offset: %u bytes\n", l3_offset);
588 offset = l3_offset + 12;
589 if (offset + 4 <= seg_len) {
590 printf(
" src address: ");
591 print_ipv4_addr(data + offset);
594 offset = l3_offset + 16;
595 if (offset + 4 <= seg_len) {
596 printf(
" dst address: ");
597 print_ipv4_addr(data + offset);
600 printf(
" IPv6 offset: %u bytes\n", l3_offset);
602 printf(
" L3 (%i) offset: %u bytes\n",
607 if (tcp || udp || sctp) {
609 printf(
" TCP offset: %u bytes\n", l4_offset);
611 printf(
" UDP offset: %u bytes\n", l4_offset);
613 printf(
" SCTP offset: %u bytes\n", l4_offset);
616 if (offset + 2 <= seg_len) {
617 printf(
" src port: ");
618 print_port(data + offset);
621 offset = l4_offset + 2;
622 if (offset + 2 <= seg_len) {
623 printf(
" dst port: ");
624 print_port(data + offset);
627 printf(
" ICMP offset: %u bytes\n", l4_offset);
632 if (u8 && len >= 2) {
633 printf(
" type: %u\n", u8[0]);
634 printf(
" code: %u\n", u8[1]);
638 printf(
" L4 (%i) offset: %u bytes\n",
643 if (global->opt.data_len)
644 print_data(pkt, global->opt.data_offset, global->opt.data_len);
646 if (global->opt.verbose)
654 static int receive_packets(test_global_t *global)
659 uint64_t num_packet = 0;
675 printed = print_packet(global, pkt, num_packet);
686 if (global->opt.num_packet &&
687 num_packet >= global->opt.num_packet)
694 int main(
int argc,
char *argv[])
697 test_global_t *global;
700 global = &test_global;
701 memset(global, 0,
sizeof(test_global_t));
704 signal(SIGINT, sig_handler);
706 if (parse_options(argc, argv, global))
711 ODPH_ERR(
"Global init failed\n");
717 ODPH_ERR(
"Local init failed\n");
727 if (open_pktios(global)) {
728 ODPH_ERR(
"Pktio open failed\n");
732 if (start_pktios(global)) {
733 ODPH_ERR(
"Pktio start failed\n");
737 if (receive_packets(global)) {
738 ODPH_ERR(
"Packet receive failed\n");
742 if (stop_pktios(global)) {
743 ODPH_ERR(
"Pktio stop failed\n");
749 if (close_pktios(global)) {
750 ODPH_ERR(
"Pktio close failed\n");
755 ODPH_ERR(
"Term local failed\n");
760 ODPH_ERR(
"Term global failed\n");
void odp_atomic_init_u32(odp_atomic_u32_t *atom, uint32_t val)
Initialize atomic uint32 variable.
uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable.
void odp_atomic_store_u32(odp_atomic_u32_t *atom, uint32_t val)
Store value to atomic uint32 variable.
#define odp_unlikely(x)
Branch unlikely taken.
uint16_t odp_be_to_cpu_16(odp_u16be_t be16)
Convert 16bit big endian to cpu native uint16_t.
void odp_event_free(odp_event_t event)
Free event.
odp_event_type_t odp_event_type(odp_event_t event)
Event type of an event.
#define ODP_EVENT_INVALID
Invalid event.
int odp_init_local(odp_instance_t instance, odp_thread_type_t thr_type)
Thread local ODP initialization.
int odp_init_global(odp_instance_t *instance, const odp_init_t *params, const odp_platform_init_t *platform_params)
Global ODP initialization.
int odp_term_local(void)
Thread local ODP termination.
int odp_term_global(odp_instance_t instance)
Global ODP termination.
uint64_t odp_instance_t
ODP instance ID.
void odp_pktin_queue_param_init(odp_pktin_queue_param_t *param)
Initialize packet input queue parameters.
void odp_pktio_param_init(odp_pktio_param_t *param)
Initialize pktio params.
int odp_pktio_close(odp_pktio_t pktio)
Close a packet IO interface.
int odp_pktio_info(odp_pktio_t pktio, odp_pktio_info_t *info)
Retrieve information about a pktio.
void odp_pktio_config_init(odp_pktio_config_t *config)
Initialize packet IO configuration options.
odp_pktio_t odp_pktio_open(const char *name, odp_pool_t pool, const odp_pktio_param_t *param)
Open a packet IO interface.
int odp_pktio_config(odp_pktio_t pktio, const odp_pktio_config_t *config)
Configure packet IO interface options.
void odp_pktio_print(odp_pktio_t pktio)
Print pktio info to the console.
int odp_pktio_start(odp_pktio_t pktio)
Start packet receive and transmit.
#define ODP_PKTIO_INVALID
Invalid packet IO handle.
odp_time_t odp_pktio_time(odp_pktio_t pktio, odp_time_t *ts_global)
Current packet IO time and global time.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
@ ODP_PKTOUT_MODE_DISABLED
Application will never send to this interface.
@ ODP_PKTIN_MODE_SCHED
Packet input through scheduler and scheduled event queues.
int odp_packet_has_l3(odp_packet_t pkt)
Check for layer 3 protocols.
odp_proto_l4_type_t odp_packet_l4_type(odp_packet_t pkt)
Layer 4 protocol type.
int odp_packet_has_ts(odp_packet_t pkt)
Check for packet timestamp.
uint32_t odp_packet_seg_len(odp_packet_t pkt)
Packet data length following the data pointer.
int odp_packet_has_icmp(odp_packet_t pkt)
Check for ICMP.
int odp_packet_has_ipv4(odp_packet_t pkt)
Check for IPv4.
uint32_t odp_packet_l4_offset(odp_packet_t pkt)
Layer 4 start offset.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
int odp_packet_has_eth(odp_packet_t pkt)
Check for Ethernet header.
int odp_packet_has_vlan_qinq(odp_packet_t pkt)
Check for VLAN QinQ (stacked VLAN)
odp_proto_l2_type_t odp_packet_l2_type(odp_packet_t pkt)
Layer 2 protocol type.
int odp_packet_has_l4(odp_packet_t pkt)
Check for layer 4 protocols.
uint32_t odp_packet_len(odp_packet_t pkt)
Packet data length.
int odp_packet_has_ipv6(odp_packet_t pkt)
Check for IPv6.
int odp_packet_has_l2(odp_packet_t pkt)
Check for layer 2 protocols.
odp_packet_t odp_packet_from_event(odp_event_t ev)
Get packet handle from event.
void odp_packet_free(odp_packet_t pkt)
Free packet.
int odp_packet_has_vlan(odp_packet_t pkt)
Check for VLAN.
uint32_t odp_packet_l3_offset(odp_packet_t pkt)
Layer 3 start offset.
void * odp_packet_l4_ptr(odp_packet_t pkt, uint32_t *len)
Layer 4 start pointer.
int odp_packet_has_sctp(odp_packet_t pkt)
Check for SCTP.
odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt)
Layer 3 protocol type.
int odp_packet_has_tcp(odp_packet_t pkt)
Check for TCP.
void odp_packet_print(odp_packet_t pkt)
Print packet debug information.
int odp_packet_copy_to_mem(odp_packet_t pkt, uint32_t offset, uint32_t len, void *dst)
Copy data from packet to memory.
odp_time_t odp_packet_ts(odp_packet_t pkt)
Packet timestamp.
int odp_packet_has_udp(odp_packet_t pkt)
Check for UDP.
odp_pktio_t odp_packet_input(odp_packet_t pkt)
Packet input interface.
uint32_t odp_packet_l2_offset(odp_packet_t pkt)
Layer 2 start offset.
@ ODP_PROTO_LAYER_ALL
All layers.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
int odp_pool_capability(odp_pool_capability_t *capa)
Query pool capabilities.
void odp_pool_param_init(odp_pool_param_t *param)
Initialize pool params.
int odp_pool_destroy(odp_pool_t pool)
Destroy a pool previously created by odp_pool_create()
#define ODP_POOL_INVALID
Invalid pool.
@ ODP_POOL_PACKET
Packet pool.
#define ODP_SCHED_SYNC_ATOMIC
Atomic queue synchronization.
#define ODP_SCHED_NO_WAIT
Do not wait.
int odp_schedule_default_prio(void)
Default scheduling priority level.
int odp_schedule_config(const odp_schedule_config_t *config)
Global schedule configuration.
uint64_t odp_schedule_wait_time(uint64_t ns)
Schedule wait time.
odp_event_t odp_schedule(odp_queue_t *from, uint64_t wait)
Schedule an event.
#define ODP_SCHED_GROUP_ALL
Group of all threads.
void odp_sys_info_print(void)
Print system info.
@ ODP_THREAD_CONTROL
Control thread.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
#define ODP_TIME_SEC_IN_NS
A second in nanoseconds.
odp_time_t odp_time_local(void)
Current local time.
#define ODP_TIME_NULL
Zero time stamp.
int odp_time_cmp(odp_time_t t2, odp_time_t t1)
Compare two times.
uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
Time difference in nanoseconds.
Packet input queue parameters.
uint32_t num_queues
Number of input queues to be created.
odp_queue_param_t queue_param
Queue parameters.
odp_pktio_config_t config
Supported pktio configuration options.
Packet IO configuration options.
odp_pktio_parser_config_t parser
Packet input parser configuration.
odp_pktin_config_opt_t pktin
Packet input configuration options bit field.
const char * name
Packet IO device name.
odp_pktin_mode_t in_mode
Packet input mode.
odp_pktout_mode_t out_mode
Packet output mode.
odp_proto_layer_t layer
Protocol parsing level in packet input.
struct odp_pool_capability_t::@122 pkt
Packet pool capabilities
uint32_t max_num
Maximum number of buffers of any size.
uint32_t num
Number of buffers in the pool.
odp_pool_type_t type
Pool type.
struct odp_pool_param_t::@126 pkt
Parameters for packet pools.
odp_schedule_param_t sched
Scheduler parameters.
odp_schedule_group_t group
Thread group.
odp_schedule_prio_t prio
Priority level.
odp_schedule_sync_t sync
Synchronization method.
uint64_t ts_all
Timestamp all packets on packet input.
struct odp_pktin_config_opt_t::@100 bit
Option flags.