37 #define foreach_ip6_hbyh_ioam_input_next \ 38 _(IP6_REWRITE, "ip6-rewrite") \ 39 _(IP6_LOOKUP, "ip6-lookup") \ 43 #define _(s,n) IP6_HBYH_IOAM_INPUT_NEXT_##s, 57 u8 trace_data_size = 0;
70 return trace_data_size;
75 u32 *elt = va_arg (*args,
u32 *);
76 u8 *trace_type_p = va_arg (*args,
u8 *);
77 u8 trace_type = *trace_type_p;
82 u32 ttl_node_id_host_byte_order = clib_net_to_host_u32 (*elt);
83 s =
format (s,
"ttl 0x%x node id 0x%x ",
84 ttl_node_id_host_byte_order>>24,
85 ttl_node_id_host_byte_order & 0x00FFFFFF);
92 u32 ingress_host_byte_order = clib_net_to_host_u32(*elt);
93 s =
format (s,
"ingress 0x%x egress 0x%x ",
94 ingress_host_byte_order >> 16,
95 ingress_host_byte_order &0xFFFF);
101 u32 ts_in_host_byte_order = clib_net_to_host_u32 (*elt);
102 s =
format (s,
"ts 0x%x \n", ts_in_host_byte_order);
108 u32 appdata_in_host_byte_order = clib_net_to_host_u32 (*elt);
109 s =
format (s,
"app 0x%x ", appdata_in_host_byte_order);
119 ioam_trace_option_t *
trace;
120 u8 trace_data_size_in_words = 0;
124 trace = (ioam_trace_option_t *)opt;
126 s =
format (s,
" Trace Type 0x%x , %d elts left ts msb(s) 0x%x\n", trace->ioam_trace_type, trace->data_list_elts_left,
129 s =
format (s,
" Trace Type 0x%x , %d elts left\n", trace->ioam_trace_type, trace->data_list_elts_left);
131 elt = &trace->elts[0];
132 while ((
u8 *) elt < ((
u8 *)(&trace->elts[0]) + trace->hdr.length - 2
134 s =
format (s,
" [%d] %U\n",elt_index,
136 elt, &trace->ioam_trace_type);
138 elt += trace_data_size_in_words;
150 ioam_trace_option_t *
trace = (ioam_trace_option_t *)opt;
160 trace->data_list_elts_left--;
165 elt = &trace->elts[elt_index];
172 *elt = (
vnet_buffer(b)->sw_if_index[
VLIB_RX]&0xFFFF) << 16 | (adj->rewrite_header.sw_if_index & 0xFFFF);
173 *elt = clib_host_to_net_u32(*elt);
182 *elt = clib_host_to_net_u32(time_u64.
as_u32[0]);
188 *elt = clib_host_to_net_u32(hm->
app_data);
199 int rewrite_options(
u8 *rewrite_string,
u8 rewrite_size))
243 s =
format (s,
"IP6_ADD_HOP_BY_HOP: next index %d",
250 #define foreach_ip6_add_hop_by_hop_error \ 251 _(PROCESSED, "Pkts w/ added ip6 hop-by-hop options") 254 #define _(sym,str) IP6_ADD_HOP_BY_HOP_ERROR_##sym, 261 #define _(sym,string) string, 272 u32 n_left_from, * from, * to_next;
282 while (n_left_from > 0)
287 to_next, n_left_to_next);
290 while (n_left_from >= 4 && n_left_to_next >= 2)
292 u32 next0 = IP6_ADD_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
293 u32 next1 = IP6_ADD_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
294 u32 sw_if_index0, sw_if_index1;
315 to_next[0] = bi0 = from[0];
316 to_next[1] = bi1 = from[1];
343 t->sw_if_index = sw_if_index0;
350 t->sw_if_index = sw_if_index1;
357 to_next, n_left_to_next,
358 bi0, bi1, next0, next1);
362 while (n_left_from > 0 && n_left_to_next > 0)
369 u64 * copy_src0, * copy_dst0;
385 copy_dst0 = (
u64 *)(((
u8 *)ip0) - rewrite_length);
386 copy_src0 = (
u64 *) ip0;
388 copy_dst0 [0] = copy_src0 [0];
389 copy_dst0 [1] = copy_src0 [1];
390 copy_dst0 [2] = copy_src0 [2];
391 copy_dst0 [3] = copy_src0 [3];
392 copy_dst0 [4] = copy_src0 [4];
402 new_l0 = clib_net_to_host_u16 (ip0->
payload_length) + rewrite_length;
406 next0 = IP6_HBYH_IOAM_INPUT_NEXT_IP6_LOOKUP;
420 to_next, n_left_to_next,
428 IP6_ADD_HOP_BY_HOP_ERROR_PROCESSED, processed);
434 .name =
"ip6-add-hop-by-hop",
435 .vector_size =
sizeof (
u32),
439 .n_errors =
ARRAY_LEN(ip6_add_hop_by_hop_error_strings),
445 #define _(s,n) [IP6_HBYH_IOAM_INPUT_NEXT_##s] = n, 465 s =
format (s,
"IP6_POP_HOP_BY_HOP: next index %d",
504 #define foreach_ip6_pop_hop_by_hop_error \ 505 _(PROCESSED, "Pkts w/ removed ip6 hop-by-hop options") \ 506 _(NO_HOHO, "Pkts w/ no ip6 hop-by-hop options") \ 507 _(OPTION_FAILED, "ip6 pop hop-by-hop failed to process") 510 #define _(sym,str) IP6_POP_HOP_BY_HOP_ERROR_##sym, 516 static char * ip6_pop_hop_by_hop_error_strings[] = {
517 #define _(sym,string) string, 530 if (!hbh0 || !ip0)
return;
534 ((
u8 *)hbh0 + ((hbh0->
length+1)<<3));
537 while (opt0 < limit0)
553 IP6_POP_HOP_BY_HOP_ERROR_OPTION_FAILED, 1);
568 u32 n_left_from, * from, * to_next;
577 while (n_left_from > 0)
582 to_next, n_left_to_next);
585 while (n_left_from >= 4 && n_left_to_next >= 2)
587 u32 next0 = IP6_POP_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
588 u32 next1 = IP6_POP_HOP_BY_HOP_NEXT_INTERFACE_OUTPUT;
589 u32 sw_if_index0, sw_if_index1;
610 to_next[0] = bi0 = from[0];
611 to_next[1] = bi1 = from[1];
638 t->sw_if_index = sw_if_index0;
645 t->sw_if_index = sw_if_index1;
652 to_next, n_left_to_next,
653 bi0, bi1, next0, next1);
657 while (n_left_from > 0 && n_left_to_next > 0)
666 u64 * copy_dst0, * copy_src0;
697 copy_src0 = (
u64 *)ip0;
698 copy_dst0 = copy_src0 + (hbh0->
length+1);
699 copy_dst0 [4] = copy_src0[4];
700 copy_dst0 [3] = copy_src0[3];
701 copy_dst0 [2] = copy_src0[2];
702 copy_dst0 [1] = copy_src0[1];
703 copy_dst0 [0] = copy_src0[0];
716 to_next, n_left_to_next,
724 IP6_POP_HOP_BY_HOP_ERROR_PROCESSED, processed);
726 IP6_POP_HOP_BY_HOP_ERROR_NO_HOHO, no_header);
732 .name =
"ip6-pop-hop-by-hop",
733 .vector_size =
sizeof (
u32),
736 .sibling_of =
"ip6-lookup",
737 .n_errors =
ARRAY_LEN(ip6_pop_hop_by_hop_error_strings),
768 return (
clib_error_create(
"registration of HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST failed"));
776 int has_pot_option,
int has_ppc_option)
782 ioam_trace_option_t * trace_option;
784 u8 trace_data_size = 0;
788 if (trace_option_elts == 0 && has_pot_option == 0)
794 if (trace_option_elts)
799 if (trace_data_size == 0)
800 return VNET_API_ERROR_INVALID_VALUE;
802 if (trace_option_elts * trace_data_size > 254)
803 return VNET_API_ERROR_INVALID_VALUE;
805 size += trace_option_elts * trace_data_size;
814 rnd_size = (size + 7) & ~7;
821 hbh->
length = (rnd_size>>3) - 1;
822 current = (
u8 *)(hbh+1);
824 if (trace_option_elts)
826 trace_option = (ioam_trace_option_t *)current;
829 trace_option->hdr.length =
831 trace_option_elts * trace_data_size;
833 trace_option->data_list_elts_left = trace_option_elts;
834 current +=
sizeof (ioam_trace_option_t) +
835 trace_option_elts * trace_data_size;
874 .path =
"clear ioam rewrite",
875 .short_help =
"clear ioam rewrite",
881 u32 app_data,
int has_pot_option,
u32 trace_tsp,
887 has_pot_option, has_ppc_option);
914 u32 trace_option_elts = 0;
915 u32 trace_type = 0, node_id = 0;
917 int has_pot_option = 0;
918 int has_ppc_option = 0;
923 if (
unformat (input,
"trace-type 0x%x trace-elts %d " 924 "trace-tsp %d node-id 0x%x app-data 0x%x",
925 &trace_type, &trace_option_elts, &trace_tsp,
926 &node_id, &app_data))
930 else if (
unformat (input,
"ppc encap"))
932 else if (
unformat (input,
"ppc decap"))
934 else if (
unformat (input,
"ppc none"))
942 app_data, has_pot_option, trace_tsp, has_ppc_option);
949 .path =
"set ioam rewrite",
950 .short_help =
"set ioam rewrite trace-type <0x1f|0x3|0x9|0x11|0x19> trace-elts <nn> trace-tsp <0|1|2|3> node-id <node id in hex> app-data <app_data in hex> [pot] [ppc <encap|decap>]",
965 s =
format(s,
" REWRITE FLOW CONFIGS - \n");
966 s =
format(s,
" Destination Address : %U\n",
974 s =
format(s,
" REWRITE FLOW CONFIGS - Not configured\n");
979 s =
format(s,
" HOP BY HOP OPTIONS - TRACE CONFIG - \n");
980 s =
format(s,
" Trace Type : 0x%x (%d)\n",
986 s =
format(s,
" Num of trace nodes : %d\n",
988 s =
format(s,
" Node-id : 0x%x (%d)\n",
990 s =
format(s,
" App Data : 0x%x (%d)\n",
995 s =
format(s,
" HOP BY HOP OPTIONS - TRACE CONFIG - Not configured\n");
998 s =
format(s,
" POT OPTION - %d (%s)\n",
1001 s =
format(s,
"Try 'show ioam pot and show pot profile' for more information\n");
1003 s =
format(s,
" EDGE TO EDGE - PPC OPTION - %d (%s)\n",
1006 s =
format(s,
"Try 'show ioam ppc' for more information\n");
1014 .path =
"show ioam summary",
1015 .short_help =
"Summary of IOAM configuration",
1020 int is_add,
int is_pop,
int is_none)
1030 BVT(clib_bihash_kv) kv, value;
1032 if ((is_add + is_pop + is_none) != 1)
1033 return VNET_API_ERROR_INVALID_VALUE_2;
1039 return VNET_API_ERROR_NO_SUCH_FIB;
1045 for (i = 0; i < len; i++)
1050 if (dst_address_length != mask_width)
1055 kv.key[2] = ((
u64)((fib_index))<<32) | dst_address_length;
1057 rv = BV(clib_bihash_search_inline_2)(&im->ip6_lookup_table, &kv, &value);
1062 return VNET_API_ERROR_NO_SUCH_ENTRY;
1067 adj_index = value.value;
1078 if (is_add || is_pop)
1099 u32 mask_width = ~0;
1111 else if (
unformat (input,
"vrf-id %d", &vrf_id))
1123 if ((is_add + is_pop + is_none) != 1)
1125 if (mask_width == ~0)
1129 is_add, is_pop, is_none);
1143 .path =
"set ioam destination",
1144 .short_help =
"set ioam destination <ip6-address>/<width> add | pop | none",
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
static uword ip6_pop_hop_by_hop_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
void vlib_put_next_frame(vlib_main_t *vm, vlib_node_runtime_t *r, u32 next_index, u32 n_vectors_left)
Release pointer to next frame vector data.
ip_lookup_next_t
Common (IP4/IP6) next index stored in adjacency.
ip6_hop_by_hop_ioam_main_t ip6_hop_by_hop_ioam_main
void * ioam_end_of_path_cb
#define clib_error_return_code(e, code, flags, args...)
sll srl srl sll sra u16x4 i
static clib_error_t * ip6_set_ioam_destination_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u16 saved_lookup_next_index
Highest possible perf subgraph arc interposition, e.g.
int(* add_options[256])(u8 *rewrite_string, u8 rewrite_size)
static vlib_cli_command_t trace
(constructor) VLIB_CLI_COMMAND (trace)
bad routing header type(not 4)") sr_error (NO_MORE_SEGMENTS
static clib_error_t * ip6_show_ioam_summary_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
ip_lookup_next_t lookup_next_index
clib_error_t * ip6_ioam_trace_profile_set(u32 trace_option_elts, u32 trace_type, u32 node_id, u32 app_data, int has_pot_option, u32 trace_tsp, int has_ppc_option)
static f64 vlib_time_now(vlib_main_t *vm)
int ip6_hbh_register_option(u8 option, int options(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt), u8 *trace(u8 *s, ip6_hop_by_hop_option_t *opt))
static clib_error_t * ip6_set_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
struct _vlib_node_registration vlib_node_registration_t
static u8 * format_ip6_add_hop_by_hop_trace(u8 *s, va_list *args)
static f64 trace_tsp_mul[4]
static uword ip6_add_hop_by_hop_node_fn(vlib_main_t *vm, vlib_node_runtime_t *node, vlib_frame_t *frame)
int ip6_hbh_pop_unregister_option(u8 option)
vnet_main_t * vnet_get_main(void)
static char * ip6_add_hop_by_hop_error_strings[]
#define HBH_OPTION_TYPE_IOAM_PROOF_OF_TRANSIT
i16 current_data
signed offset in data[], pre_data[] that we are currently processing.
#define VLIB_INIT_FUNCTION(x)
static void * vlib_buffer_get_current(vlib_buffer_t *b)
Get pointer to current data to process.
#define BIT_ING_INTERFACE
ip6_pop_hop_by_hop_error_t
vlib_node_registration_t ip6_pop_hop_by_hop_node
(constructor) VLIB_REGISTER_NODE (ip6_pop_hop_by_hop_node)
VLIB_NODE_FUNCTION_MULTIARCH(ip6_pop_hop_by_hop_node, ip6_pop_hop_by_hop_node_fn)
#define foreach_ip6_pop_hop_by_hop_error
static u8 fetch_trace_data_size(u8 trace_type)
#define clib_error_create(args...)
#define vlib_validate_buffer_enqueue_x2(vm, node, next_index, to_next, n_left_to_next, bi0, bi1, next0, next1)
Finish enqueueing two buffers forward in the graph.
#define vlib_validate_buffer_enqueue_x1(vm, node, next_index, to_next, n_left_to_next, bi0, next0)
Finish enqueueing one buffer forward in the graph.
#define vlib_get_next_frame(vm, node, next_index, vectors, n_vectors_left)
Get pointer to next frame vector data by (vlib_node_runtime_t, next_index).
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
static void vlib_node_increment_counter(vlib_main_t *vm, u32 node_index, u32 counter_index, u64 increment)
uword * fib_index_by_table_id
ip6_address_t fib_masks[129]
static u8 * format_ip6_pop_hop_by_hop_trace(u8 *s, va_list *args)
#define CLIB_PREFETCH(addr, size, type)
#define vec_free(V)
Free vector's memory (no header).
int ip6_hbh_add_unregister_option(u8 option)
#define clib_memcpy(a, b, c)
static void vlib_buffer_advance(vlib_buffer_t *b, word l)
Advance current data pointer by the supplied (signed!) amount.
void vnet_register_ioam_end_of_path_callback(void *cb)
static char * ip6_pop_hop_by_hop_error_strings[]
ip_lookup_main_t lookup_main
int ip6_hbh_add_register_option(u8 option, u8 size, int rewrite_options(u8 *rewrite_string, u8 rewrite_size))
static u8 is_zero_ip6_address(ip6_address_t *a)
u8 * prefix_lengths_in_search_order
#define VLIB_NODE_FLAG_TRACE
static u8 * format_ioam_data_list_element(u8 *s, va_list *args)
#define HBH_OPTION_TYPE_IOAM_TRACE_DATA_LIST
#define foreach_ip6_hbyh_ioam_input_next
#define VLIB_BUFFER_IS_TRACED
static void ioam_pop_hop_by_hop_processing(vlib_main_t *vm, ip6_header_t *ip0, ip6_hop_by_hop_header_t *hbh0)
static void * vlib_add_trace(vlib_main_t *vm, vlib_node_runtime_t *r, vlib_buffer_t *b, u32 n_data_bytes)
VLIB_CLI_COMMAND(set_interface_ip_source_and_port_range_check_command, static)
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
ip6_hbyh_ioam_input_next_t
int(* pop_options[256])(ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
static void * vlib_frame_vector_args(vlib_frame_t *f)
Get pointer to frame vector data.
clib_error_t * clear_ioam_rewrite_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define HBH_OPTION_TYPE_DATA_CHANGE_ENROUTE
#define vlib_prefetch_buffer_header(b, type)
Prefetch buffer metadata.
#define TRACE_TYPE_IF_TS_APP
#define foreach_ip6_add_hop_by_hop_error
#define VLIB_REGISTER_NODE(x,...)
clib_error_t * clear_ioam_rewrite_fn(void)
int ip6_ioam_set_rewrite(u8 **rwp, u32 trace_type, u32 trace_option_elts, int has_pot_option, int has_ppc_option)
#define clib_error_return(e, args...)
#define CLIB_CACHE_LINE_BYTES
u32 flags
buffer flags: VLIB_BUFFER_IS_TRACED: trace this buffer.
int ip6_ioam_set_destination(ip6_address_t *addr, u32 mask_width, u32 vrf_id, int is_add, int is_pop, int is_none)
int ip6_hbh_pop_register_option(u8 option, int options(ip6_header_t *ip, ip6_hop_by_hop_option_t *opt))
static vlib_buffer_t * vlib_get_buffer(vlib_main_t *vm, u32 buffer_index)
Translate buffer index into buffer pointer.
vlib_node_registration_t ip6_add_hop_by_hop_node
(constructor) VLIB_REGISTER_NODE (ip6_add_hop_by_hop_node)
int ip6_hbh_ioam_trace_data_list_handler(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
static ip_adjacency_t * ip_get_adjacency(ip_lookup_main_t *lm, u32 adj_index)
#define TRACE_TYPE_TS_APP
ip6_add_hop_by_hop_error_t
u8 * ip6_hbh_ioam_trace_data_list_trace_handler(u8 *s, ip6_hop_by_hop_option_t *opt)