FD.io VPP  v21.06-3-gbb25fbf28
Vector Packet Processing
nsh_api.c
Go to the documentation of this file.
1 /*
2  * nsh_api.c - nsh mapping api
3  *
4  * Copyright (c) 2019 Cisco and/or its affiliates.
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at:
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  */
17 #include <vnet/vnet.h>
18 #include <vnet/plugin/plugin.h>
19 #include <nsh/nsh.h>
20 
21 #include <vlibapi/api.h>
22 #include <vlibmemory/api.h>
23 #include <vpp/app/version.h>
24 
25 /* define message IDs */
26 #define vl_msg_id(n,h) n,
27 typedef enum
28 {
29 #include <nsh/nsh.api.h>
30  /* We'll want to know how many messages IDs we need... */
32 } vl_msg_id_t;
33 #undef vl_msg_id
34 
35 /* define message structures */
36 #define vl_typedefs
37 #include <nsh/nsh.api.h>
38 #undef vl_typedefs
39 
40 /* define generated endian-swappers */
41 #define vl_endianfun
42 #include <nsh/nsh.api.h>
43 #undef vl_endianfun
44 
45 /* instantiate all the print functions we know about */
46 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
47 #define vl_printfun
48 #include <nsh/nsh.api.h>
49 #undef vl_printfun
50 
51 /* Get the API version number */
52 #define vl_api_version(n,v) static u32 api_version=(v);
53 #include <nsh/nsh.api.h>
54 #undef vl_api_version
55 
56 #define vl_msg_name_crc_list
57 #include <nsh/nsh.api.h>
58 #undef vl_msg_name_crc_list
59 
60 #define REPLY_MSG_ID_BASE nm->msg_id_base
62 
63 /* List of message types that this plugin understands */
64 
65 #define foreach_nsh_plugin_api_msg \
66  _(NSH_ADD_DEL_ENTRY, nsh_add_del_entry) \
67  _(NSH_ENTRY_DUMP, nsh_entry_dump) \
68  _(NSH_ADD_DEL_MAP, nsh_add_del_map) \
69  _(NSH_MAP_DUMP, nsh_map_dump)
70 
71 /**
72  * @brief CLI function for NSH admin up/down
73  *
74  * @param *vnm
75  * @param nsh_hw_if
76  * @param flag
77  *
78  * @return *rc
79  *
80  */
81 static clib_error_t *
83 {
85  vnet_hw_interface_set_flags (vnm, nsh_hw_if,
87  else
88  vnet_hw_interface_set_flags (vnm, nsh_hw_if, 0);
89 
90  return 0;
91 }
92 
93 /**
94  * @brief Naming for NSH tunnel
95  *
96  * @param *s formatting string
97  * @param *args
98  *
99  * @return *s formatted string
100  *
101  */
102 static u8 *
103 format_nsh_name (u8 * s, va_list * args)
104 {
105  u32 dev_instance = va_arg (*args, u32);
106  return format (s, "nsh_tunnel%d", dev_instance);
107 }
108 
109 /* *INDENT-OFF* */
110 VNET_DEVICE_CLASS (nsh_device_class, static) = {
111  .name = "NSH",
112  .format_device_name = format_nsh_name,
113  .admin_up_down_function = nsh_interface_admin_up_down,
114 };
115 /* *INDENT-ON* */
116 
117 static void send_nsh_entry_details
119 {
121  nsh_main_t *nm = &nsh_main;
122 
123  rmp = vl_msg_api_alloc (sizeof (*rmp));
124  clib_memset (rmp, 0, sizeof (*rmp));
125 
126  rmp->_vl_msg_id = ntohs ((VL_API_NSH_ENTRY_DETAILS) + nm->msg_id_base);
127  rmp->ver_o_c = t->nsh_base.ver_o_c;
128  rmp->ttl = (t->nsh_base.ver_o_c & NSH_TTL_H4_MASK) << 2 |
129  (t->nsh_base.length & NSH_TTL_L2_MASK) >> 6;
130  rmp->length = t->nsh_base.length & NSH_LEN_MASK;
131  rmp->md_type = t->nsh_base.md_type;
132  rmp->next_protocol = t->nsh_base.next_protocol;
133  rmp->nsp_nsi = htonl (t->nsh_base.nsp_nsi);
134 
135  if (t->nsh_base.md_type == 1)
136  {
137  rmp->tlv_length = 4;
138  rmp->c1 = htonl (t->md.md1_data.c1);
139  rmp->c2 = htonl (t->md.md1_data.c2);
140  rmp->c3 = htonl (t->md.md1_data.c3);
141  rmp->c4 = htonl (t->md.md1_data.c4);
142  }
143  else if (t->nsh_base.md_type == 2)
144  {
145  rmp->tlv_length = t->tlvs_len;
146  clib_memcpy (rmp->tlv, t->tlvs_data, t->tlvs_len);
147  }
148 
149  rmp->context = context;
150 
151  vl_api_send_msg (rp, (u8 *) rmp);
152 }
153 
154 static void send_nsh_map_details
156 {
158  nsh_main_t *nm = &nsh_main;
159 
160  rmp = vl_msg_api_alloc (sizeof (*rmp));
161  clib_memset (rmp, 0, sizeof (*rmp));
162 
163  rmp->_vl_msg_id = ntohs ((VL_API_NSH_MAP_DETAILS) + nm->msg_id_base);
164  rmp->nsp_nsi = htonl (t->nsp_nsi);
165  rmp->mapped_nsp_nsi = htonl (t->mapped_nsp_nsi);
166  rmp->nsh_action = htonl (t->nsh_action);
167  rmp->sw_if_index = htonl (t->sw_if_index);
168  rmp->rx_sw_if_index = htonl (t->rx_sw_if_index);
169  rmp->next_node = htonl (t->next_node);
170 
171  rmp->context = context;
172 
173  vl_api_send_msg (rp, (u8 *) rmp);
174 }
175 
176 static void
178 {
179  nsh_main_t *nm = &nsh_main;
180  nsh_map_t *t;
181  u32 map_index;
183 
185  if (rp == 0)
186  return;
187 
188  map_index = ntohl (mp->map_index);
189 
190  if (~0 == map_index)
191  {
192  pool_foreach (t, nm->nsh_mappings)
193  {
194  send_nsh_map_details (t, rp, mp->context);
195  }
196  }
197  else
198  {
199  if (map_index >= vec_len (nm->nsh_mappings))
200  {
201  return;
202  }
203  t = &nm->nsh_mappings[map_index];
204  send_nsh_map_details (t, rp, mp->context);
205  }
206 }
207 
208 /** API message handler */
209 static void
211 {
213  nsh_main_t *nm = &nsh_main;
214  int rv;
215  nsh_add_del_map_args_t _a, *a = &_a;
216  u32 map_index = ~0;
217 
218  a->is_add = mp->is_add;
219  a->map.nsp_nsi = ntohl (mp->nsp_nsi);
220  a->map.mapped_nsp_nsi = ntohl (mp->mapped_nsp_nsi);
221  a->map.nsh_action = ntohl (mp->nsh_action);
222  a->map.sw_if_index = ntohl (mp->sw_if_index);
223  a->map.rx_sw_if_index = ntohl (mp->rx_sw_if_index);
224  a->map.next_node = ntohl (mp->next_node);
225 
226  rv = nsh_add_del_map (a, &map_index);
227 
228  if ((a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN4)
229  | (a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN6))
230  {
232  }
233 
234  REPLY_MACRO2 (VL_API_NSH_ADD_DEL_MAP_REPLY, (
235  {
236  rmp->map_index =
237  htonl (map_index);
238  }
239  ));
240 }
241 
242 int
244 {
245  u8 *rw = 0;
246  int len = 0;
247  nsh_base_header_t *nsh_base;
248  nsh_md1_data_t *nsh_md1;
249  nsh_main_t *nm = &nsh_main;
250  nsh_md2_data_t *opt0;
251  nsh_md2_data_t *limit0;
252  nsh_md2_data_t *nsh_md2;
253  nsh_option_map_t _nsh_option, *nsh_option = &_nsh_option;
254  u8 old_option_size = 0;
255  u8 new_option_size = 0;
256 
257  vec_free (nsh_entry->rewrite);
258  if (nsh_entry->nsh_base.md_type == 1)
259  {
260  len = sizeof (nsh_base_header_t) + sizeof (nsh_md1_data_t);
261  }
262  else if (nsh_entry->nsh_base.md_type == 2)
263  {
264  /* set to maxim, maybe dataplane will add more TLVs */
266  }
268  clib_memset (rw, 0, len);
269 
270  nsh_base = (nsh_base_header_t *) rw;
271  nsh_base->ver_o_c = nsh_entry->nsh_base.ver_o_c;
272  nsh_base->length = nsh_entry->nsh_base.length;
273  nsh_base->md_type = nsh_entry->nsh_base.md_type;
274  nsh_base->next_protocol = nsh_entry->nsh_base.next_protocol;
275  nsh_base->nsp_nsi = clib_host_to_net_u32 (nsh_entry->nsh_base.nsp_nsi);
276 
277  if (nsh_base->md_type == 1)
278  {
279  nsh_md1 = (nsh_md1_data_t *) (rw + sizeof (nsh_base_header_t));
280  nsh_md1->c1 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c1);
281  nsh_md1->c2 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c2);
282  nsh_md1->c3 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c3);
283  nsh_md1->c4 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c4);
284  nsh_entry->rewrite_size = 24;
285  }
286  else if (nsh_base->md_type == 2)
287  {
288  opt0 = (nsh_md2_data_t *) (nsh_entry->tlvs_data);
289  limit0 = (nsh_md2_data_t *) ((u8 *) opt0 + nsh_entry->tlvs_len);
290 
291  nsh_md2 = (nsh_md2_data_t *) (rw + sizeof (nsh_base_header_t));
292  nsh_entry->rewrite_size = sizeof (nsh_base_header_t);
293 
294  while (opt0 < limit0)
295  {
296  old_option_size = sizeof (nsh_md2_data_t) + opt0->length;
297  /* round to 4-byte */
298  old_option_size = ((old_option_size + 3) >> 2) << 2;
299 
300  nsh_option = nsh_md2_lookup_option (opt0->class, opt0->type);
301  if (nsh_option == NULL)
302  {
303  goto next_tlv_md2;
304  }
305 
306  if (nm->add_options[nsh_option->option_id] != NULL)
307  {
308  if (0 != nm->add_options[nsh_option->option_id] ((u8 *) nsh_md2,
309  &new_option_size))
310  {
311  goto next_tlv_md2;
312  }
313 
314  /* round to 4-byte */
315  new_option_size = ((new_option_size + 3) >> 2) << 2;
316 
317  nsh_entry->rewrite_size += new_option_size;
318  nsh_md2 =
319  (nsh_md2_data_t *) (((u8 *) nsh_md2) + new_option_size);
320  opt0 = (nsh_md2_data_t *) (((u8 *) opt0) + old_option_size);
321  }
322  else
323  {
324  next_tlv_md2:
325  opt0 = (nsh_md2_data_t *) (((u8 *) opt0) + old_option_size);
326  }
327 
328  }
329  }
330 
331  nsh_entry->rewrite = rw;
332  nsh_base->length = (nsh_base->length & NSH_TTL_L2_MASK) |
333  ((nsh_entry->rewrite_size >> 2) & NSH_LEN_MASK);
334 
335  return 0;
336 }
337 
339 
340 /**
341  * Action function to add or del an nsh map.
342  * Shared by both CLI and binary API
343  **/
344 int
346 {
347  nsh_main_t *nm = &nsh_main;
348  vnet_main_t *vnm = nm->vnet_main;
349  nsh_map_t *map = 0;
350  u32 key, *key_copy;
351  uword *entry;
352  hash_pair_t *hp;
353  u32 map_index = ~0;
355  u32 nsh_hw_if = ~0;
356  u32 nsh_sw_if = ~0;
357 
358  /* net order, so data plane could use nsh header to lookup directly */
359  key = clib_host_to_net_u32 (a->map.nsp_nsi);
360 
361  entry = hash_get_mem (nm->nsh_mapping_by_key, &key);
362 
363  if (a->is_add)
364  {
365  /* adding an entry, must not already exist */
366  if (entry)
367  return -1; //TODO API_ERROR_INVALID_VALUE;
368 
369  pool_get_aligned (nm->nsh_mappings, map, CLIB_CACHE_LINE_BYTES);
370  clib_memset (map, 0, sizeof (*map));
371 
372  /* copy from arg structure */
373  map->nsp_nsi = a->map.nsp_nsi;
374  map->mapped_nsp_nsi = a->map.mapped_nsp_nsi;
375  map->nsh_action = a->map.nsh_action;
376  map->sw_if_index = a->map.sw_if_index;
377  map->rx_sw_if_index = a->map.rx_sw_if_index;
378  map->next_node = a->map.next_node;
379  map->adj_index = a->map.adj_index;
380 
381 
382  key_copy = clib_mem_alloc (sizeof (*key_copy));
383  clib_memcpy (key_copy, &key, sizeof (*key_copy));
384 
385  hash_set_mem (nm->nsh_mapping_by_key, key_copy, map - nm->nsh_mappings);
386  map_index = map - nm->nsh_mappings;
387 
388  if (vec_len (nm->free_nsh_tunnel_hw_if_indices) > 0)
389  {
390  nsh_hw_if = nm->free_nsh_tunnel_hw_if_indices
391  [vec_len (nm->free_nsh_tunnel_hw_if_indices) - 1];
392  _vec_len (nm->free_nsh_tunnel_hw_if_indices) -= 1;
393 
394  hi = vnet_get_hw_interface (vnm, nsh_hw_if);
395  hi->dev_instance = map_index;
396  hi->hw_instance = hi->dev_instance;
397  }
398  else
399  {
400  nsh_hw_if = vnet_register_interface
401  (vnm, nsh_device_class.index, map_index, nsh_hw_class.index,
402  map_index);
403  hi = vnet_get_hw_interface (vnm, nsh_hw_if);
404  hi->output_node_index = nsh_aware_vnf_proxy_node.index;
405  }
406 
407  map->nsh_hw_if = nsh_hw_if;
408  map->nsh_sw_if = nsh_sw_if = hi->sw_if_index;
409  vec_validate_init_empty (nm->tunnel_index_by_sw_if_index, nsh_sw_if,
410  ~0);
411  nm->tunnel_index_by_sw_if_index[nsh_sw_if] = key;
412 
413  vnet_sw_interface_set_flags (vnm, hi->sw_if_index,
415  }
416  else
417  {
418  if (!entry)
419  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
420 
421  map = pool_elt_at_index (nm->nsh_mappings, entry[0]);
422 
423  vnet_sw_interface_set_flags (vnm, map->nsh_sw_if,
425  vec_add1 (nm->free_nsh_tunnel_hw_if_indices, map->nsh_sw_if);
426  nm->tunnel_index_by_sw_if_index[map->nsh_sw_if] = ~0;
427 
428  hp = hash_get_pair (nm->nsh_mapping_by_key, &key);
429  key_copy = (void *) (hp->key);
430  hash_unset_mem (nm->nsh_mapping_by_key, &key);
431  clib_mem_free (key_copy);
432 
433  pool_put (nm->nsh_mappings, map);
434  }
435 
436  if (map_indexp)
437  *map_indexp = map_index;
438 
439  return 0;
440 }
441 
442 /**
443  * Action function to add or del an nsh-proxy-session.
444  * Shared by both CLI and binary API
445  **/
446 int
448 {
449  nsh_main_t *nm = &nsh_main;
450  nsh_proxy_session_t *proxy = 0;
451  nsh_proxy_session_by_key_t key, *key_copy;
452  uword *entry;
453  hash_pair_t *hp;
454  u32 nsp = 0, nsi = 0;
455 
456  clib_memset (&key, 0, sizeof (key));
457  key.transport_type = a->map.next_node;
458  key.transport_index = a->map.sw_if_index;
459 
460  entry = hash_get_mem (nm->nsh_proxy_session_by_key, &key);
461 
462  if (a->is_add)
463  {
464  /* adding an entry, must not already exist */
465  if (entry)
466  return -1; //TODO API_ERROR_INVALID_VALUE;
467 
468  pool_get_aligned (nm->nsh_proxy_sessions, proxy, CLIB_CACHE_LINE_BYTES);
469  clib_memset (proxy, 0, sizeof (*proxy));
470 
471  /* Nsi needs to minus 1 within NSH-Proxy */
472  nsp = (a->map.nsp_nsi >> NSH_NSP_SHIFT) & NSH_NSP_MASK;
473  nsi = a->map.nsp_nsi & NSH_NSI_MASK;
474  if (nsi == 0)
475  return -1;
476 
477  nsi = nsi - 1;
478  /* net order, so could use it to lookup nsh map table directly */
479  proxy->nsp_nsi = clib_host_to_net_u32 ((nsp << NSH_NSP_SHIFT) | nsi);
480 
481  key_copy = clib_mem_alloc (sizeof (*key_copy));
482  clib_memcpy (key_copy, &key, sizeof (*key_copy));
483 
484  hash_set_mem (nm->nsh_proxy_session_by_key, key_copy,
485  proxy - nm->nsh_proxy_sessions);
486  }
487  else
488  {
489  if (!entry)
490  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
491 
492  proxy = pool_elt_at_index (nm->nsh_proxy_sessions, entry[0]);
493  hp = hash_get_pair (nm->nsh_proxy_session_by_key, &key);
494  key_copy = (void *) (hp->key);
495  hash_unset_mem (nm->nsh_proxy_session_by_key, &key);
496  clib_mem_free (key_copy);
497 
498  pool_put (nm->nsh_proxy_sessions, proxy);
499  }
500 
501  return 0;
502 }
503 
504 /**
505  * Action function for adding an NSH entry
506  * nsh_add_del_entry_args_t *a: host order
507  */
508 int
510 {
511  nsh_main_t *nm = &nsh_main;
512  nsh_entry_t *nsh_entry = 0;
513  u32 key, *key_copy;
514  uword *entry_id;
515  hash_pair_t *hp;
516  u32 entry_index = ~0;
517  u8 tlvs_len = 0;
518  u8 *data = 0;
519 
520  /* host order, because nsh map table stores nsp_nsi in host order */
521  key = a->nsh_entry.nsh_base.nsp_nsi;
522 
523  entry_id = hash_get_mem (nm->nsh_entry_by_key, &key);
524 
525  if (a->is_add)
526  {
527  /* adding an entry, must not already exist */
528  if (entry_id)
529  return -1; // TODO VNET_API_ERROR_INVALID_VALUE;
530 
531  pool_get_aligned (nm->nsh_entries, nsh_entry, CLIB_CACHE_LINE_BYTES);
532  clib_memset (nsh_entry, 0, sizeof (*nsh_entry));
533 
534  /* copy from arg structure */
535 #define _(x) nsh_entry->nsh_base.x = a->nsh_entry.nsh_base.x;
537 #undef _
538 
539  if (a->nsh_entry.nsh_base.md_type == 1)
540  {
541  nsh_entry->md.md1_data.c1 = a->nsh_entry.md.md1_data.c1;
542  nsh_entry->md.md1_data.c2 = a->nsh_entry.md.md1_data.c2;
543  nsh_entry->md.md1_data.c3 = a->nsh_entry.md.md1_data.c3;
544  nsh_entry->md.md1_data.c4 = a->nsh_entry.md.md1_data.c4;
545  }
546  else if (a->nsh_entry.nsh_base.md_type == 2)
547  {
548  vec_free (nsh_entry->tlvs_data);
549  tlvs_len = a->nsh_entry.tlvs_len;
551 
552  clib_memcpy (data, a->nsh_entry.tlvs_data, tlvs_len);
553  nsh_entry->tlvs_data = data;
554  nsh_entry->tlvs_len = tlvs_len;
555  vec_free (a->nsh_entry.tlvs_data);
556  }
557 
558  nsh_header_rewrite (nsh_entry);
559 
560  key_copy = clib_mem_alloc (sizeof (*key_copy));
561  clib_memcpy (key_copy, &key, sizeof (*key_copy));
562 
563  hash_set_mem (nm->nsh_entry_by_key, key_copy,
564  nsh_entry - nm->nsh_entries);
565  entry_index = nsh_entry - nm->nsh_entries;
566  }
567  else
568  {
569  if (!entry_id)
570  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
571 
572  nsh_entry = pool_elt_at_index (nm->nsh_entries, entry_id[0]);
573  hp = hash_get_pair (nm->nsh_entry_by_key, &key);
574  key_copy = (void *) (hp->key);
575  hash_unset_mem (nm->nsh_entry_by_key, &key);
576  clib_mem_free (key_copy);
577 
578  vec_free (nsh_entry->tlvs_data);
579  vec_free (nsh_entry->rewrite);
580  pool_put (nm->nsh_entries, nsh_entry);
581  }
582 
583  if (entry_indexp)
584  *entry_indexp = entry_index;
585 
586  return 0;
587 }
588 
589 
590 /** API message handler */
593 {
595  nsh_main_t *nm = &nsh_main;
596  int rv;
597  nsh_add_del_entry_args_t _a, *a = &_a;
598  u32 entry_index = ~0;
599  u8 tlvs_len = 0;
600  u8 *data = 0;
601 
602  a->is_add = mp->is_add;
603  a->nsh_entry.nsh_base.ver_o_c =
604  (mp->ver_o_c & 0xF0) | ((mp->ttl & NSH_LEN_MASK) >> 2);
605  a->nsh_entry.nsh_base.length =
606  (mp->length & NSH_LEN_MASK) | ((mp->ttl & 0x3) << 6);
607  a->nsh_entry.nsh_base.md_type = mp->md_type;
608  a->nsh_entry.nsh_base.next_protocol = mp->next_protocol;
609  a->nsh_entry.nsh_base.nsp_nsi = ntohl (mp->nsp_nsi);
610  if (mp->md_type == 1)
611  {
612  a->nsh_entry.md.md1_data.c1 = ntohl (mp->c1);
613  a->nsh_entry.md.md1_data.c2 = ntohl (mp->c2);
614  a->nsh_entry.md.md1_data.c3 = ntohl (mp->c3);
615  a->nsh_entry.md.md1_data.c4 = ntohl (mp->c4);
616  }
617  else if (mp->md_type == 2)
618  {
619  tlvs_len = mp->tlv_length;
621 
622  clib_memcpy (data, mp->tlv, tlvs_len);
623  a->nsh_entry.tlvs_data = data;
624  a->nsh_entry.tlvs_len = tlvs_len;
625  }
626 
627  rv = nsh_add_del_entry (a, &entry_index);
628 
629  REPLY_MACRO2 (VL_API_NSH_ADD_DEL_ENTRY_REPLY, (
630  {
631  rmp->entry_index =
632  htonl (entry_index);
633  }
634  ));
635 }
636 
637 static void
639 {
640  nsh_main_t *nm = &nsh_main;
641  nsh_entry_t *t;
642  u32 entry_index;
644 
646  if (rp == 0)
647  return;
648 
649  entry_index = ntohl (mp->entry_index);
650 
651  if (~0 == entry_index)
652  {
653  pool_foreach (t, nm->nsh_entries)
654  {
655  send_nsh_entry_details (t, rp, mp->context);
656  }
657  }
658  else
659  {
660  if (entry_index >= vec_len (nm->nsh_entries))
661  {
662  return;
663  }
664  t = &nm->nsh_entries[entry_index];
665  send_nsh_entry_details (t, rp, mp->context);
666  }
667 }
668 
669 static void
671 {
672 #define _(id,n,crc) \
673  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + nm->msg_id_base);
674  foreach_vl_msg_name_crc_nsh;
675 #undef _
676 }
677 
678 /* Set up the API message handling tables */
679 static clib_error_t *
681 {
682  nsh_main_t *nm __attribute__ ((unused)) = &nsh_main;
683 #define _(N,n) \
684  vl_msg_api_set_handlers((VL_API_##N + nm->msg_id_base), \
685  #n, \
686  vl_api_##n##_t_handler, \
687  vl_noop_handler, \
688  vl_api_##n##_t_endian, \
689  vl_api_##n##_t_print, \
690  sizeof(vl_api_##n##_t), 1);
692 #undef _
693 
694  return 0;
695 }
696 
697 clib_error_t *
699 {
701  u8 *name;
702 
703  name = format (0, "nsh_%08x%c", api_version, 0);
704 
705  /* Set up the API */
707  ((char *) name, VL_MSG_FIRST_AVAILABLE);
708 
710 
711  /* Add our API messages to the global name_crc hash table */
713 
714  vec_free (name);
715 
716  return error;
717 }
718 
719 /*
720  * fd.io coding-style-patch-verification: ON
721  *
722  * Local Variables:
723  * eval: (c-set-style "gnu")
724  * End:
725  */
vl_api_nsh_add_del_entry_t::is_add
bool is_add
Definition: nsh.api:24
vl_api_client_index_to_registration
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:79
api.h
vnet_sw_interface_set_flags
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:523
ntohs
#define ntohs(x)
Definition: af_xdp.bpf.c:29
send_nsh_entry_details
static void send_nsh_entry_details(nsh_entry_t *t, vl_api_registration_t *rp, u32 context)
Definition: nsh_api.c:118
vl_api_nsh_add_del_entry_t::md_type
u8 md_type
Definition: nsh.api:26
nsh_add_del_proxy_session
int nsh_add_del_proxy_session(nsh_add_del_map_args_t *a)
Action function to add or del an nsh-proxy-session.
Definition: nsh_api.c:447
vl_api_nsh_map_dump_t
Definition: nsh.api:110
REPLY_MACRO2
#define REPLY_MACRO2(t, body)
Definition: api_helper_macros.h:65
vl_api_nsh_entry_details_t::tlv
u8 tlv[248]
Definition: nsh.api:70
clib_memcpy
#define clib_memcpy(d, s, n)
Definition: string.h:197
vl_api_send_msg
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
vl_api_nsh_add_del_map_t::next_node
u32 next_node
Definition: nsh.api:97
nsh_hw_class
vnet_hw_interface_class_t nsh_hw_class
nsh_entry_t
Note: rewrite and rewrite_size used to support varied nsh header.
Definition: nsh.h:36
pool_elt_at_index
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:553
vl_api_nsh_add_del_entry_reply_t::entry_index
u32 entry_index
Definition: nsh.api:46
name
string name[64]
Definition: fib.api:25
vl_api_nsh_entry_details_t::context
u32 context
Definition: nsh.api:57
pool_get_aligned
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:249
nsh_map_t::nsp_nsi
u32 nsp_nsi
Key for nsh_header_t entry: 24bit NSP 8bit NSI.
Definition: nsh.h:64
vl_api_nsh_entry_details_t::c1
u32 c1
Definition: nsh.api:65
format_nsh_name
static u8 * format_nsh_name(u8 *s, va_list *args)
Naming for NSH tunnel.
Definition: nsh_api.c:103
foreach_copy_nsh_base_hdr_field
#define foreach_copy_nsh_base_hdr_field
Definition: nsh.h:183
clib_mem_free
static void clib_mem_free(void *p)
Definition: mem.h:311
VNET_DEVICE_CLASS
VNET_DEVICE_CLASS(nsh_device_class, static)
nsh_map_t::rx_sw_if_index
u32 rx_sw_if_index
Definition: nsh.h:83
MAX_NSH_HEADER_LEN
#define MAX_NSH_HEADER_LEN
Definition: nsh.h:250
vl_api_nsh_map_details_t::sw_if_index
vl_api_interface_index_t sw_if_index
Definition: nsh.api:122
hash_get_pair
#define hash_get_pair(h, key)
Definition: hash.h:252
am
app_main_t * am
Definition: application.c:489
VNET_SW_INTERFACE_FLAG_ADMIN_UP
@ VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:843
pool_put
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:305
vm
vlib_main_t * vm
X-connect all packets from the HOST to the PHY.
Definition: nat44_ei.c:3047
api.h
vl_api_nsh_map_details_t::mapped_nsp_nsi
u32 mapped_nsp_nsi
Definition: nsh.api:120
VNET_SW_INTERFACE_FLAG_ADMIN_DOWN
#define VNET_SW_INTERFACE_FLAG_ADMIN_DOWN
Definition: nsh.h:241
NSH_NSI_MASK
#define NSH_NSI_MASK
Definition: nsh_packet.h:112
VNET_HW_INTERFACE_FLAG_LINK_UP
@ VNET_HW_INTERFACE_FLAG_LINK_UP
Definition: interface.h:509
vl_msg_api_get_msg_ids
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:1047
vl_api_nsh_map_details_t::rx_sw_if_index
vl_api_interface_index_t rx_sw_if_index
Definition: nsh.api:123
hi
vl_api_ip4_address_t hi
Definition: arp.api:37
vl_api_nsh_map_details_t::context
u32 context
Definition: nsh.api:117
nsh_header_rewrite
int nsh_header_rewrite(nsh_entry_t *nsh_entry)
Definition: nsh_api.c:243
nsh_api_init
clib_error_t * nsh_api_init(vlib_main_t *vm, nsh_main_t *nm)
Definition: nsh_api.c:698
vl_api_nsh_entry_dump_t::context
u32 context
Definition: nsh.api:52
nsh_md2_lookup_option
nsh_option_map_t * nsh_md2_lookup_option(u16 class, u8 type)
Definition: nsh.c:88
vl_api_nsh_entry_details_t::c2
u32 c2
Definition: nsh.api:66
NSH_TTL_H4_MASK
#define NSH_TTL_H4_MASK
Definition: nsh_packet.h:107
vl_api_nsh_add_del_map_t_handler
static void vl_api_nsh_add_del_map_t_handler(vl_api_nsh_add_del_map_t *mp)
API message handler.
Definition: nsh_api.c:210
send_nsh_map_details
static void send_nsh_map_details(nsh_map_t *t, vl_api_registration_t *rp, u32 context)
Definition: nsh_api.c:155
error
Definition: cJSON.c:88
nsh_add_del_entry_args_t
Definition: nsh.h:54
vl_api_nsh_add_del_map_t::rx_sw_if_index
vl_api_interface_index_t rx_sw_if_index
Definition: nsh.api:96
vl_api_nsh_entry_dump_t::client_index
u32 client_index
Definition: nsh.api:51
nsh_main_t
Definition: nsh.h:105
key
typedef key
Definition: ipsec_types.api:88
vl_api_nsh_add_del_map_t::nsh_action
u32 nsh_action
Definition: nsh.api:94
vl_api_nsh_add_del_entry_t::tlv_length
u8 tlv_length
Definition: nsh.api:35
vl_api_nsh_map_details_t::nsh_action
u32 nsh_action
Definition: nsh.api:121
vl_api_nsh_entry_details_t::tlv_length
u8 tlv_length
Definition: nsh.api:69
vl_api_nsh_add_del_entry_t::nsp_nsi
u32 nsp_nsi
Definition: nsh.api:25
pool_foreach
#define pool_foreach(VAR, POOL)
Iterate through pool.
Definition: pool.h:534
vec_len
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: vec_bootstrap.h:142
nsh_md2_data_t
nsh_tlv_header_t nsh_md2_data_t
Definition: nsh_packet.h:93
len
u8 len
Definition: ip_types.api:103
map
counters map
Definition: map.api:356
vec_add1
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:606
vl_api_nsh_add_del_entry_t
/**
Definition: nsh.api:21
vnet_get_hw_interface
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
Definition: interface_funcs.h:44
vl_api_nsh_entry_details_t::next_protocol
u8 next_protocol
Definition: nsh.api:64
vl_api_registration_
An API client registration, only in vpp/vlib.
Definition: api_common.h:47
nsh_map_t::next_node
u32 next_node
Definition: nsh.h:84
nsh_plugin_api_hookup
static clib_error_t * nsh_plugin_api_hookup(vlib_main_t *vm)
Definition: nsh_api.c:680
vec_validate_aligned
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:534
vl_api_nsh_entry_details_t::length
u8 length
Definition: nsh.api:63
vl_api_nsh_entry_details_t
Definition: nsh.api:56
uword
u64 uword
Definition: types.h:112
NSH_TTL_L2_MASK
#define NSH_TTL_L2_MASK
Definition: nsh_packet.h:108
hash_set_mem
#define hash_set_mem(h, key, value)
Definition: hash.h:275
vl_api_nsh_add_del_entry_t::c3
u32 c3
Definition: nsh.api:33
nsh_add_del_map_args_t
Definition: nsh.h:88
nat44_ei_main_s::vnet_main
vnet_main_t * vnet_main
Definition: nat44_ei.h:479
vlibapi_get_main
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:390
vl_api_nsh_add_del_entry_t::ver_o_c
u8 ver_o_c
Definition: nsh.api:27
vl_msg_id_t
vl_msg_id_t
Definition: nsh_api.c:27
nsh_entry_t::tlvs_data
u8 * tlvs_data
Definition: nsh.h:46
setup_message_id_table
static void setup_message_id_table(nsh_main_t *nm, api_main_t *am)
Definition: nsh_api.c:670
vl_api_nsh_add_del_map_reply_t::map_index
u32 map_index
Definition: nsh.api:107
vl_api_nsh_add_del_map_reply_t
Reply from adding NSH map (nsh_add_del_map)
Definition: nsh.api:104
nsh_map_t
Definition: nsh.h:59
vl_api_nsh_entry_details_t::c4
u32 c4
Definition: nsh.api:68
vl_api_nsh_entry_details_t::nsp_nsi
u32 nsp_nsi
Definition: nsh.api:59
nsh_proxy_session_by_key_t
Definition: nsh.h:93
nsh_map_t::nsh_action
u32 nsh_action
Definition: nsh.h:74
vl_api_nsh_map_dump_t::context
u32 context
Definition: nsh.api:112
vl_api_nsh_add_del_entry_t::c4
u32 c4
Definition: nsh.api:34
vl_api_nsh_add_del_entry_t::ttl
u8 ttl
Definition: nsh.api:28
NSH_LEN_MASK
#define NSH_LEN_MASK
Definition: nsh_packet.h:109
CLIB_CACHE_LINE_BYTES
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
nsh_entry_t::md1_data
nsh_md1_data_t md1_data
Definition: nsh.h:42
nsh_interface_admin_up_down
static clib_error_t * nsh_interface_admin_up_down(vnet_main_t *vnm, u32 nsh_hw_if, u32 flags)
CLI function for NSH admin up/down.
Definition: nsh_api.c:82
vl_api_nsh_map_dump_t::client_index
u32 client_index
Definition: nsh.api:111
nat44_ei_main_s::msg_id_base
u16 msg_id_base
Definition: nat44_ei.h:447
vl_api_nsh_entry_dump_t
Definition: nsh.api:50
plugin.h
api_main_t
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:228
data
u8 data[128]
Definition: ipsec_types.api:92
vl_api_nsh_entry_details_t::ver_o_c
u8 ver_o_c
Definition: nsh.api:61
vl_api_nsh_map_details_t::nsp_nsi
u32 nsp_nsi
Definition: nsh.api:119
VL_MSG_FIRST_AVAILABLE
@ VL_MSG_FIRST_AVAILABLE
Definition: nsh_api.c:31
nsh_proxy_session_t
Definition: nsh.h:98
nsh_option_map_t::option_id
u32 option_id
Definition: nsh.h:29
vnet_hw_interface_t
Definition: interface.h:638
vnet_main_t
Definition: vnet.h:76
vec_free
#define vec_free(V)
Free vector's memory (no header).
Definition: vec.h:395
nsh_entry_t::nsh_base
nsh_base_header_t nsh_base
Definition: nsh.h:40
hash_get_mem
#define hash_get_mem(h, key)
Definition: hash.h:269
vl_api_nsh_map_dump_t_handler
static void vl_api_nsh_map_dump_t_handler(vl_api_nsh_map_dump_t *mp)
Definition: nsh_api.c:177
nsh_main
nsh_main_t nsh_main
Definition: nsh.c:28
format
description fragment has unexpected format
Definition: map.api:433
nsh.h
vec_validate_init_empty
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header,...
Definition: vec.h:570
u32
unsigned int u32
Definition: types.h:88
nsh_add_del_map
int nsh_add_del_map(nsh_add_del_map_args_t *a, u32 *map_indexp)
Action function to add or del an nsh map.
Definition: nsh_api.c:345
nsh_entry_t::rewrite
u8 * rewrite
Rewrite string.
Definition: nsh.h:50
api_helper_macros.h
vl_api_nsh_add_del_entry_t::c2
u32 c2
Definition: nsh.api:32
hash_pair_t::key
uword key
Definition: hash.h:162
nsh_map_t::sw_if_index
u32 sw_if_index
Definition: nsh.h:82
vl_api_nsh_add_del_entry_t::tlv
u8 tlv[248]
Definition: nsh.api:36
nsh_proxy_session_t::nsp_nsi
u32 nsp_nsi
Definition: nsh.h:100
nm
nat44_ei_main_t * nm
Definition: nat44_ei_hairpinning.c:413
NSH_NSP_MASK
#define NSH_NSP_MASK
Definition: nsh_packet.h:113
vl_api_nsh_add_del_entry_t_handler
static void vl_api_nsh_add_del_entry_t_handler(vl_api_nsh_add_del_entry_t *mp)
API message handler.
Definition: nsh_api.c:592
clib_memset
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
vlib_main_t
Definition: main.h:102
foreach_nsh_plugin_api_msg
#define foreach_nsh_plugin_api_msg
Definition: nsh_api.c:65
vl_api_nsh_map_details_t
Definition: nsh.api:116
u8
unsigned char u8
Definition: types.h:56
clib_error_t
Definition: clib_error.h:21
vnet_hw_interface_set_flags
clib_error_t * vnet_hw_interface_set_flags(vnet_main_t *vnm, u32 hw_if_index, vnet_hw_interface_flags_t flags)
Definition: interface.c:513
a
a
Definition: bitmap.h:544
hash_unset_mem
#define hash_unset_mem(h, key)
Definition: hash.h:291
vl_api_nsh_add_del_entry_t::length
u8 length
Definition: nsh.api:29
vl_api_nsh_map_details_t::next_node
u32 next_node
Definition: nsh.api:124
vl_api_nsh_add_del_map_t::mapped_nsp_nsi
u32 mapped_nsp_nsi
Definition: nsh.api:93
nsh_entry_t::rewrite_size
u8 rewrite_size
Definition: nsh.h:51
vl_api_nsh_add_del_entry_t::next_protocol
u8 next_protocol
Definition: nsh.api:30
nsh_entry_t::tlvs_len
u8 tlvs_len
Definition: nsh.h:45
nsh_map_t::mapped_nsp_nsi
u32 mapped_nsp_nsi
Key for nsh_header_t entry to map to.
Definition: nsh.h:72
vl_api_nsh_entry_dump_t_handler
static void vl_api_nsh_entry_dump_t_handler(vl_api_nsh_entry_dump_t *mp)
Definition: nsh_api.c:638
vl_api_nsh_entry_details_t::c3
u32 c3
Definition: nsh.api:67
context
u32 context
Definition: ip.api:780
rv
int __clib_unused rv
Definition: application.c:491
NSH_NSP_SHIFT
#define NSH_NSP_SHIFT
Definition: nsh_packet.h:114
nsh_option_map_t
Definition: nsh.h:28
nsh_aware_vnf_proxy_node
vlib_node_registration_t nsh_aware_vnf_proxy_node
(constructor) VLIB_REGISTER_NODE (nsh_aware_vnf_proxy_node)
Definition: nsh_node.c:965
vl_api_nsh_add_del_map_t
Set or delete a mapping from one NSH header to another and its egress (decap to inner packet,...
Definition: nsh.api:88
vnet.h
vl_api_nsh_entry_details_t::ttl
u8 ttl
Definition: nsh.api:62
vl_api_nsh_add_del_entry_reply_t
Reply from adding NSH entry (nsh_add_del_entry)
Definition: nsh.api:43
vl_api_nsh_entry_dump_t::entry_index
u32 entry_index
Definition: nsh.api:53
nsh_add_del_entry
int nsh_add_del_entry(nsh_add_del_entry_args_t *a, u32 *entry_indexp)
Action function for adding an NSH entry nsh_add_del_entry_args_t *a: host order.
Definition: nsh_api.c:509
nsh_entry_t::md
union nsh_entry_t::@755 md
vl_api_nsh_map_dump_t::map_index
u32 map_index
Definition: nsh.api:113
vnet_hw_interface_class_t
struct _vnet_hw_interface_class vnet_hw_interface_class_t
clib_mem_alloc
static void * clib_mem_alloc(uword size)
Definition: mem.h:253
vl_api_nsh_add_del_map_t::sw_if_index
vl_api_interface_index_t sw_if_index
Definition: nsh.api:95
vl_api_nsh_add_del_map_t::nsp_nsi
u32 nsp_nsi
Definition: nsh.api:92
vnet_register_interface
u32 vnet_register_interface(vnet_main_t *vnm, u32 dev_class_index, u32 dev_instance, u32 hw_class_index, u32 hw_instance)
Definition: interface.c:812
vl_api_nsh_add_del_map_t::is_add
bool is_add
Definition: nsh.api:91
hash_pair_t
Definition: hash.h:159
vl_api_nsh_add_del_entry_t::c1
u32 c1
Definition: nsh.api:31
vl_api_nsh_entry_details_t::md_type
u8 md_type
Definition: nsh.api:60
vl_msg_api_alloc
void * vl_msg_api_alloc(int nbytes)
Definition: memory_shared.c:199
flags
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:105