18 #include <odp/helper/odph_api.h>
20 #include "odp_ipfragreass_fragment.h"
21 #include "odp_ipfragreass_reassemble.h"
22 #include "odp_ipfragreass_helpers.h"
24 #define NUM_PACKETS 200
25 #define MAX_WORKERS 32
26 #define FRAGLISTS 16384
28 #define MIN_MF_FRAG_SIZE 576
29 #define MAX_PKT_LEN 8192
30 #define MAX_FRAGS_PER_PKT 6
35 #define POOL_MIN_SEG_LEN IP_HDR_LEN_MIN
36 #define POOL_UAREA_SIZE sizeof(struct packet)
37 #define MAX_FRAGS (MAX_FRAGS_PER_PKT * NUM_PACKETS)
51 } thread_stats[MAX_WORKERS];
71 unsigned int seed = time(NULL);
77 union fraglist init_data;
80 printf(
"= Seed: %d\n", seed);
81 printf(
"= MTU: %d\n", MTU);
85 fprintf(stderr,
"ERROR: ODP global init failed.\n");
89 fprintf(stderr,
"ERROR: ODP local init failed.\n");
96 pool_params.
pkt.
len = MAX_PKT_LEN;
97 pool_params.
pkt.
num = 2 * MAX_FRAGS + MAX_WORKERS;
102 fprintf(stderr,
"ERROR: packet pool create failed.\n");
109 ODP_CACHE_LINE_SIZE, 0);
111 fprintf(stderr,
"ERROR: odp_shm_reserve\n");
115 if (fraglists == NULL) {
116 fprintf(stderr,
"ERROR: odp_shm_addr\n");
120 init_fraglist(&init_data);
121 for (i = 0; i < FRAGLISTS; ++i)
130 fprintf(stderr,
"ERROR: odp_queue_create\n");
139 &reass_queue_params);
141 fprintf(stderr,
"ERROR: odp_queue_create\n");
149 printf(
"= Workers: %d\n", *num_workers);
150 printf(
"= CPU Mask: %s (first CPU: %d)\n\n", cpumask_str,
178 struct packet *fragment;
185 ++thread_stats[threadno].frags;
191 assert(fragment != NULL);
193 + ipv4hdr_ihl(*hdr));
194 assert(!ipv4hdr_more_fragments(*hdr) ||
197 - ipv4hdr_ihl(*hdr)) % 8 == 0));
199 fragment->handle = pkt;
200 fragment->prev = NULL;
203 reassembled = reassemble_ipv4_packets(fraglists, FRAGLISTS,
213 if (threadno == 0 && iterations++ > 50) {
215 garbage_collect_fraglists(fraglists, FRAGLISTS,
216 reassembled_pkts, 0);
237 odph_thread_t thread_tbl[MAX_WORKERS];
238 odph_thread_common_param_t thr_common;
239 odph_thread_param_t thr_param;
245 int total_fragments = 0;
247 int num_workers = MAX_WORKERS;
250 init(&instance, &fragment_pool, &shm, &cpumask, &num_workers);
253 printf(
"\n= Fragmenting %d packets...\n", NUM_PACKETS);
254 for (i = 0; i < NUM_PACKETS; ++i) {
258 packet = pack_udp_ipv4_packet(fragment_pool, ip_id++,
260 MTU + IP_HDR_LEN_MAX + 1);
262 fprintf(stderr,
"ERROR: pack_udp_ipv4_packet\n");
268 fprintf(stderr,
"ERROR: odp_packet_copy\n");
272 if (fragment_ipv4_packet(packet,
273 &fragment_buffer[total_fragments],
275 fprintf(stderr,
"ERROR: fragment_ipv4_packet\n");
279 total_fragments += num_fragments;
283 printf(
"\n= Shuffling %d fragments...\n", total_fragments);
284 shuffle(fragment_buffer, total_fragments);
287 for (i = 0; i < total_fragments; ++i) {
291 fprintf(stderr,
"ERROR: odp_queue_enq\n");
297 odph_thread_common_param_init(&thr_common);
298 thr_common.instance = instance;
299 thr_common.cpumask = &cpumask;
300 thr_common.share_param = 1;
302 odph_thread_param_init(&thr_param);
303 thr_param.start = run_worker;
307 memset(thread_tbl, 0,
sizeof(thread_tbl));
308 odph_thread_create(thread_tbl, &thr_common, &thr_param, num_workers);
311 printf(
"\n= Starting reassembly...\n");
315 odph_thread_join(thread_tbl, num_workers);
316 for (i = 0; i < num_workers; ++i)
317 printf(
"=== Thread %02d processed %3d fragments\n", i,
318 thread_stats[i].frags);
321 for (reassembled = 0; (ev =
odp_queue_deq(reassembled_pkts)) !=
323 assert(reassembled < NUM_PACKETS);
329 printf(
"\n= Checking reassembled packets...\n");
330 for (i = 0; i < reassembled; ++i) {
336 odph_ipv4hdr_t reassembled_hdr;
339 for (k = 0; k < reassembled; ++k) {
341 if (hdr.src_addr == reassembled_hdr.src_addr &&
342 hdr.dst_addr == reassembled_hdr.dst_addr &&
343 hdr.id == reassembled_hdr.id &&
344 hdr.proto == reassembled_hdr.proto) {
353 assert(!packet_memcmp(orig_pkts[j], packet, 0, 0, len));
355 printf(
"=== Successfully reassembled %d of %d packets\n", reassembled,
357 assert(reassembled == NUM_PACKETS);
358 printf(
"\n= Complete!\n");
361 for (i = 0; i < reassembled; ++i)
363 for (i = 0; i < NUM_PACKETS; ++i)
365 garbage_collect_fraglists(fraglists, FRAGLISTS, reassembled_pkts, 1);
373 "ERROR: fragment_pool destruction failed\n");
377 fprintf(stderr,
"ERROR: odp_term_local\n");
381 fprintf(stderr,
"ERROR: odp_term_global\n");
void odp_atomic_add_u32(odp_atomic_u32_t *atom, uint32_t val)
Add to atomic uint32 variable.
uint32_t odp_atomic_load_u32(odp_atomic_u32_t *atom)
Load value of atomic uint32 variable.
void odp_atomic_init_u128(odp_atomic_u128_t *atom, odp_u128_t val)
Initialize atomic odp_u128_t variable.
void odp_barrier_init(odp_barrier_t *barr, int count)
Initialize barrier with thread count.
void odp_barrier_wait(odp_barrier_t *barr)
Synchronize thread execution on barrier.
#define ODP_ALIGNED_CACHE
Defines type/struct/variable to be cache line size aligned.
#define ODP_UNUSED
Intentionally unused variables of functions.
uint16_t odp_u16be_t
unsigned 16bit big endian
int odp_cpumask_default_worker(odp_cpumask_t *mask, int num)
Default CPU mask for worker threads.
int odp_cpumask_first(const odp_cpumask_t *mask)
Find first set CPU in mask.
int32_t odp_cpumask_to_str(const odp_cpumask_t *mask, char *str, int32_t size)
Format a string from CPU mask.
#define ODP_CPUMASK_STR_SIZE
The maximum number of characters needed to record any CPU mask as a string (output of odp_cpumask_to_...
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.
odp_event_t odp_packet_to_event(odp_packet_t pkt)
Convert packet handle to event.
odp_packet_t odp_packet_copy(odp_packet_t pkt, odp_pool_t pool)
Full copy of a packet.
void * odp_packet_data(odp_packet_t pkt)
Packet data pointer.
void * odp_packet_user_area(odp_packet_t pkt)
User area address.
uint32_t odp_packet_len(odp_packet_t pkt)
Packet data length.
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.
#define ODP_PACKET_INVALID
Invalid packet.
int odp_packet_is_valid(odp_packet_t pkt)
Check that packet is valid.
odp_pool_t odp_pool_create(const char *name, const odp_pool_param_t *param)
Create a pool.
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.
void odp_queue_param_init(odp_queue_param_t *param)
Initialize queue params.
#define ODP_QUEUE_INVALID
Invalid queue.
odp_event_t odp_queue_deq(odp_queue_t queue)
Dequeue an event from a queue.
int odp_queue_enq(odp_queue_t queue, odp_event_t ev)
Enqueue an event to a queue.
odp_queue_t odp_queue_create(const char *name, const odp_queue_param_t *param)
Queue create.
int odp_queue_destroy(odp_queue_t queue)
Destroy ODP queue.
@ ODP_QUEUE_TYPE_PLAIN
Plain queue.
@ ODP_QUEUE_OP_MT_UNSAFE
Not multithread safe operation.
int odp_shm_free(odp_shm_t shm)
Free a contiguous block of shared memory.
#define ODP_SHM_INVALID
Invalid shared memory block.
void * odp_shm_addr(odp_shm_t shm)
Shared memory block address.
odp_shm_t odp_shm_reserve(const char *name, uint64_t size, uint64_t align, uint32_t flags)
Reserve a contiguous block of shared memory.
int odp_thread_id(void)
Get thread identifier.
@ ODP_THREAD_WORKER
Worker thread.
@ ODP_THREAD_CONTROL
Control thread.
uint64_t odp_time_to_ns(odp_time_t time)
Convert time to nanoseconds.
odp_time_t odp_time_global(void)
Current global time.
uint32_t uarea_size
Minimum user area size in bytes.
uint32_t num
Number of buffers in the pool.
odp_pool_type_t type
Pool type.
uint32_t len
Minimum length of 'num' packets.
uint32_t seg_len
Minimum number of packet data bytes that can be stored in the first segment of a newly allocated pack...
struct odp_pool_param_t::@126 pkt
Parameters for packet pools.
odp_queue_op_mode_t enq_mode
Enqueue mode.
odp_queue_type_t type
Queue type.
odp_queue_op_mode_t deq_mode
Dequeue mode.