15 #ifndef __included_ioam_export_h__ 16 #define __included_ioam_export_h__ 82 #define DEFAULT_EXPORT_SIZE (3 * CLIB_CACHE_LINE_BYTES) 87 #define DEFAULT_EXPORT_RECORDS 7 170 for (i = 0; i < no_of_threads; i++)
174 memset (eb, 0,
sizeof (*eb));
188 #define IPFIX_IOAM_EXPORT_ID 272 244 udp->
src_port = clib_host_to_net_u16 (4939 );
245 udp->
dst_port = clib_host_to_net_u16 (4939);
259 DEFAULT_EXPORT_SIZE)));
265 DEFAULT_EXPORT_SIZE)));
271 DEFAULT_EXPORT_SIZE));
341 #define EXPORT_TIMEOUT (20.0) 342 #define THREAD_PERIOD (30.0) 351 uword *event_data = 0;
354 u32 *vec_buffer_indices = 0;
355 u32 *vec_buffer_to_be_sent = 0;
356 u32 *thread_index = 0;
357 u32 new_pool_index = 0;
364 clib_warning (
"bogus kickoff event received, %d", event_type);
391 if (*em->
lockp[i] == 1)
399 memset (new_eb, 0,
sizeof (*new_eb));
403 vec_add (vec_buffer_indices, &new_pool_index, 1);
416 if (vec_len (thread_index) != 0)
421 for (i = 0; i <
vec_len (thread_index); i++)
423 while (__sync_lock_test_and_set (em->
lockp[thread_index[i]], 1))
427 *em->
lockp[thread_index[
i]] = 0;
431 for (i = 0; i <
vec_len (vec_buffer_to_be_sent); i++)
442 for (i = 0; i <
vec_len (vec_buffer_indices); i++)
455 #define ioam_export_node_common(EM, VM, N, F, HTYPE, L, V, NEXT) \ 457 u32 n_left_from, *from, *to_next; \ 458 export_next_t next_index; \ 459 u32 pkts_recorded = 0; \ 460 ioam_export_buffer_t *my_buf = 0; \ 461 vlib_buffer_t *eb0 = 0; \ 463 from = vlib_frame_vector_args (F); \ 464 n_left_from = (F)->n_vectors; \ 465 next_index = (N)->cached_next_index; \ 466 while (__sync_lock_test_and_set ((EM)->lockp[(VM)->cpu_index], 1)); \ 467 my_buf = ioam_export_get_my_buffer (EM, (VM)->cpu_index); \ 468 my_buf->touched_at = vlib_time_now (VM); \ 469 while (n_left_from > 0) \ 471 u32 n_left_to_next; \ 472 vlib_get_next_frame (VM, N, next_index, to_next, n_left_to_next); \ 473 while (n_left_from >= 4 && n_left_to_next >= 2) \ 479 vlib_buffer_t *p0, *p1; \ 480 u32 ip_len0, ip_len1; \ 482 vlib_buffer_t *p2, *p3; \ 483 p2 = vlib_get_buffer (VM, from[2]); \ 484 p3 = vlib_get_buffer (VM, from[3]); \ 485 vlib_prefetch_buffer_header (p2, LOAD); \ 486 vlib_prefetch_buffer_header (p3, LOAD); \ 487 CLIB_PREFETCH (p2->data, 3 * CLIB_CACHE_LINE_BYTES, LOAD); \ 488 CLIB_PREFETCH (p3->data, 3 * CLIB_CACHE_LINE_BYTES, LOAD); \ 490 to_next[0] = bi0 = from[0]; \ 491 to_next[1] = bi1 = from[1]; \ 495 n_left_to_next -= 2; \ 496 p0 = vlib_get_buffer (VM, bi0); \ 497 p1 = vlib_get_buffer (VM, bi1); \ 498 ip0 = vlib_buffer_get_current (p0); \ 499 ip1 = vlib_buffer_get_current (p1); \ 501 clib_net_to_host_u16 (ip0->L) + sizeof (HTYPE); \ 503 clib_net_to_host_u16 (ip1->L) + sizeof (HTYPE); \ 504 ebi0 = my_buf->buffer_index; \ 505 eb0 = vlib_get_buffer (VM, ebi0); \ 506 if (PREDICT_FALSE (eb0 == 0)) \ 509 ip_len0 > DEFAULT_EXPORT_SIZE ? DEFAULT_EXPORT_SIZE : ip_len0; \ 511 ip_len1 > DEFAULT_EXPORT_SIZE ? DEFAULT_EXPORT_SIZE : ip_len1; \ 512 copy3cachelines (eb0->data + eb0->current_length, ip0, ip_len0); \ 513 eb0->current_length += DEFAULT_EXPORT_SIZE; \ 514 my_buf->records_in_this_buffer++; \ 515 if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS) \ 517 ioam_export_send_buffer (EM, VM, my_buf); \ 518 ioam_export_init_buffer (EM, VM, my_buf); \ 520 ebi0 = my_buf->buffer_index; \ 521 eb0 = vlib_get_buffer (VM, ebi0); \ 522 if (PREDICT_FALSE (eb0 == 0)) \ 524 copy3cachelines (eb0->data + eb0->current_length, ip1, ip_len1); \ 525 eb0->current_length += DEFAULT_EXPORT_SIZE; \ 526 my_buf->records_in_this_buffer++; \ 527 if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS) \ 529 ioam_export_send_buffer (EM, VM, my_buf); \ 530 ioam_export_init_buffer (EM, VM, my_buf); \ 532 pkts_recorded += 2; \ 533 if (PREDICT_FALSE (((node)->flags & VLIB_NODE_FLAG_TRACE))) \ 535 if (p0->flags & VLIB_BUFFER_IS_TRACED) \ 537 export_trace_t *t = \ 538 vlib_add_trace (VM, node, p0, sizeof (*t)); \ 540 clib_net_to_host_u32 (ip0->V); \ 541 t->next_index = next0; \ 543 if (p1->flags & VLIB_BUFFER_IS_TRACED) \ 545 export_trace_t *t = \ 546 vlib_add_trace (VM, N, p1, sizeof (*t)); \ 548 clib_net_to_host_u32 (ip1->V); \ 549 t->next_index = next1; \ 553 vlib_validate_buffer_enqueue_x2 (VM, N, next_index, \ 554 to_next, n_left_to_next, \ 555 bi0, bi1, next0, next1); \ 557 while (n_left_from > 0 && n_left_to_next > 0) \ 569 n_left_to_next -= 1; \ 570 p0 = vlib_get_buffer (VM, bi0); \ 571 ip0 = vlib_buffer_get_current (p0); \ 573 clib_net_to_host_u16 (ip0->L) + sizeof (HTYPE); \ 574 ebi0 = my_buf->buffer_index; \ 575 eb0 = vlib_get_buffer (VM, ebi0); \ 576 if (PREDICT_FALSE (eb0 == 0)) \ 579 ip_len0 > DEFAULT_EXPORT_SIZE ? DEFAULT_EXPORT_SIZE : ip_len0; \ 580 copy3cachelines (eb0->data + eb0->current_length, ip0, ip_len0); \ 581 eb0->current_length += DEFAULT_EXPORT_SIZE; \ 582 my_buf->records_in_this_buffer++; \ 583 if (my_buf->records_in_this_buffer >= DEFAULT_EXPORT_RECORDS) \ 585 ioam_export_send_buffer (EM, VM, my_buf); \ 586 ioam_export_init_buffer (EM, VM, my_buf); \ 588 if (PREDICT_FALSE (((N)->flags & VLIB_NODE_FLAG_TRACE) \ 589 && (p0->flags & VLIB_BUFFER_IS_TRACED))) \ 591 export_trace_t *t = vlib_add_trace (VM, (N), p0, sizeof (*t)); \ 593 clib_net_to_host_u32 (ip0->V); \ 594 t->next_index = next0; \ 596 pkts_recorded += 1; \ 598 vlib_validate_buffer_enqueue_x1 (VM, N, next_index, \ 599 to_next, n_left_to_next, \ 602 vlib_put_next_frame (VM, N, next_index, n_left_to_next); \ 604 vlib_node_increment_counter (VM, export_node.index, \ 605 EXPORT_ERROR_RECORDED, pkts_recorded); \ 606 *(EM)->lockp[(VM)->cpu_index] = 0; \
sll srl srl sll sra u16x4 i
#define DEFAULT_EXPORT_RECORDS
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Fixed length block allocator.
u32 export_process_node_index
static f64 vlib_time_now(vlib_main_t *vm)
static int ioam_export_send_buffer(ioam_export_main_t *em, vlib_main_t *vm, ioam_export_buffer_t *eb)
vlib_node_registration_t export_node
(constructor) VLIB_REGISTER_NODE (export_node)
struct _vlib_node_registration vlib_node_registration_t
static int ioam_export_header_create(ioam_export_main_t *em, ip4_address_t *collector_address, ip4_address_t *src_address)
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
ip4_address_t ipfix_collector
#define vec_pop(V)
Returns last element of a vector and decrements its length.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
vlib_node_registration_t ip4_lookup_node
(constructor) VLIB_REGISTER_NODE (ip4_lookup_node)
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
ioam_export_main_t vxlan_gpe_ioam_export_main
static uword ioam_export_process_common(ioam_export_main_t *em, vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f, u32 index)
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
static int ioam_export_buffer_add_header(ioam_export_main_t *em, vlib_buffer_t *b0)
#define pool_alloc_aligned(P, N, A)
Allocate N more free elements to pool (general version).
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
ioam_export_buffer_t * buffer_pool
ipfix_data_packet_t ipfix
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
struct ioam_export_buffer ioam_export_buffer_t
#define clib_warning(format, args...)
#define IPFIX_IOAM_EXPORT_ID
vlib_node_registration_t vxlan_export_node
(constructor) VLIB_REGISTER_NODE (vxlan_export_node)
vlib_worker_thread_t * vlib_worker_threads
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
u16 current_length
Nbytes between current data and the end of this buffer.
#define pool_put(P, E)
Free an object E in pool P.
static void ioam_export_header_cleanup(ioam_export_main_t *em, ip4_address_t *collector_address, ip4_address_t *src_address)
void vlib_put_frame_to_node(vlib_main_t *vm, u32 to_node_index, vlib_frame_t *f)
static u32 version_length(u16 length)
static void ioam_export_thread_buffer_free(ioam_export_main_t *em)
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P (general version).
u8 records_in_this_buffer
#define pool_free(p)
Free a pool.
#define vec_free(V)
Free vector's memory (no header).
ip4_address_t src_address
#define clib_memcpy(a, b, c)
#define VLIB_BUFFER_TOTAL_LENGTH_VALID
static ioam_export_buffer_t * ioam_export_get_my_buffer(ioam_export_main_t *em, u32 thread_id)
void vlib_buffer_free(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Free buffers Frees the entire buffer chain for each buffer.
static void clib_mem_free(void *p)
u32 vlib_buffer_alloc(vlib_main_t *vm, u32 *buffers, u32 n_buffers)
Allocate buffers into supplied array.
static u32 ipfix_set_id_length(u16 set_id, u16 length)
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static int ioam_export_init_buffer(ioam_export_main_t *em, vlib_main_t *vm, ioam_export_buffer_t *eb)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
#define ip_csum_update(sum, old, new, type, field)
#define DEFAULT_EXPORT_SIZE
static void * clib_mem_alloc_aligned(uword size, uword align)
static int ioam_export_thread_buffer_init(ioam_export_main_t *em, vlib_main_t *vm)
vlib_frame_t * vlib_get_frame_to_node(vlib_main_t *vm, u32 to_node_index)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
u32 ip4_lookup_node_index
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
static u16 ip4_header_checksum(ip4_header_t *i)
static u16 ip_csum_fold(ip_csum_t c)
ioam_export_main_t ioam_export_main