API Reference Manual  1.45.1
odp_ping.c

This application replies to IPv4 ping requests. It can be used to test connectivity with standard ping utility. ARP table needs to be setup manually on the sender side as the application does not reply to ARP requests.

/* SPDX-License-Identifier: BSD-3-Clause
* Copyright (c) 2019-2023 Nokia
*/
#include <stdio.h>
#include <string.h>
#include <signal.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>
#include <getopt.h>
#include <odp_api.h>
#include <odp/helper/odph_api.h>
#define MAX_PKTIOS 32
#define MAX_PKTIO_NAME 255
#define MAX_PKT_NUM 1024
ODP_STATIC_ASSERT(MAX_PKTIOS < UINT8_MAX, "MAX_PKTIOS too large for index lookup");
typedef struct test_options_t {
uint64_t num_packet;
uint32_t timeout;
int promisc;
int verbose;
int num_pktio;
char pktio_name[MAX_PKTIOS][MAX_PKTIO_NAME + 1];
} test_options_t;
typedef struct test_global_t {
test_options_t opt;
uint64_t rx_packets;
uint64_t tx_replies;
odp_pool_t pool;
struct {
odph_ethaddr_t eth_addr;
odp_pktio_t pktio;
int started;
} pktio[MAX_PKTIOS];
/* Pktio index lookup table */
uint8_t pktio_from_idx[ODP_PKTIO_MAX_INDEX + 1];
} test_global_t;
static test_global_t test_global;
static void sig_handler(int signo)
{
(void)signo;
odp_atomic_store_u32(&test_global.stop, 1);
}
static void print_usage(void)
{
printf("\n"
"ODP ping example. Replies to ICMPv4 ping requests.\n"
"\n"
"OPTIONS:\n"
" -i, --interface <name> Packet IO interfaces (comma-separated, no spaces)\n"
" -n, --num_packet <number> Exit after this many packets. Use 0 to run infinitely. Default 0.\n"
" -t, --timeout <sec> Exit after this many seconds. Use 0 to run infinitely. Default 0.\n"
" -p, --promisc Set interface into promiscuous mode.\n"
" -v, --verbose Print extra packet information.\n"
" -h, --help Display help and exit.\n\n");
}
static int parse_options(int argc, char *argv[], test_global_t *global)
{
int i, opt, long_index;
char *name, *str;
int len, str_len;
const struct option longopts[] = {
{"interface", required_argument, NULL, 'i'},
{"num_packet", required_argument, NULL, 'n'},
{"timeout", required_argument, NULL, 't'},
{"promisc", no_argument, NULL, 'p'},
{"verbose", no_argument, NULL, 'v'},
{"help", no_argument, NULL, 'h'},
{NULL, 0, NULL, 0}
};
const char *shortopts = "+i:n:t:pvh";
int ret = 0;
while (1) {
opt = getopt_long(argc, argv, shortopts, longopts, &long_index);
if (opt == -1)
break; /* No more options */
switch (opt) {
case 'i':
i = 0;
str = optarg;
str_len = strlen(str);
while (str_len > 0) {
len = strcspn(str, ",");
str_len -= len + 1;
if (i == MAX_PKTIOS) {
ODPH_ERR("Too many interfaces\n");
ret = -1;
break;
}
if (len > MAX_PKTIO_NAME) {
ODPH_ERR("Too long interface name: %s\n", str);
ret = -1;
break;
}
name = global->opt.pktio_name[i];
memcpy(name, str, len);
str += len + 1;
i++;
}
global->opt.num_pktio = i;
break;
case 'n':
global->opt.num_packet = atoll(optarg);
break;
case 't':
global->opt.timeout = atoi(optarg);
break;
case 'p':
global->opt.promisc = 1;
break;
case 'v':
global->opt.verbose = 1;
break;
case 'h':
default:
print_usage();
return -1;
}
}
if (global->opt.num_pktio == 0) {
ODPH_ERR("At least one pktio interface needed\n");
ret = -1;
}
return ret;
}
static int open_pktios(test_global_t *global)
{
odp_pool_param_t pool_param;
odp_pktio_param_t pktio_param;
odp_pool_t pool;
odp_pktio_t pktio;
odp_pktio_config_t pktio_config;
char *name;
int i, num_pktio;
uint32_t num_pkt = MAX_PKT_NUM;
num_pktio = global->opt.num_pktio;
if (odp_pool_capability(&pool_capa)) {
ODPH_ERR("Pool capability failed\n");
return -1;
}
if (pool_capa.pkt.max_num < MAX_PKT_NUM)
num_pkt = pool_capa.pkt.max_num;
odp_pool_param_init(&pool_param);
pool_param.pkt.num = num_pkt;
pool_param.type = ODP_POOL_PACKET;
pool = odp_pool_create("packet pool", &pool_param);
global->pool = pool;
if (pool == ODP_POOL_INVALID) {
ODPH_ERR("Pool create failed\n");
return -1;
}
odp_pktio_param_init(&pktio_param);
for (i = 0; i < num_pktio; i++)
global->pktio[i].pktio = ODP_PKTIO_INVALID;
/* Open and configure interfaces */
for (i = 0; i < num_pktio; i++) {
name = global->opt.pktio_name[i];
pktio = odp_pktio_open(name, pool, &pktio_param);
if (pktio == ODP_PKTIO_INVALID) {
ODPH_ERR("Pktio open failed: %s\n", name);
return -1;
}
global->pktio[i].pktio = pktio;
if (odp_pktio_capability(pktio, &pktio_capa)) {
ODPH_ERR("Packet IO capability failed\n");
return -1;
}
if (odp_pktio_mac_addr(pktio,
&global->pktio[i].eth_addr.addr,
ODPH_ETHADDR_LEN) != ODPH_ETHADDR_LEN) {
ODPH_ERR("MAC address read failed: %s\n", name);
return -1;
}
odp_pktio_config_init(&pktio_config);
pktio_config.pktin.bit.ts_all = 1;
odp_pktio_config(pktio, &pktio_config);
pktin_param.num_queues = 1;
if (odp_pktin_queue_config(pktio, &pktin_param)) {
ODPH_ERR("Pktin config failed: %s\n", name);
return -1;
}
pktout_param.num_queues = 1;
if (odp_pktout_queue_config(pktio, &pktout_param)) {
ODPH_ERR("Pktout config failed: %s\n", name);
return -1;
}
if (odp_pktout_queue(pktio, &pktout, 1) != 1) {
ODPH_ERR("Pktout queue request failed: %s\n", name);
return -1;
}
global->pktio[i].pktout = pktout;
if (global->opt.promisc && odp_pktio_promisc_mode(pktio) != 1) {
if (pktio_capa.set_op.op.promisc_mode == 0) {
ODPH_ERR("Promiscuous mode cannot be set: %s\n", name);
return -1;
}
if (odp_pktio_promisc_mode_set(pktio, 1)) {
ODPH_ERR("Promiscuous mode set failed: %s\n", name);
return -1;
}
}
}
return 0;
}
static int init_pktio_lookup_tbl(test_global_t *global)
{
for (int i = 0; i < global->opt.num_pktio; i++) {
odp_pktio_t pktio = global->pktio[i].pktio;
int pktio_idx = odp_pktio_index(pktio);
if (pktio_idx < 0) {
ODPH_ERR("odp_pktio_index() failed: %s\n", global->opt.pktio_name[i]);
return -1;
}
global->pktio_from_idx[pktio_idx] = i;
}
return 0;
}
static int start_pktios(test_global_t *global)
{
int i;
for (i = 0; i < global->opt.num_pktio; i++) {
if (odp_pktio_start(global->pktio[i].pktio)) {
ODPH_ERR("Pktio start failed: %s\n", global->opt.pktio_name[i]);
return -1;
}
global->pktio[i].started = 1;
}
return 0;
}
static int stop_pktios(test_global_t *global)
{
odp_pktio_t pktio;
int i, ret = 0;
for (i = 0; i < global->opt.num_pktio; i++) {
pktio = global->pktio[i].pktio;
if (pktio == ODP_PKTIO_INVALID || global->pktio[i].started == 0)
continue;
if (odp_pktio_stop(pktio)) {
ODPH_ERR("Pktio stop failed: %s\n", global->opt.pktio_name[i]);
ret = -1;
}
}
return ret;
}
static void empty_queues(void)
{
uint64_t wait_time = odp_schedule_wait_time(ODP_TIME_SEC_IN_NS / 2);
/* Drop all events from all queues */
while (1) {
ev = odp_schedule(NULL, wait_time);
if (ev == ODP_EVENT_INVALID)
break;
}
}
static int close_pktios(test_global_t *global)
{
odp_pktio_t pktio;
odp_pool_t pool;
int i, ret = 0;
for (i = 0; i < global->opt.num_pktio; i++) {
pktio = global->pktio[i].pktio;
if (pktio == ODP_PKTIO_INVALID)
continue;
if (odp_pktio_close(pktio)) {
ODPH_ERR("Pktio close failed: %s\n", global->opt.pktio_name[i]);
ret = -1;
}
}
pool = global->pool;
if (pool == ODP_POOL_INVALID)
return ret;
if (odp_pool_destroy(pool)) {
ODPH_ERR("Pool destroy failed\n");
ret = -1;
}
return ret;
}
static void print_mac_addr(uint8_t *addr)
{
printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
addr[0], addr[1], addr[2], addr[3], addr[4], addr[5]);
}
static void print_ipv4_addr(uint8_t *addr)
{
printf("%u.%u.%u.%u\n",
addr[0], addr[1], addr[2], addr[3]);
}
static void print_data(odp_packet_t pkt, uint32_t offset, uint32_t len)
{
const uint32_t bytes_per_row = 16;
const uint32_t num_char = 1 + (bytes_per_row * 3) + 1;
uint8_t data[bytes_per_row];
char row[num_char];
uint32_t copy_len, i, j;
uint32_t data_len = odp_packet_len(pkt);
if (offset > data_len)
return;
if (offset + len > data_len)
len = data_len - offset;
while (len) {
i = 0;
if (len > bytes_per_row)
copy_len = bytes_per_row;
else
copy_len = len;
odp_packet_copy_to_mem(pkt, offset, copy_len, data);
i += snprintf(&row[i], num_char - i, " ");
for (j = 0; j < copy_len; j++)
i += snprintf(&row[i], num_char - i, " %02x", data[j]);
row[i] = 0;
printf("%s\n", row);
len -= copy_len;
offset += copy_len;
}
}
static void print_packet(odp_packet_t pkt, uint64_t num_packet)
{
odp_pktio_t pktio;
odp_pktio_info_t pktio_info;
odp_time_t time;
uint64_t sec, nsec;
uint32_t offset;
uint8_t *data = odp_packet_data(pkt);
uint32_t seg_len = odp_packet_seg_len(pkt);
uint32_t l2_offset = odp_packet_l2_offset(pkt);
uint32_t l3_offset = odp_packet_l3_offset(pkt);
uint32_t l4_offset = odp_packet_l4_offset(pkt);
uint32_t data_len = odp_packet_len(pkt);
int icmp = odp_packet_has_icmp(pkt);
int ipv4 = odp_packet_has_ipv4(pkt);
time = odp_packet_ts(pkt);
else
time = odp_time_local();
nsec = odp_time_to_ns(time);
sec = nsec / ODP_TIME_SEC_IN_NS;
nsec = nsec - (sec * ODP_TIME_SEC_IN_NS);
pktio = odp_packet_input(pkt);
printf("PACKET [%" PRIu64 "]\n", num_packet);
printf(" time: %" PRIu64 ".%09" PRIu64 " sec\n", sec, nsec);
if (odp_pktio_info(pktio, &pktio_info) == 0)
printf(" interface name: %s\n", pktio_info.name);
else
printf(" interface name: n/a\n");
printf(" packet length: %u bytes\n", odp_packet_len(pkt));
/* L2 */
if (odp_packet_has_eth(pkt)) {
printf(" Ethernet offset: %u bytes\n", l2_offset);
offset = l2_offset;
if (offset + 6 <= seg_len) {
printf(" dst address: ");
print_mac_addr(data + offset);
}
offset = l2_offset + 6;
if (offset + 6 <= seg_len) {
printf(" src address: ");
print_mac_addr(data + offset);
}
} else if (odp_packet_has_l2(pkt)) {
printf(" L2 (%i) offset: %u bytes\n",
odp_packet_l2_type(pkt), l2_offset);
}
/* L3 */
if (ipv4) {
printf(" IPv4 offset: %u bytes\n", l3_offset);
offset = l3_offset + 12;
if (offset + 4 <= seg_len) {
printf(" src address: ");
print_ipv4_addr(data + offset);
}
offset = l3_offset + 16;
if (offset + 4 <= seg_len) {
printf(" dst address: ");
print_ipv4_addr(data + offset);
}
} else if (odp_packet_has_ipv6(pkt)) {
printf(" IPv6 offset: %u bytes\n", l3_offset);
} else if (odp_packet_has_l3(pkt)) {
printf(" L3 (%i) offset: %u bytes\n",
odp_packet_l3_type(pkt), l3_offset);
}
/* L4 */
if (icmp) {
printf(" ICMP offset: %u bytes\n", l4_offset);
if (ipv4) {
uint32_t len;
uint8_t *u8 = odp_packet_l4_ptr(pkt, &len);
if (u8 && len >= 2) {
printf(" type: %u\n", u8[0]);
printf(" code: %u\n", u8[1]);
}
}
} else if (odp_packet_has_l4(pkt)) {
printf(" L4 (%i) offset: %u bytes\n",
odp_packet_l4_type(pkt), l4_offset);
}
print_data(pkt, 0, data_len);
printf("\n");
}
/* Updated checksum when a 16 bit word has been changed from old to new */
static uint16_t update_chksum(uint16_t chksum, uint16_t old, uint16_t new)
{
uint16_t chksum_comp = ~chksum;
uint16_t old_comp = ~old;
uint32_t sum = chksum_comp + old_comp + new;
while (sum >> 16)
sum = (sum & 0xffff) + (sum >> 16);
return ~sum;
}
static void icmp_reply(test_global_t *global, odp_packet_t pkt)
{
uint32_t dst_ip;
odph_ipv4hdr_t *ip_hdr;
odph_ethhdr_t *eth_hdr;
uint16_t old, new;
uint32_t len = 0;
int index = global->pktio_from_idx[odp_packet_input_index(pkt)];
odp_pktout_queue_t pktout = global->pktio[index].pktout;
odph_ethaddr_t *eth_addr = &global->pktio[index].eth_addr;
int icmp = odp_packet_has_icmp(pkt);
int ipv4 = odp_packet_has_ipv4(pkt);
int eth = odp_packet_has_eth(pkt);
odph_icmphdr_t *icmp_hdr = odp_packet_l4_ptr(pkt, &len);
goto error;
if (eth == 0 || ipv4 == 0 || icmp == 0)
goto error;
/* ICMP type, code and chksum fields are located in the first 4 bytes */
if (icmp_hdr == NULL || len < 4)
goto error;
if (icmp_hdr->type != ODPH_ICMP_ECHO || icmp_hdr->code != 0)
goto error;
/* Echo reply */
old = *(uint16_t *)(uintptr_t)icmp_hdr;
icmp_hdr->type = ODPH_ICMP_ECHOREPLY;
new = *(uint16_t *)(uintptr_t)icmp_hdr;
icmp_hdr->chksum = update_chksum(icmp_hdr->chksum, old, new);
/* Swap IP addresses */
ip_hdr = odp_packet_l3_ptr(pkt, &len);
if (ip_hdr == NULL || len < 20)
goto error;
dst_ip = ip_hdr->dst_addr;
ip_hdr->dst_addr = ip_hdr->src_addr;
ip_hdr->src_addr = dst_ip;
/* Swap Ethernet addresses */
eth_hdr = odp_packet_l2_ptr(pkt, &len);
if (eth_hdr == NULL || len < 14)
goto error;
eth_hdr->dst = eth_hdr->src;
eth_hdr->src = *eth_addr;
if (odp_pktout_send(pktout, &pkt, 1) != 1)
goto error;
global->tx_replies++;
return;
error:
}
static void print_stat(test_global_t *global, uint64_t rx_packets,
uint64_t diff_ns)
{
uint64_t prev = global->rx_packets;
double per_sec = 1000000000.0 * (rx_packets - prev) / diff_ns;
printf("Received %" PRIu64 " packets (%.1f / sec). "
"Sent %" PRIu64 " replies.\n",
rx_packets, per_sec, global->tx_replies);
global->rx_packets = rx_packets;
}
static int receive_packets(test_global_t *global)
{
uint64_t diff_ns;
int print = 0;
uint64_t num_packet = 0;
uint64_t timeout_ns = global->opt.timeout * ODP_TIME_SEC_IN_NS;
odp_time_t cur = start;
odp_time_t prev = start;
while (!odp_atomic_load_u32(&global->stop)) {
ev = odp_schedule(NULL, wait);
cur = odp_time_local();
diff_ns = odp_time_diff_ns(cur, prev);
if (diff_ns >= ODP_TIME_SEC_IN_NS) {
prev = cur;
print = 1;
}
if (ev == ODP_EVENT_INVALID) {
if (print) {
print_stat(global, num_packet, diff_ns);
print = 0;
}
if (timeout_ns) {
if (odp_time_diff_ns(cur, start) >= timeout_ns)
break;
}
continue;
}
if (odp_event_type(ev) != ODP_EVENT_PACKET) {
printf("Bad event type: %i\n", odp_event_type(ev));
continue;
}
if (global->opt.verbose)
print_packet(pkt, num_packet);
/* Reply or drop packet */
icmp_reply(global, pkt);
num_packet++;
if (print) {
print_stat(global, num_packet, diff_ns);
print = 0;
}
if (global->opt.num_packet && num_packet >= global->opt.num_packet)
break;
}
/* Timeout before num packets received */
if (global->opt.num_packet && num_packet < global->opt.num_packet) {
ODPH_ERR("Received %" PRIu64 "/%" PRIu64 " packets\n",
num_packet, global->opt.num_packet);
return -1;
}
return 0;
}
int main(int argc, char *argv[])
{
odp_instance_t instance;
test_global_t *global;
int ret = 0;
global = &test_global;
memset(global, 0, sizeof(test_global_t));
odp_atomic_init_u32(&global->stop, 0);
signal(SIGINT, sig_handler);
if (parse_options(argc, argv, global))
return -1;
/* Init ODP before calling anything else */
if (odp_init_global(&instance, NULL, NULL)) {
ODPH_ERR("Global init failed\n");
return -1;
}
/* Init this thread */
ODPH_ERR("Local init failed\n");
return -1;
}
global->pool = ODP_POOL_INVALID;
if (open_pktios(global)) {
ODPH_ERR("Pktio open failed\n");
return -1;
}
if (init_pktio_lookup_tbl(global)) {
ODPH_ERR("Mapping pktio indexes failed\n");
return -1;
}
if (start_pktios(global)) {
ODPH_ERR("Pktio start failed\n");
return -1;
}
if (receive_packets(global)) {
ret = -1;
}
if (stop_pktios(global)) {
ODPH_ERR("Pktio stop failed\n");
return -1;
}
empty_queues();
if (close_pktios(global)) {
ODPH_ERR("Pktio close failed\n");
return -1;
}
if (odp_term_local()) {
ODPH_ERR("Term local failed\n");
return -1;
}
if (odp_term_global(instance)) {
ODPH_ERR("Term global failed\n");
return -1;
}
return ret;
}
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.
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.
#define ODP_STATIC_ASSERT(cond, msg)
Compile time assertion macro.
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.
int odp_pktio_mac_addr(odp_pktio_t pktio, void *mac_addr, int size)
Get the default MAC address of a packet IO interface.
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_promisc_mode(odp_pktio_t pktio)
Determine if promiscuous mode is enabled for a packet IO interface.
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.
int odp_pktout_queue(odp_pktio_t pktio, odp_pktout_queue_t queues[], int num)
Direct packet output queues.
int odp_pktio_promisc_mode_set(odp_pktio_t pktio, odp_bool_t enable)
Set promiscuous mode.
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.
void odp_pktout_queue_param_init(odp_pktout_queue_param_t *param)
Initialize packet output queue parameters.
int odp_pktio_stop(odp_pktio_t pktio)
Stop packet receive and transmit.
int odp_pktio_index(odp_pktio_t pktio)
Get pktio interface index.
int odp_pktio_capability(odp_pktio_t pktio, odp_pktio_capability_t *capa)
Query packet IO interface capabilities.
#define ODP_PKTIO_MAX_INDEX
Maximum packet IO interface index.
int odp_pktout_send(odp_pktout_queue_t queue, const odp_packet_t packets[], int num)
Send packets directly to an interface output queue.
int odp_pktin_queue_config(odp_pktio_t pktio, const odp_pktin_queue_param_t *param)
Configure packet input queues.
int odp_pktout_queue_config(odp_pktio_t pktio, const odp_pktout_queue_param_t *param)
Configure packet output queues.
@ ODP_PKTOUT_MODE_DIRECT
Direct packet output on the 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.
int odp_packet_input_index(odp_packet_t pkt)
Packet input interface index.
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.
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_error(odp_packet_t pkt)
Check for all parse errors in packet.
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.
void * odp_packet_l2_ptr(odp_packet_t pkt, uint32_t *len)
Layer 2 start pointer.
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.
odp_proto_l3_type_t odp_packet_l3_type(odp_packet_t pkt)
Layer 3 protocol type.
void * odp_packet_l3_ptr(odp_packet_t pkt, uint32_t *len)
Layer 3 start pointer.
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.
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.
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_MSEC_IN_NS
A millisecond in nanoseconds.
uint64_t odp_time_diff_ns(odp_time_t t2, odp_time_t t1)
Time difference in nanoseconds.
The OpenDataPlane API.
Packet input queue parameters.
uint32_t num_queues
Number of input queues to be created.
odp_queue_param_t queue_param
Queue parameters.
Packet IO capabilities.
odp_pktio_set_op_t set_op
Supported set operations.
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.
Packet IO information.
const char * name
Packet IO device name.
Packet IO parameters.
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.
Packet output queue parameters.
uint32_t num_queues
Number of output queues to be created.
uint32_t max_num
Maximum number of buffers of any size.
struct odp_pool_capability_t::@119 pkt
Packet pool capabilities
Pool parameters.
uint32_t num
Number of buffers in the pool.
odp_pool_type_t type
Pool type.
struct odp_pool_param_t::@123 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.
struct odp_pktio_set_op_t::@104 op
Operation flags.
uint32_t promisc_mode
Promiscuous mode.