FD.io VPP  v20.01-48-g3e0dafb74
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
118  (nsh_entry_t * t, vl_api_registration_t * rp, u32 context)
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
155  (nsh_map_t * t, vl_api_registration_t * rp, u32 context)
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,
195  mp->context);
196  }
197  ));
198  }
199  else
200  {
201  if (map_index >= vec_len (nm->nsh_mappings))
202  {
203  return;
204  }
205  t = &nm->nsh_mappings[map_index];
206  send_nsh_map_details (t, rp, mp->context);
207  }
208 }
209 
210 /** API message handler */
211 static void
213 {
215  nsh_main_t *nm = &nsh_main;
216  int rv;
217  nsh_add_del_map_args_t _a, *a = &_a;
218  u32 map_index = ~0;
219 
220  a->is_add = mp->is_add;
221  a->map.nsp_nsi = ntohl (mp->nsp_nsi);
222  a->map.mapped_nsp_nsi = ntohl (mp->mapped_nsp_nsi);
223  a->map.nsh_action = ntohl (mp->nsh_action);
224  a->map.sw_if_index = ntohl (mp->sw_if_index);
225  a->map.rx_sw_if_index = ntohl (mp->rx_sw_if_index);
226  a->map.next_node = ntohl (mp->next_node);
227 
228  rv = nsh_add_del_map (a, &map_index);
229 
230  if ((a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN4)
231  | (a->map.next_node == NSH_NODE_NEXT_ENCAP_VXLAN6))
232  {
233  rv = nsh_add_del_proxy_session (a);
234  }
235 
236  REPLY_MACRO2 (VL_API_NSH_ADD_DEL_MAP_REPLY, (
237  {
238  rmp->map_index =
239  htonl (map_index);
240  }
241  ));
242 }
243 
244 int
246 {
247  u8 *rw = 0;
248  int len = 0;
249  nsh_base_header_t *nsh_base;
250  nsh_md1_data_t *nsh_md1;
251  nsh_main_t *nm = &nsh_main;
252  nsh_md2_data_t *opt0;
253  nsh_md2_data_t *limit0;
254  nsh_md2_data_t *nsh_md2;
255  nsh_option_map_t _nsh_option, *nsh_option = &_nsh_option;
256  u8 old_option_size = 0;
257  u8 new_option_size = 0;
258 
259  vec_free (nsh_entry->rewrite);
260  if (nsh_entry->nsh_base.md_type == 1)
261  {
262  len = sizeof (nsh_base_header_t) + sizeof (nsh_md1_data_t);
263  }
264  else if (nsh_entry->nsh_base.md_type == 2)
265  {
266  /* set to maxim, maybe dataplane will add more TLVs */
267  len = MAX_NSH_HEADER_LEN;
268  }
270  clib_memset (rw, 0, len);
271 
272  nsh_base = (nsh_base_header_t *) rw;
273  nsh_base->ver_o_c = nsh_entry->nsh_base.ver_o_c;
274  nsh_base->length = nsh_entry->nsh_base.length;
275  nsh_base->md_type = nsh_entry->nsh_base.md_type;
276  nsh_base->next_protocol = nsh_entry->nsh_base.next_protocol;
277  nsh_base->nsp_nsi = clib_host_to_net_u32 (nsh_entry->nsh_base.nsp_nsi);
278 
279  if (nsh_base->md_type == 1)
280  {
281  nsh_md1 = (nsh_md1_data_t *) (rw + sizeof (nsh_base_header_t));
282  nsh_md1->c1 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c1);
283  nsh_md1->c2 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c2);
284  nsh_md1->c3 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c3);
285  nsh_md1->c4 = clib_host_to_net_u32 (nsh_entry->md.md1_data.c4);
286  nsh_entry->rewrite_size = 24;
287  }
288  else if (nsh_base->md_type == 2)
289  {
290  opt0 = (nsh_md2_data_t *) (nsh_entry->tlvs_data);
291  limit0 = (nsh_md2_data_t *) ((u8 *) opt0 + nsh_entry->tlvs_len);
292 
293  nsh_md2 = (nsh_md2_data_t *) (rw + sizeof (nsh_base_header_t));
294  nsh_entry->rewrite_size = sizeof (nsh_base_header_t);
295 
296  while (opt0 < limit0)
297  {
298  old_option_size = sizeof (nsh_md2_data_t) + opt0->length;
299  /* round to 4-byte */
300  old_option_size = ((old_option_size + 3) >> 2) << 2;
301 
302  nsh_option = nsh_md2_lookup_option (opt0->class, opt0->type);
303  if (nsh_option == NULL)
304  {
305  goto next_tlv_md2;
306  }
307 
308  if (nm->add_options[nsh_option->option_id] != NULL)
309  {
310  if (0 != nm->add_options[nsh_option->option_id] ((u8 *) nsh_md2,
311  &new_option_size))
312  {
313  goto next_tlv_md2;
314  }
315 
316  /* round to 4-byte */
317  new_option_size = ((new_option_size + 3) >> 2) << 2;
318 
319  nsh_entry->rewrite_size += new_option_size;
320  nsh_md2 =
321  (nsh_md2_data_t *) (((u8 *) nsh_md2) + new_option_size);
322  opt0 = (nsh_md2_data_t *) (((u8 *) opt0) + old_option_size);
323  }
324  else
325  {
326  next_tlv_md2:
327  opt0 = (nsh_md2_data_t *) (((u8 *) opt0) + old_option_size);
328  }
329 
330  }
331  }
332 
333  nsh_entry->rewrite = rw;
334  nsh_base->length = (nsh_base->length & NSH_TTL_L2_MASK) |
335  ((nsh_entry->rewrite_size >> 2) & NSH_LEN_MASK);
336 
337  return 0;
338 }
339 
341 
342 /**
343  * Action function to add or del an nsh map.
344  * Shared by both CLI and binary API
345  **/
346 int
348 {
349  nsh_main_t *nm = &nsh_main;
350  vnet_main_t *vnm = nm->vnet_main;
351  nsh_map_t *map = 0;
352  u32 key, *key_copy;
353  uword *entry;
354  hash_pair_t *hp;
355  u32 map_index = ~0;
357  u32 nsh_hw_if = ~0;
358  u32 nsh_sw_if = ~0;
359 
360  /* net order, so data plane could use nsh header to lookup directly */
361  key = clib_host_to_net_u32 (a->map.nsp_nsi);
362 
363  entry = hash_get_mem (nm->nsh_mapping_by_key, &key);
364 
365  if (a->is_add)
366  {
367  /* adding an entry, must not already exist */
368  if (entry)
369  return -1; //TODO API_ERROR_INVALID_VALUE;
370 
372  clib_memset (map, 0, sizeof (*map));
373 
374  /* copy from arg structure */
375  map->nsp_nsi = a->map.nsp_nsi;
377  map->nsh_action = a->map.nsh_action;
378  map->sw_if_index = a->map.sw_if_index;
380  map->next_node = a->map.next_node;
381  map->adj_index = a->map.adj_index;
382 
383 
384  key_copy = clib_mem_alloc (sizeof (*key_copy));
385  clib_memcpy (key_copy, &key, sizeof (*key_copy));
386 
387  hash_set_mem (nm->nsh_mapping_by_key, key_copy, map - nm->nsh_mappings);
388  map_index = map - nm->nsh_mappings;
389 
391  {
392  nsh_hw_if = nm->free_nsh_tunnel_hw_if_indices
394  _vec_len (nm->free_nsh_tunnel_hw_if_indices) -= 1;
395 
396  hi = vnet_get_hw_interface (vnm, nsh_hw_if);
397  hi->dev_instance = map_index;
398  hi->hw_instance = hi->dev_instance;
399  }
400  else
401  {
402  nsh_hw_if = vnet_register_interface
403  (vnm, nsh_device_class.index, map_index, nsh_hw_class.index,
404  map_index);
405  hi = vnet_get_hw_interface (vnm, nsh_hw_if);
407  }
408 
409  map->nsh_hw_if = nsh_hw_if;
410  map->nsh_sw_if = nsh_sw_if = hi->sw_if_index;
412  ~0);
413  nm->tunnel_index_by_sw_if_index[nsh_sw_if] = key;
414 
417  }
418  else
419  {
420  if (!entry)
421  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
422 
423  map = pool_elt_at_index (nm->nsh_mappings, entry[0]);
424 
428  nm->tunnel_index_by_sw_if_index[map->nsh_sw_if] = ~0;
429 
430  hp = hash_get_pair (nm->nsh_mapping_by_key, &key);
431  key_copy = (void *) (hp->key);
433  clib_mem_free (key_copy);
434 
435  pool_put (nm->nsh_mappings, map);
436  }
437 
438  if (map_indexp)
439  *map_indexp = map_index;
440 
441  return 0;
442 }
443 
444 /**
445  * Action function to add or del an nsh-proxy-session.
446  * Shared by both CLI and binary API
447  **/
448 int
450 {
451  nsh_main_t *nm = &nsh_main;
452  nsh_proxy_session_t *proxy = 0;
453  nsh_proxy_session_by_key_t key, *key_copy;
454  uword *entry;
455  hash_pair_t *hp;
456  u32 nsp = 0, nsi = 0;
457 
458  clib_memset (&key, 0, sizeof (key));
459  key.transport_type = a->map.next_node;
461 
462  entry = hash_get_mem (nm->nsh_proxy_session_by_key, &key);
463 
464  if (a->is_add)
465  {
466  /* adding an entry, must not already exist */
467  if (entry)
468  return -1; //TODO API_ERROR_INVALID_VALUE;
469 
471  clib_memset (proxy, 0, sizeof (*proxy));
472 
473  /* Nsi needs to minus 1 within NSH-Proxy */
474  nsp = (a->map.nsp_nsi >> NSH_NSP_SHIFT) & NSH_NSP_MASK;
475  nsi = a->map.nsp_nsi & NSH_NSI_MASK;
476  if (nsi == 0)
477  return -1;
478 
479  nsi = nsi - 1;
480  /* net order, so could use it to lookup nsh map table directly */
481  proxy->nsp_nsi = clib_host_to_net_u32 ((nsp << NSH_NSP_SHIFT) | nsi);
482 
483  key_copy = clib_mem_alloc (sizeof (*key_copy));
484  clib_memcpy (key_copy, &key, sizeof (*key_copy));
485 
486  hash_set_mem (nm->nsh_proxy_session_by_key, key_copy,
487  proxy - nm->nsh_proxy_sessions);
488  }
489  else
490  {
491  if (!entry)
492  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
493 
494  proxy = pool_elt_at_index (nm->nsh_proxy_sessions, entry[0]);
495  hp = hash_get_pair (nm->nsh_proxy_session_by_key, &key);
496  key_copy = (void *) (hp->key);
498  clib_mem_free (key_copy);
499 
500  pool_put (nm->nsh_proxy_sessions, proxy);
501  }
502 
503  return 0;
504 }
505 
506 /**
507  * Action function for adding an NSH entry
508  * nsh_add_del_entry_args_t *a: host order
509  */
510 int
512 {
513  nsh_main_t *nm = &nsh_main;
514  nsh_entry_t *nsh_entry = 0;
515  u32 key, *key_copy;
516  uword *entry_id;
517  hash_pair_t *hp;
518  u32 entry_index = ~0;
519  u8 tlvs_len = 0;
520  u8 *data = 0;
521 
522  /* host order, because nsh map table stores nsp_nsi in host order */
523  key = a->nsh_entry.nsh_base.nsp_nsi;
524 
525  entry_id = hash_get_mem (nm->nsh_entry_by_key, &key);
526 
527  if (a->is_add)
528  {
529  /* adding an entry, must not already exist */
530  if (entry_id)
531  return -1; // TODO VNET_API_ERROR_INVALID_VALUE;
532 
534  clib_memset (nsh_entry, 0, sizeof (*nsh_entry));
535 
536  /* copy from arg structure */
537 #define _(x) nsh_entry->nsh_base.x = a->nsh_entry.nsh_base.x;
539 #undef _
540 
541  if (a->nsh_entry.nsh_base.md_type == 1)
542  {
543  nsh_entry->md.md1_data.c1 = a->nsh_entry.md.md1_data.c1;
544  nsh_entry->md.md1_data.c2 = a->nsh_entry.md.md1_data.c2;
545  nsh_entry->md.md1_data.c3 = a->nsh_entry.md.md1_data.c3;
546  nsh_entry->md.md1_data.c4 = a->nsh_entry.md.md1_data.c4;
547  }
548  else if (a->nsh_entry.nsh_base.md_type == 2)
549  {
550  vec_free (nsh_entry->tlvs_data);
551  tlvs_len = a->nsh_entry.tlvs_len;
552  vec_validate_aligned (data, tlvs_len - 1, CLIB_CACHE_LINE_BYTES);
553 
554  clib_memcpy (data, a->nsh_entry.tlvs_data, tlvs_len);
555  nsh_entry->tlvs_data = data;
556  nsh_entry->tlvs_len = tlvs_len;
558  }
559 
560  nsh_header_rewrite (nsh_entry);
561 
562  key_copy = clib_mem_alloc (sizeof (*key_copy));
563  clib_memcpy (key_copy, &key, sizeof (*key_copy));
564 
565  hash_set_mem (nm->nsh_entry_by_key, key_copy,
566  nsh_entry - nm->nsh_entries);
567  entry_index = nsh_entry - nm->nsh_entries;
568  }
569  else
570  {
571  if (!entry_id)
572  return -2; //TODO API_ERROR_NO_SUCH_ENTRY;
573 
574  nsh_entry = pool_elt_at_index (nm->nsh_entries, entry_id[0]);
575  hp = hash_get_pair (nm->nsh_entry_by_key, &key);
576  key_copy = (void *) (hp->key);
577  hash_unset_mem (nm->nsh_entry_by_key, &key);
578  clib_mem_free (key_copy);
579 
580  vec_free (nsh_entry->tlvs_data);
581  vec_free (nsh_entry->rewrite);
582  pool_put (nm->nsh_entries, nsh_entry);
583  }
584 
585  if (entry_indexp)
586  *entry_indexp = entry_index;
587 
588  return 0;
589 }
590 
591 
592 /** API message handler */
595 {
597  nsh_main_t *nm = &nsh_main;
598  int rv;
599  nsh_add_del_entry_args_t _a, *a = &_a;
600  u32 entry_index = ~0;
601  u8 tlvs_len = 0;
602  u8 *data = 0;
603 
604  a->is_add = mp->is_add;
605  a->nsh_entry.nsh_base.ver_o_c =
606  (mp->ver_o_c & 0xF0) | ((mp->ttl & NSH_LEN_MASK) >> 2);
607  a->nsh_entry.nsh_base.length =
608  (mp->length & NSH_LEN_MASK) | ((mp->ttl & 0x3) << 6);
609  a->nsh_entry.nsh_base.md_type = mp->md_type;
610  a->nsh_entry.nsh_base.next_protocol = mp->next_protocol;
611  a->nsh_entry.nsh_base.nsp_nsi = ntohl (mp->nsp_nsi);
612  if (mp->md_type == 1)
613  {
614  a->nsh_entry.md.md1_data.c1 = ntohl (mp->c1);
615  a->nsh_entry.md.md1_data.c2 = ntohl (mp->c2);
616  a->nsh_entry.md.md1_data.c3 = ntohl (mp->c3);
617  a->nsh_entry.md.md1_data.c4 = ntohl (mp->c4);
618  }
619  else if (mp->md_type == 2)
620  {
621  tlvs_len = mp->tlv_length;
622  vec_validate_aligned (data, tlvs_len - 1, CLIB_CACHE_LINE_BYTES);
623 
624  clib_memcpy (data, mp->tlv, tlvs_len);
625  a->nsh_entry.tlvs_data = data;
626  a->nsh_entry.tlvs_len = tlvs_len;
627  }
628 
629  rv = nsh_add_del_entry (a, &entry_index);
630 
631  REPLY_MACRO2 (VL_API_NSH_ADD_DEL_ENTRY_REPLY, (
632  {
633  rmp->entry_index =
634  htonl (entry_index);
635  }
636  ));
637 }
638 
639 static void
641 {
642  nsh_main_t *nm = &nsh_main;
643  nsh_entry_t *t;
644  u32 entry_index;
646 
648  if (rp == 0)
649  return;
650 
651  entry_index = ntohl (mp->entry_index);
652 
653  if (~0 == entry_index)
654  {
655  pool_foreach (t, nm->nsh_entries, (
656  {
657  send_nsh_entry_details (t, rp,
658  mp->context);
659  }
660  ));
661  }
662  else
663  {
664  if (entry_index >= vec_len (nm->nsh_entries))
665  {
666  return;
667  }
668  t = &nm->nsh_entries[entry_index];
669  send_nsh_entry_details (t, rp, mp->context);
670  }
671 }
672 
673 static void
675 {
676 #define _(id,n,crc) \
677  vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id + nm->msg_id_base);
678  foreach_vl_msg_name_crc_nsh;
679 #undef _
680 }
681 
682 /* Set up the API message handling tables */
683 static clib_error_t *
685 {
686  nsh_main_t *nm __attribute__ ((unused)) = &nsh_main;
687 #define _(N,n) \
688  vl_msg_api_set_handlers((VL_API_##N + nm->msg_id_base), \
689  #n, \
690  vl_api_##n##_t_handler, \
691  vl_noop_handler, \
692  vl_api_##n##_t_endian, \
693  vl_api_##n##_t_print, \
694  sizeof(vl_api_##n##_t), 1);
696 #undef _
697 
698  return 0;
699 }
700 
701 clib_error_t *
703 {
704  clib_error_t *error;
705  u8 *name;
706 
707  name = format (0, "nsh_%08x%c", api_version, 0);
708 
709  /* Set up the API */
711  ((char *) name, VL_MSG_FIRST_AVAILABLE);
712 
713  error = nsh_plugin_api_hookup (vm);
714 
715  /* Add our API messages to the global name_crc hash table */
717 
718  vec_free (name);
719 
720  return error;
721 }
722 
723 /*
724  * fd.io coding-style-patch-verification: ON
725  *
726  * Local Variables:
727  * eval: (c-set-style "gnu")
728  * End:
729  */
VNET_DEVICE_CLASS(nsh_device_class, static)
u32 entry_index
Definition: nsh.api:46
u32 sw_if_index
Definition: nsh.h:82
vl_api_interface_index_t sw_if_index
Definition: nsh.api:122
u32 nsh_action
Definition: nsh.h:74
#define VNET_SW_INTERFACE_FLAG_ADMIN_DOWN
Definition: nsh.h:241
Reply from adding NSH entry (nsh_add_del_entry)
Definition: nsh.api:43
#define NSH_NSP_MASK
Definition: nsh_packet.h:113
u32 * tunnel_index_by_sw_if_index
Mapping from sw_if_index to tunnel index.
Definition: nsh.h:131
u8 tlv[248]
Definition: nsh.api:36
a
Definition: bitmap.h:538
vl_api_interface_index_t rx_sw_if_index
Definition: nsh.api:123
vl_api_interface_index_t sw_if_index
Definition: nsh.api:95
u32 c4
Definition: nsh.api:34
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:58
u32 c1
Definition: nsh.api:65
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
u32 next_node
Definition: nsh.h:84
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
u8 ver_o_c
Definition: nsh.api:27
u32 nsh_sw_if
Definition: nsh.h:79
#define NSH_LEN_MASK
Definition: nsh_packet.h:109
#define hash_set_mem(h, key, value)
Definition: hash.h:275
union nsh_entry_t::@616 md
static void send_nsh_map_details(nsh_map_t *t, vl_api_registration_t *rp, u32 context)
Definition: nsh_api.c:155
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:451
u32 nsp_nsi
Definition: nsh.api:25
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:449
vlib_node_registration_t nsh_aware_vnf_proxy_node
(constructor) VLIB_REGISTER_NODE (nsh_aware_vnf_proxy_node)
Definition: nsh_node.c:959
u32 context
Definition: nsh.api:52
void * vl_msg_api_alloc(int nbytes)
u32 c1
Definition: nsh.api:31
unsigned char u8
Definition: types.h:56
u8 tlv[248]
Definition: nsh.api:70
nsh_base_header_t nsh_base
Definition: nsh.h:40
bool is_add
Definition: nsh.api:24
u32 c2
Definition: nsh.api:32
/**
Definition: nsh.api:21
nsh_proxy_session_t * nsh_proxy_sessions
Definition: nsh.h:123
u32 client_index
Definition: nsh.api:51
#define clib_memcpy(d, s, n)
Definition: string.h:180
u8 length
Definition: nsh.api:63
u32 context
Definition: nsh.api:57
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
int(* add_options[MAX_MD2_OPTIONS])(u8 *opt, u8 *opt_size)
Definition: nsh.h:146
u8 is_add
Definition: nsh.h:55
u8 next_protocol
Definition: nsh.api:30
#define foreach_copy_nsh_base_hdr_field
Definition: nsh.h:183
nsh_entry_t * nsh_entries
Definition: nsh.h:110
vl_msg_id_t
Definition: nsh_api.c:27
u32 adj_index
Definition: nsh.h:85
#define hash_get_pair(h, key)
Definition: hash.h:252
unsigned int u32
Definition: types.h:88
u32 * free_nsh_tunnel_hw_if_indices
Free vlib hw_if_indices.
Definition: nsh.h:129
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:762
u16 msg_id_base
Definition: nsh.h:107
nsh_option_map_t * nsh_md2_lookup_option(u16 class, u8 type)
Definition: nsh.c:88
u32 c3
Definition: nsh.api:33
u32 c2
Definition: nsh.api:66
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
#define hash_unset_mem(h, key)
Definition: hash.h:291
Definition: nsh.h:59
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:594
nsh_map_t * nsh_mappings
Definition: nsh.h:116
uword * nsh_entry_by_key
Definition: nsh.h:113
u8 * rewrite
Rewrite string.
Definition: nsh.h:50
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
u8 tlv_length
Definition: nsh.api:69
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:347
u32 c4
Definition: nsh.api:68
static u8 * format_nsh_name(u8 *s, va_list *args)
Naming for NSH tunnel.
Definition: nsh_api.c:103
vlib_main_t * vm
Definition: in2out_ed.c:1810
u8 len
Definition: ip_types.api:91
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:225
Definition: nsh.h:54
#define pool_get_aligned(P, E, A)
Allocate an object E from a pool P with alignment A.
Definition: pool.h:231
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
static void setup_message_id_table(nsh_main_t *nm, api_main_t *am)
Definition: nsh_api.c:674
static void vl_api_nsh_map_dump_t_handler(vl_api_nsh_map_dump_t *mp)
Definition: nsh_api.c:177
u32 flags
Definition: vhost_user.h:141
vl_api_interface_index_t rx_sw_if_index
Definition: nsh.api:96
u8 md_type
Definition: nsh.api:26
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
u8 length
Definition: nsh.api:29
#define MAX_NSH_HEADER_LEN
Definition: nsh.h:250
uword * nsh_proxy_session_by_key
Definition: nsh.h:126
u32 nsp_nsi
Key for nsh_header_t entry: 24bit NSP 8bit NSI.
Definition: nsh.h:64
#define NSH_NSI_MASK
Definition: nsh_packet.h:112
nsh_main_t nsh_main
Definition: nsh.c:28
u32 nsh_hw_if
vnet intfc hw_if_index
Definition: nsh.h:77
u8 tlvs_len
Definition: nsh.h:45
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
static clib_error_t * nsh_plugin_api_hookup(vlib_main_t *vm)
Definition: nsh_api.c:684
string name[64]
Definition: ip.api:44
u32 nsp_nsi
Definition: nsh.api:59
nsh_tlv_header_t nsh_md2_data_t
Definition: nsh_packet.h:93
u32 mapped_nsp_nsi
Key for nsh_header_t entry to map to.
Definition: nsh.h:72
u8 next_protocol
Definition: nsh.api:64
u32 rx_sw_if_index
Definition: nsh.h:83
u32 option_id
Definition: nsh.h:29
u8 data[128]
Definition: ipsec_types.api:87
nsh_map_t map
Definition: nsh.h:90
vnet_hw_interface_class_t nsh_hw_class
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:511
static void clib_mem_free(void *p)
Definition: mem.h:226
Set or delete a mapping from one NSH header to another and its egress (decap to inner packet...
Definition: nsh.api:88
nsh_md1_data_t md1_data
Definition: nsh.h:42
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
Definition: nsh.api:50
u8 ver_o_c
Definition: nsh.api:61
u8 ttl
Definition: nsh.api:62
static void vl_api_nsh_entry_dump_t_handler(vl_api_nsh_entry_dump_t *mp)
Definition: nsh_api.c:640
static void send_nsh_entry_details(nsh_entry_t *t, vl_api_registration_t *rp, u32 context)
Definition: nsh_api.c:118
static void * clib_mem_alloc(uword size)
Definition: mem.h:153
u8 rewrite_size
Definition: nsh.h:51
vl_api_ip4_address_t hi
Definition: arp.api:37
typedef key
Definition: ipsec_types.api:83
u8 tlv_length
Definition: nsh.api:35
u8 * tlvs_data
Definition: nsh.h:46
struct _vnet_hw_interface_class vnet_hw_interface_class_t
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
Definition: nsh.api:56
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:492
u64 uword
Definition: types.h:112
u8 md_type
Definition: nsh.api:60
#define NSH_NSP_SHIFT
Definition: nsh_packet.h:114
u32 c3
Definition: nsh.api:67
vnet_main_t * vnet_main
Definition: nsh.h:168
#define NSH_TTL_L2_MASK
Definition: nsh_packet.h:108
#define hash_get_mem(h, key)
Definition: hash.h:269
static api_main_t * vlibapi_get_main(void)
Definition: api_common.h:378
Reply from adding NSH map (nsh_add_del_map)
Definition: nsh.api:104
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:501
u8 ttl
Definition: nsh.api:28
Note: rewrite and rewrite_size used to support varied nsh header.
Definition: nsh.h:36
clib_error_t * nsh_api_init(vlib_main_t *vm, nsh_main_t *nm)
Definition: nsh_api.c:702
#define NSH_TTL_H4_MASK
Definition: nsh_packet.h:107
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:487
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
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:212
u32 entry_index
Definition: nsh.api:53
uword * nsh_mapping_by_key
Definition: nsh.h:119
int nsh_header_rewrite(nsh_entry_t *nsh_entry)
Definition: nsh_api.c:245
#define foreach_nsh_plugin_api_msg
Definition: nsh_api.c:65
uword key
Definition: hash.h:162
nsh_entry_t nsh_entry
Definition: nsh.h:56
u16 vl_msg_api_get_msg_ids(const char *name, int n)
Definition: api_shared.c:980