FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
ioam_cache.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2017 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  *------------------------------------------------------------------
17  * ioam_cache.c - ioam ip6 API / debug CLI handling
18  *------------------------------------------------------------------
19  */
20 
21 #include <vnet/vnet.h>
22 #include <vnet/plugin/plugin.h>
23 #include <ioam/ip6/ioam_cache.h>
24 
25 #include <vlibapi/api.h>
26 #include <vlibmemory/api.h>
27 #include <vnet/ip/ip6_hop_by_hop.h>
28 
29 #include "ioam_cache.h"
30 
31 /* define message IDs */
32 #include <ioam/ip6/ioam_cache.api_enum.h>
33 #include <ioam/ip6/ioam_cache.api_types.h>
34 
35 #define REPLY_MSG_ID_BASE cm->msg_id_base
37 
39 
40 static u8 *
42 {
43  ioam_e2e_id_option_t *e2e = (ioam_e2e_id_option_t *) opt;
44 
45  if (e2e)
46  {
47  s =
48  format (s, "IP6_HOP_BY_HOP E2E ID = %U\n", format_ip6_address,
49  &(e2e->id));
50  }
51 
52 
53  return s;
54 }
55 
56 static u8 *
58 {
59  ioam_e2e_cache_option_t *e2e = (ioam_e2e_cache_option_t *) opt;
60 
61  if (e2e)
62  {
63  s =
64  format (s, "IP6_HOP_BY_HOP E2E CACHE = pool:%d idx:%d\n",
65  e2e->pool_id, e2e->pool_index);
66  }
67 
68 
69  return s;
70 }
71 
72 /* Action function shared between message handler and debug CLI */
73 int
75  ip6_address_t * sr_localsid, u8 is_disable)
76 {
77  vlib_main_t *vm = em->vlib_main;
78 
79  if (is_disable == 0)
80  {
82  em->sr_localsid_cache.as_u64[0] = sr_localsid->as_u64[0];
83  em->sr_localsid_cache.as_u64[1] = sr_localsid->as_u64[1];
89 
90  }
91  else
92  {
95  em->sr_localsid_cache.as_u64[0] = 0;
96  em->sr_localsid_cache.as_u64[1] = 0;
99  }
100 
101  return 0;
102 }
103 
104 /* Action function shared between message handler and debug CLI */
105 int
107  u8 criteria,
108  u8 no_of_responses,
109  ip6_address_t * sr_localsid,
110  u8 is_disable)
111 {
112  vlib_main_t *vm = em->vlib_main;
113 
114  if (is_disable == 0)
115  {
117  em->criteria_oneway = criteria;
118  em->wait_for_responses = no_of_responses;
119  em->sr_localsid_ts.as_u64[0] = sr_localsid->as_u64[0];
120  em->sr_localsid_ts.as_u64[1] = sr_localsid->as_u64[1];
127 
128  /* Turn on the cleanup process */
129  // vlib_process_signal_event (vm, em->cleanup_process_node_index, 1, 0);
130  }
131  else
132  {
135  em->sr_localsid_ts.as_u64[0] = 0;
136  em->sr_localsid_ts.as_u64[1] = 0;
141  }
142 
143  return 0;
144 }
145 
146 /* API message handler */
149 {
150  vl_api_ioam_cache_ip6_enable_disable_reply_t *rmp;
152  ip6_address_t sr_localsid;
153  int rv;
154 
155  sr_localsid.as_u64[0] = 0;
156  sr_localsid.as_u64[1] = 0;
157  rv =
158  ioam_cache_ip6_enable_disable (cm, &sr_localsid, (int) (mp->is_disable));
159  REPLY_MACRO (VL_API_IOAM_CACHE_IP6_ENABLE_DISABLE_REPLY);
160 }
161 
162 static clib_error_t *
164  unformat_input_t * input, vlib_cli_command_t * cmd)
165 {
167  u8 is_disable = 0;
168  ip6_address_t sr_localsid;
169  u8 address_set = 0;
170 
172  {
173  if (unformat (input, "disable"))
174  is_disable = 1;
175  else if (!address_set
176  && unformat (input, "sr_localsid %U", unformat_ip6_address,
177  &sr_localsid))
178  address_set = 1;
179  else
180  break;
181  }
182 
183  if (is_disable == 0 && !address_set)
184  return clib_error_return (0, "Error: SRv6 LocalSID address is mandatory");
185 
186  ioam_cache_ip6_enable_disable (em, &sr_localsid, is_disable);
187 
188  return 0;
189 }
190 
191 /* *INDENT_OFF* */
192 VLIB_CLI_COMMAND (set_ioam_cache_command, static) =
193 {
194 .path = "set ioam ip6 cache",.short_help =
195  "set ioam ip6 cache sr_localsid <ip6 address> [disable]",.function =
197 /* *INDENT_ON* */
198 
199 #define IOAM_TS_WAIT_FOR_RESPONSES 3
200 static clib_error_t *
202  unformat_input_t * input,
203  vlib_cli_command_t * cmd)
204 {
206  u8 is_disable = 0;
207  u8 one_way = 0;
208  ip6_address_t sr_localsid;
209  u8 address_set = 0;
210  u8 no_of_responses = IOAM_TS_WAIT_FOR_RESPONSES;
211 
213  {
214  if (unformat (input, "disable"))
215  is_disable = 1;
216  else if (unformat (input, "rtt"))
217  one_way = 0;
218  else if (unformat (input, "oneway"))
219  one_way = 1;
220  else if (unformat (input, "wait_for_responses %d", &no_of_responses))
221  ;
222  else if (!address_set
223  && unformat (input, "sr_localsid %U", unformat_ip6_address,
224  &sr_localsid))
225  address_set = 1;
226  else
227  break;
228  }
229  if (is_disable == 0 && !address_set)
230  return clib_error_return (0,
231  "Error: SRv6 LocalSID address is mandatory to receive response.");
232 
233  ioam_tunnel_select_ip6_enable_disable (em, one_way, no_of_responses,
234  &sr_localsid, is_disable);
235 
236  return 0;
237 }
238 
239 /* *INDENT_OFF* */
240 VLIB_CLI_COMMAND (set_ioam_cache_ts_command, static) =
241 {
242 .path = "set ioam ip6 sr-tunnel-select",.short_help =
243  "set ioam ip6 sr-tunnel-select [disable] [oneway|rtt] [wait_for_responses <n|default 3>] \
244  [sr_localsid <ip6 address>]",.function = set_ioam_tunnel_select_command_fn};
245 /* *INDENT_ON* */
246 
247 static void
249 {
251  ioam_cache_entry_t *entry = 0;
252  ioam_cache_ts_entry_t *ts_entry = 0;
253  int no_of_threads = vec_len (vlib_worker_threads);
254  int i;
255 
256  pool_foreach (entry, cm->ioam_rewrite_pool, (
257  {
258  vlib_cli_output (vm, "%U",
259  format_ioam_cache_entry,
260  entry);
261  }));
262 
263  if (cm->ts_stats)
264  for (i = 0; i < no_of_threads; i++)
265  {
266  vlib_cli_output (vm, "Number of entries in thread-%d selection pool: %lu\n \
267  (pool found to be full: %lu times)", i,
268  cm->ts_stats[i].inuse, cm->ts_stats[i].add_failed);
269 
270  if (verbose == 1)
272  pool_foreach (ts_entry, cm->ioam_ts_pool[i], (
273  {
274  vlib_cli_output (vm,
275  "%U",
276  format_ioam_cache_ts_entry,
277  ts_entry,
278  (u32)
279  i);
280  }
281  ));
283  }
284 
285 }
286 
287 static clib_error_t *
289  unformat_input_t * input,
290  vlib_cli_command_t * cmd)
291 {
292  u8 verbose = 0;
293 
295  {
296  if (unformat (input, "verbose"))
297  verbose = 1;
298  else
299  return clib_error_return (0, "unknown input `%U'",
300  format_unformat_error, input);
301  }
302  ioam_cache_table_print (vm, verbose);
303 
304 
305  return 0;
306 }
307 
308 /* *INDENT_OFF* */
309 VLIB_CLI_COMMAND (show_ioam_cache_command, static) =
310 {
311 .path = "show ioam ip6 cache",.short_help =
312  "show ioam ip6 cache [verbose]",.function = show_ioam_cache_command_fn};
313 /* *INDENT_ON* */
314 
315 #include <ioam/ip6/ioam_cache.api.c>
316 static clib_error_t *
318 {
319  vlib_node_t *node;
321  u32 cache_node_index = ioam_cache_node.index;
322  u32 ts_node_index = ioam_cache_ts_node.index;
323  vlib_node_t *ip6_hbyh_node = NULL, *ip6_hbh_pop_node = NULL, *error_node =
324  NULL;
325 
326  clib_memset (&ioam_cache_main, 0, sizeof (ioam_cache_main));
327  /* Ask for a correctly-sized block of API message decode slots */
329 
330  /* Hook this node to ip6-hop-by-hop */
331  ip6_hbyh_node = vlib_get_node_by_name (vm, (u8 *) "ip6-hop-by-hop");
332  em->cache_hbh_slot =
333  vlib_node_add_next (vm, ip6_hbyh_node->index, cache_node_index);
334  em->ts_hbh_slot =
335  vlib_node_add_next (vm, ip6_hbyh_node->index, ts_node_index);
336 
337  ip6_hbh_pop_node = vlib_get_node_by_name (vm, (u8 *) "ip6-pop-hop-by-hop");
338  em->ip6_hbh_pop_node_index = ip6_hbh_pop_node->index;
339 
340  error_node = vlib_get_node_by_name (vm, (u8 *) "error-drop");
341  em->error_node_index = error_node->index;
342  em->vlib_main = vm;
343 
344  node = vlib_get_node_by_name (vm, (u8 *) "ip6-add-from-cache-hop-by-hop");
346 
347  node = vlib_get_node_by_name (vm, (u8 *) "ip6-add-syn-hop-by-hop");
349 
350  return 0;
351 }
352 
354 
355 /*
356  * fd.io coding-style-patch-verification: ON
357  *
358  * Local Variables:
359  * eval: (c-set-style "gnu")
360  * End:
361  */
ip6_address_t sr_localsid_ts
Definition: ioam_cache.h:198
int ioam_tunnel_select_ip6_enable_disable(ioam_cache_main_t *em, u8 criteria, u8 no_of_responses, ip6_address_t *sr_localsid, u8 is_disable)
Definition: ioam_cache.c:106
static clib_error_t * set_ioam_cache_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ioam_cache.c:163
ioam_cache_entry_t * ioam_rewrite_pool
Definition: ioam_cache.h:172
static int ioam_cache_ts_table_init(vlib_main_t *vm)
Definition: ioam_cache.h:528
void ip6_hbh_set_next_override(uword next)
Definition: ip6_forward.c:2717
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 index
Definition: node.h:279
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:2725
#define IOAM_TS_WAIT_FOR_RESPONSES
Definition: ioam_cache.c:199
static int ioam_cache_table_init(vlib_main_t *vm)
Definition: ioam_cache.h:449
static int ioam_cache_table_destroy(vlib_main_t *vm)
Definition: ioam_cache.h:468
static clib_error_t * show_ioam_cache_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ioam_cache.c:288
vlib_main_t * vm
Definition: in2out_ed.c:1582
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1173
unsigned char u8
Definition: types.h:56
static clib_error_t * set_ioam_tunnel_select_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: ioam_cache.c:201
#define vlib_worker_thread_barrier_sync(X)
Definition: threads.h:205
Definition: ioam_cache.h:99
int ioam_cache_ip6_enable_disable(ioam_cache_main_t *em, ip6_address_t *sr_localsid, u8 is_disable)
Definition: ioam_cache.c:74
ip6_address_t sr_localsid_cache
Definition: ioam_cache.h:180
static int ip6_ioam_ts_cache_set_rewrite(void)
Definition: ioam_cache.h:853
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
static void vl_api_ioam_cache_ip6_enable_disable_t_handler(vl_api_ioam_cache_ip6_enable_disable_t *mp)
Definition: ioam_cache.c:148
#define clib_error_return(e, args...)
Definition: error.h:99
u32 ip6_reset_ts_hbh_node_index
Definition: ioam_cache.h:210
unsigned int u32
Definition: types.h:88
#define HBH_OPTION_TYPE_IOAM_EDGE_TO_EDGE_ID
Definition: ioam_cache.h:266
static u8 * ioam_e2e_cache_trace_handler(u8 *s, ip6_hop_by_hop_option_t *opt)
Definition: ioam_cache.c:57
vlib_node_registration_t ioam_cache_ts_node
(constructor) VLIB_REGISTER_NODE (ioam_cache_ts_node)
ioam_cache_ts_pool_stats_t * ts_stats
Definition: ioam_cache.h:188
int ip6_hbh_unregister_option(u8 option)
Definition: ip6_forward.c:2749
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:34
Definition: ioam_cache.h:125
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
ioam_cache_ts_entry_t ** ioam_ts_pool
Definition: ioam_cache.h:187
vlib_node_registration_t ioam_cache_node
(constructor) VLIB_REGISTER_NODE (ioam_cache_node)
static int ip6_ioam_ts_cache_cleanup_rewrite(void)
Definition: ioam_cache.h:892
struct _unformat_input_t unformat_input_t
u32 ip6_hbh_pop_node_index
Definition: ioam_cache.h:205
#define REPLY_MACRO(t)
unformat_function_t unformat_ip6_address
Definition: format.h:89
static clib_error_t * ioam_cache_init(vlib_main_t *vm)
Definition: ioam_cache.c:317
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
format_function_t format_ip6_address
Definition: format.h:91
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
vlib_main_t vlib_node_runtime_t * node
Definition: in2out_ed.c:1582
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
void ioam_cache_ts_timer_node_enable(vlib_main_t *vm, u8 enable)
static u8 * ioam_e2e_id_trace_handler(u8 *s, ip6_hop_by_hop_option_t *opt)
Definition: ioam_cache.c:41
static int ioam_cache_ts_table_destroy(vlib_main_t *vm)
Definition: ioam_cache.h:603
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
vlib_main_t * vlib_main
Definition: ioam_cache.h:201
ioam_cache_main_t ioam_cache_main
Definition: ioam_cache.c:38
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
void vlib_worker_thread_barrier_release(vlib_main_t *vm)
Definition: threads.c:1554
static void setup_message_id_table(snat_main_t *sm, api_main_t *am)
Definition: nat_api.c:2804
static void ioam_cache_table_print(vlib_main_t *vm, u8 verbose)
Definition: ioam_cache.c:248
u32 ip6_add_from_cache_hbh_node_index
Definition: ioam_cache.h:209
#define HBH_OPTION_TYPE_IOAM_E2E_CACHE_ID
Definition: ioam_cache.h:267
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171