FD.io VPP  v21.01.1
Vector Packet Processing
ip6_ioam_e2e.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2016 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 
16 #include <vlib/vlib.h>
17 #include <vnet/vnet.h>
18 #include <vppinfra/error.h>
19 
20 #include <vnet/ip/ip.h>
21 
22 #include <vppinfra/hash.h>
23 #include <vppinfra/error.h>
24 #include <vppinfra/elog.h>
25 
26 #include <vnet/ip/ip6_hop_by_hop.h>
27 #include "ip6_ioam_e2e.h"
28 
30 
33 {
34  ioam_e2e_option_t * e2e = (ioam_e2e_option_t *)opt;
35  u32 seqno = 0;
36 
37  if (e2e)
38  {
39  seqno = clib_net_to_host_u32 (e2e->e2e_hdr.e2e_data);
40  }
41 
42  s = format (s, "SeqNo = 0x%Lx", seqno);
43  return s;
44 }
45 
46 int
48 {
49  int *analyse = data;
50 
51  /* Register hanlders if enabled */
52  if (!disable)
53  {
54  /* If encap node register for encap handler */
55  if (0 == *analyse)
56  {
60  {
61  return (-1);
62  }
63  }
64  /* If analyze node then register for decap handler */
65  else
66  {
69  {
70  return (-1);
71  }
72  }
73  return 0;
74  }
75 
76  /* UnRegister handlers */
79  return 0;
80 }
81 
82 int
83 ioam_e2e_rewrite_handler (u8 *rewrite_string,
84  u8 *rewrite_size)
85 {
86  ioam_e2e_option_t *e2e_option;
87 
88  if (rewrite_string && *rewrite_size == sizeof(ioam_e2e_option_t))
89  {
90  e2e_option = (ioam_e2e_option_t *)rewrite_string;
91  e2e_option->hdr.type = HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE
93  e2e_option->hdr.length = sizeof (ioam_e2e_option_t) -
94  sizeof (ip6_hop_by_hop_option_t);
95  return(0);
96  }
97  return(-1);
98 }
99 
100 u32
102 {
104  u16 i;
105 
106  if (add)
107  {
108  pool_get(ioam_e2e_main.e2e_data, data);
109  data->flow_ctx = ctx;
111  return ((u32) (data - ioam_e2e_main.e2e_data));
112  }
113 
114  /* Delete case */
115  for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++)
116  {
117  if (pool_is_free_index(ioam_e2e_main.e2e_data, i))
118  continue;
119 
120  data = pool_elt_at_index(ioam_e2e_main.e2e_data, i);
121  if (data && (data->flow_ctx == ctx))
122  {
123  pool_put_index(ioam_e2e_main.e2e_data, i);
124  return (0);
125  }
126  }
127  return 0;
128 }
129 
130 static clib_error_t *
132  unformat_input_t * input,
133  vlib_cli_command_t * cmd)
134 {
135  ioam_e2e_data_t *e2e_data;
136  u8 *s = 0;
137  int i;
138 
139  vec_reset_length(s);
140 
141  s = format(0, "IOAM E2E information: \n");
142  for (i = 0; i < vec_len(ioam_e2e_main.e2e_data); i++)
143  {
144  if (pool_is_free_index(ioam_e2e_main.e2e_data, i))
145  continue;
146 
147  e2e_data = pool_elt_at_index(ioam_e2e_main.e2e_data, i);
148  s = format(s, "Flow name: %s\n", get_flow_name_from_flow_ctx(e2e_data->flow_ctx));
149 
151  &e2e_data->seqno_data,
152  !IOAM_DEAP_ENABLED(e2e_data->flow_ctx));
153  }
154 
155  vlib_cli_output(vm, "%v", s);
156  return 0;
157 }
158 
159 
160 VLIB_CLI_COMMAND (ioam_show_e2e_cmd, static) = {
161  .path = "show ioam e2e ",
162  .short_help = "show ioam e2e information",
163  .function = ioam_show_e2e_cmd_fn,
164 };
165 
166 /*
167  * Init handler E2E headet handling.
168  * Init hanlder registers encap, decap, trace and Rewrite handlers.
169  */
170 static clib_error_t *
172 {
173  /*
174  * As of now we have only PPC under E2E header.
175  */
178  {
179  return (clib_error_create("Registration of "
180  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed"));
181  }
182 
184  sizeof(ioam_e2e_option_t),
186  {
187  return (clib_error_create("Registration of "
188  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE for rewrite failed"));
189  }
190 
193  {
194  return (clib_error_create("Registration of "
195  "HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE Flow handler failed"));
196  }
197 
198  ioam_e2e_main.vlib_main = vm;
199  ioam_e2e_main.vnet_main = vnet_get_main();
200 
201  return (0);
202 }
203 
204 /*
205  * Init function for the E2E lib.
206  * ip6_hop_by_hop_ioam_e2e_init gets called during init.
207  */
208 /* *INDENT-OFF* */
210 {
211  .runs_after = VLIB_INITS("ip6_hop_by_hop_ioam_init"),
212 };
213 /* *INDENT-ON* */
int ioam_seqno_encap_handler(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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))
Definition: ip6_forward.c:2729
int ioam_seqno_decap_handler(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt)
void ioam_seqno_init_data(ioam_seqno_data *data)
vlib_main_t * vm
Definition: in2out_ed.c:1580
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:251
unsigned char u8
Definition: types.h:56
u8 data[128]
Definition: ipsec_types.api:90
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
int ip6_hbh_flow_handler_register(u8 option, u32 ioam_flow_handler(u32 flow_ctx, u8 add))
int ip6_hbh_pop_unregister_option(u8 option)
static u8 * ioam_e2e_trace_handler(u8 *s, ip6_hop_by_hop_option_t *opt)
Definition: ip6_ioam_e2e.c:31
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
#define HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE
int ip6_hbh_pop_register_option(u8 option, int options(vlib_buffer_t *b, ip6_header_t *ip, ip6_hop_by_hop_option_t *opt))
description fragment has unexpected format
Definition: map.api:433
vnet_main_t * vnet_main
Definition: ip6_ioam_e2e.h:38
unsigned int u32
Definition: types.h:88
#define clib_error_create(args...)
Definition: error.h:96
int ip6_hbh_unregister_option(u8 option)
Definition: ip6_forward.c:2753
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:546
long ctx[MAX_CONNS]
Definition: main.c:144
struct _unformat_input_t unformat_input_t
unsigned short u16
Definition: types.h:57
static clib_error_t * ioam_e2e_init(vlib_main_t *vm)
Definition: ip6_ioam_e2e.c:171
vlib_main_t * vlib_main
Definition: ip6_ioam_e2e.h:37
The fine-grained event logger allows lightweight, thread-safe event logging at minimum cost...
u32 ioam_e2e_flow_handler(u32 ctx, u8 add)
Definition: ip6_ioam_e2e.c:101
int ip6_hbh_config_handler_register(u8 option, int config_handler(void *data, u8 disable))
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:298
ioam_seqno_data seqno_data
Definition: ip6_ioam_e2e.h:32
ioam_e2e_main_t ioam_e2e_main
Definition: ip6_ioam_e2e.c:29
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:330
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
u8 * show_ioam_seqno_cmd_fn(u8 *s, ioam_seqno_data *seqno_data, u8 enc)
u8 * get_flow_name_from_flow_ctx(u32 flow_ctx)
int ioam_e2e_config_handler(void *data, u8 disable)
Definition: ip6_ioam_e2e.c:47
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static clib_error_t * ioam_show_e2e_cmd_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ip6_ioam_e2e.c:131
ioam_e2e_data_t * e2e_data
Definition: ip6_ioam_e2e.h:36
int ioam_e2e_rewrite_handler(u8 *rewrite_string, u8 *rewrite_size)
Definition: ip6_ioam_e2e.c:83
#define HBH_OPTION_TYPE_SKIP_UNKNOWN
#define IOAM_DEAP_ENABLED(opaque_data)
int ip6_hbh_add_register_option(u8 option, u8 size, int rewrite_options(u8 *rewrite_string, u8 *rewrite_size))
#define VLIB_INITS(...)
Definition: init.h:357