FD.io VPP  v17.10-9-gd594711
Vector Packet Processing
api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * api.c - message handler registration
4  *
5  * Copyright (c) 2010-2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <stdio.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/mman.h>
25 #include <sys/stat.h>
26 #include <netinet/in.h>
27 #include <signal.h>
28 #include <pthread.h>
29 #include <unistd.h>
30 #include <time.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <pwd.h>
34 #include <grp.h>
35 
36 #include <vppinfra/clib.h>
37 #include <vppinfra/vec.h>
38 #include <vppinfra/hash.h>
39 #include <vppinfra/bitmap.h>
40 #include <vppinfra/fifo.h>
41 #include <vppinfra/time.h>
42 #include <vppinfra/mheap.h>
43 #include <vppinfra/heap.h>
44 #include <vppinfra/pool.h>
45 #include <vppinfra/format.h>
46 #include <vppinfra/error.h>
47 
48 #include <vnet/api_errno.h>
49 #include <vnet/vnet.h>
50 #include <vnet/l2/l2_input.h>
51 #include <vnet/l2/l2_bd.h>
52 #include <vnet/ip/ip.h>
53 #include <vnet/ip/ip6.h>
54 #include <vnet/ip/ip6_neighbor.h>
55 #if WITH_LIBSSL > 0
56 #include <vnet/srv6/sr.h>
57 #endif
58 #include <vlib/vlib.h>
59 #include <vlib/unix/unix.h>
60 #include <vlibapi/api.h>
61 #include <vlibmemory/api.h>
63 #include <vnet/l2/l2_classify.h>
64 #include <vnet/map/map.h>
65 #include <vnet/ip/ip6_hop_by_hop.h>
67 #include <vnet/ip/punt.h>
68 #include <vnet/feature/feature.h>
69 
70 #undef BIHASH_TYPE
71 #undef __included_bihash_template_h__
72 #include <vnet/l2/l2_fib.h>
73 
74 #include <vpp/stats/stats.h>
75 #include <vpp/oam/oam.h>
76 
77 #include <vnet/ethernet/ethernet.h>
79 #include <vnet/interface.h>
80 #include <vnet/l2/l2_fib.h>
81 #include <vnet/l2/l2_bd.h>
82 #include <vpp/api/vpe_msg_enum.h>
83 #include <vnet/span/span.h>
84 #include <vnet/fib/fib_api.h>
85 #include <vnet/dpo/drop_dpo.h>
86 #include <vnet/dpo/receive_dpo.h>
87 #include <vnet/dpo/lookup_dpo.h>
88 #include <vnet/dpo/classify_dpo.h>
89 #include <vnet/dpo/ip_null_dpo.h>
90 #define vl_typedefs /* define message structures */
91 #include <vpp/api/vpe_all_api_h.h>
92 #undef vl_typedefs
93 #define vl_endianfun /* define message structures */
94 #include <vpp/api/vpe_all_api_h.h>
95 #undef vl_endianfun
96 /* instantiate all the print functions we know about */
97 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
98 #define vl_printfun
99 #include <vpp/api/vpe_all_api_h.h>
100 #undef vl_printfun
102 #define foreach_vpe_api_msg \
103 _(WANT_OAM_EVENTS, want_oam_events) \
104 _(OAM_ADD_DEL, oam_add_del) \
105 _(SW_INTERFACE_SET_MPLS_ENABLE, sw_interface_set_mpls_enable) \
106 _(SW_INTERFACE_SET_VPATH, sw_interface_set_vpath) \
107 _(SW_INTERFACE_SET_L2_XCONNECT, sw_interface_set_l2_xconnect) \
108 _(SW_INTERFACE_SET_L2_BRIDGE, sw_interface_set_l2_bridge) \
109 _(CREATE_VLAN_SUBIF, create_vlan_subif) \
110 _(CREATE_SUBIF, create_subif) \
111 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
112 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
113 _(RESET_FIB, reset_fib) \
114 _(CREATE_LOOPBACK, create_loopback) \
115 _(CREATE_LOOPBACK_INSTANCE, create_loopback_instance) \
116 _(CONTROL_PING, control_ping) \
117 _(CLI, cli) \
118 _(CLI_INBAND, cli_inband) \
119 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
120 _(L2_PATCH_ADD_DEL, l2_patch_add_del) \
121 _(CLASSIFY_SET_INTERFACE_IP_TABLE, classify_set_interface_ip_table) \
122 _(CLASSIFY_SET_INTERFACE_L2_TABLES, classify_set_interface_l2_tables) \
123 _(GET_NODE_INDEX, get_node_index) \
124 _(ADD_NODE_NEXT, add_node_next) \
125 _(L2_INTERFACE_EFP_FILTER, l2_interface_efp_filter) \
126 _(SHOW_VERSION, show_version) \
127 _(INTERFACE_NAME_RENUMBER, interface_name_renumber) \
128 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
129 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
130 _(INPUT_ACL_SET_INTERFACE, input_acl_set_interface) \
131 _(DELETE_LOOPBACK, delete_loopback) \
132 _(BD_IP_MAC_ADD_DEL, bd_ip_mac_add_del) \
133 _(GET_NODE_GRAPH, get_node_graph) \
134 _(IOAM_ENABLE, ioam_enable) \
135 _(IOAM_DISABLE, ioam_disable) \
136 _(GET_NEXT_INDEX, get_next_index) \
137 _(PG_CREATE_INTERFACE, pg_create_interface) \
138 _(PG_CAPTURE, pg_capture) \
139 _(PG_ENABLE_DISABLE, pg_enable_disable) \
140 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
141  ip_source_and_port_range_check_add_del) \
142 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
143  ip_source_and_port_range_check_interface_add_del) \
144 _(DELETE_SUBIF, delete_subif) \
145 _(PUNT, punt) \
146 _(PUNT_SOCKET_REGISTER, punt_socket_register) \
147 _(PUNT_SOCKET_DEREGISTER, punt_socket_deregister) \
148 _(FEATURE_ENABLE_DISABLE, feature_enable_disable)
149 
150 #define QUOTE_(x) #x
151 #define QUOTE(x) QUOTE_(x)
152 typedef enum
153 {
156 } resolve_t;
157 
160 
161 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
162 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
163 
164 /* Clean up all registrations belonging to the indicated client */
165 static clib_error_t *
167 {
170  uword *p;
171  int stats_memclnt_delete_callback (u32 client_index);
172 
173  stats_memclnt_delete_callback (client_index);
174 
175 #define _(a) \
176  p = hash_get (vam->a##_registration_hash, client_index); \
177  if (p) { \
178  rp = pool_elt_at_index (vam->a##_registrations, p[0]); \
179  pool_put (vam->a##_registrations, rp); \
180  hash_unset (vam->a##_registration_hash, client_index); \
181  }
183 #undef _
184  return 0;
185 }
186 
188 
189 pub_sub_handler (oam_events, OAM_EVENTS);
190 
191 #define RESOLUTION_EVENT 1
192 #define RESOLUTION_PENDING_EVENT 2
193 #define IP4_ARP_EVENT 3
194 #define IP6_ND_EVENT 4
195 
197 
199 
200 static void
202 {
204  vnet_main_t *vnm = vam->vnet_main;
205  vlib_main_t *vm = vam->vlib_main;
206  vl_api_ip4_arp_event_t *event;
209 
210  /* Client can cancel, die, etc. */
211  if (pool_is_free_index (vam->arp_events, pool_index))
212  return;
213 
214  event = pool_elt_at_index (vam->arp_events, pool_index);
215 
217  if (!q)
218  {
221  event->pid, &event->address,
222  vpe_resolver_process_node.index, IP4_ARP_EVENT,
223  ~0 /* pool index, notused */ , 0 /* is_add */ );
224  return;
225  }
226 
227  if (q->cursize < q->maxsize)
228  {
229  mp = vl_msg_api_alloc (sizeof (*mp));
230  clib_memcpy (mp, event, sizeof (*mp));
231  vl_msg_api_send_shmem (q, (u8 *) & mp);
232  }
233  else
234  {
235  static f64 last_time;
236  /*
237  * Throttle syslog msgs.
238  * It's pretty tempting to just revoke the registration...
239  */
240  if (vlib_time_now (vm) > last_time + 10.0)
241  {
242  clib_warning ("arp event for %U to pid %d: queue stuffed!",
243  format_ip4_address, &event->address, event->pid);
244  last_time = vlib_time_now (vm);
245  }
246  }
247 }
248 
249 void
251 {
253  vnet_main_t *vnm = vam->vnet_main;
254  vlib_main_t *vm = vam->vlib_main;
255  vl_api_ip6_nd_event_t *event;
258 
259  /* Client can cancel, die, etc. */
260  if (pool_is_free_index (vam->nd_events, pool_index))
261  return;
262 
263  event = pool_elt_at_index (vam->nd_events, pool_index);
264 
266  if (!q)
267  {
270  event->pid, &event->address,
271  vpe_resolver_process_node.index, IP6_ND_EVENT,
272  ~0 /* pool index, notused */ , 0 /* is_add */ );
273  return;
274  }
275 
276  if (q->cursize < q->maxsize)
277  {
278  mp = vl_msg_api_alloc (sizeof (*mp));
279  clib_memcpy (mp, event, sizeof (*mp));
280  vl_msg_api_send_shmem (q, (u8 *) & mp);
281  }
282  else
283  {
284  static f64 last_time;
285  /*
286  * Throttle syslog msgs.
287  * It's pretty tempting to just revoke the registration...
288  */
289  if (vlib_time_now (vm) > last_time + 10.0)
290  {
291  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
292  format_ip6_address, &event->address, event->pid);
293  last_time = vlib_time_now (vm);
294  }
295  }
296 }
297 
298 static uword
301 {
302  volatile f64 timeout = 100.0;
303  volatile uword *event_data = 0;
304 
305  while (1)
306  {
308 
309  uword event_type =
310  vlib_process_get_events (vm, (uword **) & event_data);
311 
312  int i;
313  switch (event_type)
314  {
316  timeout = 1.0;
317  break;
318 
319  case RESOLUTION_EVENT:
320  clib_warning ("resolver: BOGUS TYPE");
321  break;
322 
323  case IP4_ARP_EVENT:
324  for (i = 0; i < vec_len (event_data); i++)
325  handle_ip4_arp_event (event_data[i]);
326  break;
327 
328  case IP6_ND_EVENT:
329  for (i = 0; i < vec_len (event_data); i++)
330  handle_ip6_nd_event (event_data[i]);
331  break;
332 
333  case ~0: /* timeout */
334  break;
335  }
336 
337  vec_reset_length (event_data);
338  }
339  return 0; /* or not */
340 }
341 
342 /* *INDENT-OFF* */
343 VLIB_REGISTER_NODE (vpe_resolver_process_node,static) = {
344  .function = resolver_process,
345  .type = VLIB_NODE_TYPE_PROCESS,
346  .name = "vpe-route-resolver-process",
347 };
348 /* *INDENT-ON* */
349 
350 static void
352 {
353  vl_api_sw_interface_set_vpath_reply_t *rmp;
354  int rv = 0;
355  u32 sw_if_index = ntohl (mp->sw_if_index);
356 
358 
359  l2input_intf_bitmap_enable (sw_if_index, L2INPUT_FEAT_VPATH, mp->enable);
360  vnet_feature_enable_disable ("ip4-unicast", "vpath-input-ip4",
361  sw_if_index, mp->enable, 0, 0);
362  vnet_feature_enable_disable ("ip4-multicast", "vpath-input-ip4",
363  sw_if_index, mp->enable, 0, 0);
364  vnet_feature_enable_disable ("ip6-unicast", "vpath-input-ip6",
365  sw_if_index, mp->enable, 0, 0);
366  vnet_feature_enable_disable ("ip6-multicast", "vpath-input-ip6",
367  sw_if_index, mp->enable, 0, 0);
368 
370 
371  REPLY_MACRO (VL_API_SW_INTERFACE_SET_VPATH_REPLY);
372 }
373 
374 static void
377 {
378  vl_api_sw_interface_set_l2_xconnect_reply_t *rmp;
379  int rv = 0;
380  u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
381  u32 tx_sw_if_index = ntohl (mp->tx_sw_if_index);
383  vnet_main_t *vnm = vnet_get_main ();
384 
386 
387  if (mp->enable)
388  {
390  rv = set_int_l2_mode (vm, vnm, MODE_L2_XC,
391  rx_sw_if_index, 0, 0, 0, tx_sw_if_index);
392  }
393  else
394  {
395  rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
396  }
397 
400 
401  REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_XCONNECT_REPLY);
402 }
403 
404 static void
407 {
408  bd_main_t *bdm = &bd_main;
409  vl_api_sw_interface_set_l2_bridge_reply_t *rmp;
410  int rv = 0;
412  vnet_main_t *vnm = vnet_get_main ();
413 
415  u32 rx_sw_if_index = ntohl (mp->rx_sw_if_index);
416 
417 
418  if (mp->enable)
419  {
420  VALIDATE_BD_ID (mp);
421  u32 bd_id = ntohl (mp->bd_id);
422  u32 bd_index = bd_find_or_add_bd_index (bdm, bd_id);
423  u32 bvi = mp->bvi;
424  u8 shg = mp->shg;
425  rv = set_int_l2_mode (vm, vnm, MODE_L2_BRIDGE,
426  rx_sw_if_index, bd_index, bvi, shg, 0);
427  }
428  else
429  {
430  rv = set_int_l2_mode (vm, vnm, MODE_L3, rx_sw_if_index, 0, 0, 0, 0);
431  }
432 
435 
436  REPLY_MACRO (VL_API_SW_INTERFACE_SET_L2_BRIDGE_REPLY);
437 }
438 
439 static void
441 {
442  bd_main_t *bdm = &bd_main;
443  vl_api_bd_ip_mac_add_del_reply_t *rmp;
444  int rv = 0;
445  u32 bd_id = ntohl (mp->bd_id);
446  u32 bd_index;
447  uword *p;
448 
449  if (bd_id == 0)
450  {
451  rv = VNET_API_ERROR_BD_NOT_MODIFIABLE;
452  goto out;
453  }
454 
455  p = hash_get (bdm->bd_index_by_bd_id, bd_id);
456  if (p == 0)
457  {
458  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
459  goto out;
460  }
461 
462  bd_index = p[0];
463  if (bd_add_del_ip_mac (bd_index, mp->ip_address,
464  mp->mac_address, mp->is_ipv6, mp->is_add))
465  rv = VNET_API_ERROR_UNSPECIFIED;
466 
467 out:
468  REPLY_MACRO (VL_API_BD_IP_MAC_ADD_DEL_REPLY);
469 }
470 
471 static void
473 {
475  vnet_main_t *vnm = vnet_get_main ();
476  u32 sw_if_index = (u32) ~ 0;
478  int rv = 0;
479  u32 id;
480  vnet_sw_interface_t template;
481  uword *p;
483  u64 sup_and_sub_key;
485  clib_error_t *error;
486 
488 
489  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
490 
492  {
493  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
494  goto out;
495  }
496 
497  id = ntohl (mp->vlan_id);
498  if (id == 0 || id > 4095)
499  {
500  rv = VNET_API_ERROR_INVALID_VLAN;
501  goto out;
502  }
503 
504  sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
505 
506  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
507  if (p)
508  {
509  rv = VNET_API_ERROR_VLAN_ALREADY_EXISTS;
510  goto out;
511  }
512 
513  memset (&template, 0, sizeof (template));
514  template.type = VNET_SW_INTERFACE_TYPE_SUB;
515  template.sup_sw_if_index = hi->sw_if_index;
516  template.sub.id = id;
517  template.sub.eth.raw_flags = 0;
518  template.sub.eth.flags.one_tag = 1;
519  template.sub.eth.outer_vlan_id = id;
520  template.sub.eth.flags.exact_match = 1;
521 
522  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
523  if (error)
524  {
525  clib_error_report (error);
526  rv = VNET_API_ERROR_INVALID_REGISTRATION;
527  goto out;
528  }
529 
530  u64 *kp = clib_mem_alloc (sizeof (*kp));
531  *kp = sup_and_sub_key;
532 
533  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
534  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
535 
537 
538 out:
540  if (!q)
541  return;
542 
543  rmp = vl_msg_api_alloc (sizeof (*rmp));
544  rmp->_vl_msg_id = htons (VL_API_CREATE_VLAN_SUBIF_REPLY);
545  rmp->context = mp->context;
546  rmp->retval = htonl (rv);
547  rmp->sw_if_index = htonl (sw_if_index);
548  vl_msg_api_send_shmem (q, (u8 *) & rmp);
549 }
550 
551 static void
553 {
555  vnet_main_t *vnm = vnet_get_main ();
556  u32 sw_if_index = ~0;
557  int rv = 0;
558  u32 sub_id;
561  vnet_sw_interface_t template;
562  uword *p;
564  u64 sup_and_sub_key;
565  clib_error_t *error;
566 
568 
569  si = vnet_get_sup_sw_interface (vnm, ntohl (mp->sw_if_index));
570  hi = vnet_get_sup_hw_interface (vnm, ntohl (mp->sw_if_index));
571 
573  {
574  rv = VNET_API_ERROR_BOND_SLAVE_NOT_ALLOWED;
575  goto out;
576  }
577 
578  sw_if_index = si->sw_if_index;
579  sub_id = ntohl (mp->sub_id);
580 
581  sup_and_sub_key = ((u64) (sw_if_index) << 32) | (u64) sub_id;
582 
583  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
584  if (p)
585  {
586  if (CLIB_DEBUG > 0)
587  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
588  sw_if_index, sub_id);
589  rv = VNET_API_ERROR_SUBIF_ALREADY_EXISTS;
590  goto out;
591  }
592 
593  memset (&template, 0, sizeof (template));
594  template.type = VNET_SW_INTERFACE_TYPE_SUB;
595  template.sup_sw_if_index = sw_if_index;
596  template.sub.id = sub_id;
597  template.sub.eth.flags.no_tags = mp->no_tags;
598  template.sub.eth.flags.one_tag = mp->one_tag;
599  template.sub.eth.flags.two_tags = mp->two_tags;
600  template.sub.eth.flags.dot1ad = mp->dot1ad;
601  template.sub.eth.flags.exact_match = mp->exact_match;
602  template.sub.eth.flags.default_sub = mp->default_sub;
603  template.sub.eth.flags.outer_vlan_id_any = mp->outer_vlan_id_any;
604  template.sub.eth.flags.inner_vlan_id_any = mp->inner_vlan_id_any;
605  template.sub.eth.outer_vlan_id = ntohs (mp->outer_vlan_id);
606  template.sub.eth.inner_vlan_id = ntohs (mp->inner_vlan_id);
607 
608  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
609  if (error)
610  {
611  clib_error_report (error);
612  rv = VNET_API_ERROR_SUBIF_CREATE_FAILED;
613  goto out;
614  }
615 
616  u64 *kp = clib_mem_alloc (sizeof (*kp));
617  *kp = sup_and_sub_key;
618 
619  hash_set (hi->sub_interface_sw_if_index_by_id, sub_id, sw_if_index);
620  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
621 
623 
624 out:
625 
626  /* *INDENT-OFF* */
627  REPLY_MACRO2(VL_API_CREATE_SUBIF_REPLY,
628  ({
629  rmp->sw_if_index = ntohl(sw_if_index);
630  }));
631  /* *INDENT-ON* */
632 }
633 
634 static void
636 {
637  vl_api_proxy_arp_add_del_reply_t *rmp;
638  u32 fib_index;
639  int rv;
640  ip4_main_t *im = &ip4_main;
641  stats_main_t *sm = &stats_main;
642  int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
643  ip4_address_t * hi_addr,
644  u32 fib_index, int is_del);
645  uword *p;
646 
647  dslock (sm, 1 /* release hint */ , 6 /* tag */ );
648 
649  p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
650 
651  if (!p)
652  {
653  rv = VNET_API_ERROR_NO_SUCH_FIB;
654  goto out;
655  }
656 
657  fib_index = p[0];
658 
660  (ip4_address_t *) mp->hi_address,
661  fib_index, mp->is_add == 0);
662 
663 out:
664  dsunlock (sm);
665  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
666 }
667 
668 static void
671 {
672  int rv = 0;
673  vnet_main_t *vnm = vnet_get_main ();
674  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
675 
677 
678  vnet_sw_interface_t *si =
679  vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
680 
681  ASSERT (si);
682 
683  if (mp->enable_disable)
685  else
687 
689 
690  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
691 }
692 
693 static void
696 {
697  vl_api_sw_interface_set_mpls_enable_reply_t *rmp;
698  int rv = 0;
699 
701 
703  ntohl (mp->sw_if_index),
704  mp->enable, 1);
705 
707  REPLY_MACRO (VL_API_SW_INTERFACE_SET_MPLS_ENABLE_REPLY);
708 }
709 
710 void
712 {
716  vl_api_oam_event_t *mp;
717 
718  /* *INDENT-OFF* */
719  pool_foreach(reg, vam->oam_events_registrations,
720  ({
721  q = vl_api_client_index_to_input_queue (reg->client_index);
722  if (q)
723  {
724  mp = vl_msg_api_alloc (sizeof (*mp));
725  mp->_vl_msg_id = ntohs (VL_API_OAM_EVENT);
726  clib_memcpy (mp->dst_address, &t->dst_address,
727  sizeof (mp->dst_address));
728  mp->state = t->state;
729  vl_msg_api_send_shmem (q, (u8 *)&mp);
730  }
731  }));
732  /* *INDENT-ON* */
733 }
734 
735 static void
737 {
738  vl_api_oam_add_del_reply_t *rmp;
739  int rv;
740 
742  (ip4_address_t *) mp->dst_address,
743  ntohl (mp->vrf_id), (int) (mp->is_add));
744 
745  REPLY_MACRO (VL_API_OAM_ADD_DEL_REPLY);
746 }
747 
748 
749 static int
751 {
752  vnet_main_t *vnm = vnet_get_main ();
754  ip4_main_t *im4 = &ip4_main;
755  static u32 *sw_if_indices_to_shut;
756  stats_main_t *sm = &stats_main;
757  fib_table_t *fib_table;
758  ip4_fib_t *fib;
759  u32 sw_if_index;
760  int i;
761  int rv = VNET_API_ERROR_NO_SUCH_FIB;
762  u32 target_fib_id = ntohl (mp->vrf_id);
763 
764  dslock (sm, 1 /* release hint */ , 8 /* tag */ );
765 
766  /* *INDENT-OFF* */
767  pool_foreach (fib_table, im4->fibs,
768  ({
769  vnet_sw_interface_t * si;
770 
771  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
772 
773  if (fib->table_id != target_fib_id)
774  continue;
775 
776  /* remove any mpls encap/decap labels */
777  mpls_fib_reset_labels (fib->table_id);
778 
779  /* remove any proxy arps in this fib */
780  vnet_proxy_arp_fib_reset (fib->table_id);
781 
782  /* Set the flow hash for this fib to the default */
783  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
784 
785  vec_reset_length (sw_if_indices_to_shut);
786 
787  /* Shut down interfaces in this FIB / clean out intfc routes */
788  pool_foreach (si, im->sw_interfaces,
789  ({
790  u32 sw_if_index = si->sw_if_index;
791 
792  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
793  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
794  fib->index))
795  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
796  }));
797 
798  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
799  sw_if_index = sw_if_indices_to_shut[i];
800 
801  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
803  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
804  }
805 
807 
808  rv = 0;
809  break;
810  })); /* pool_foreach (fib) */
811  /* *INDENT-ON* */
812 
813  dsunlock (sm);
814  return rv;
815 }
816 
817 static int
819 {
820  vnet_main_t *vnm = vnet_get_main ();
822  ip6_main_t *im6 = &ip6_main;
823  stats_main_t *sm = &stats_main;
824  static u32 *sw_if_indices_to_shut;
825  fib_table_t *fib_table;
826  ip6_fib_t *fib;
827  u32 sw_if_index;
828  int i;
829  int rv = VNET_API_ERROR_NO_SUCH_FIB;
830  u32 target_fib_id = ntohl (mp->vrf_id);
831 
832  dslock (sm, 1 /* release hint */ , 9 /* tag */ );
833 
834  /* *INDENT-OFF* */
835  pool_foreach (fib_table, im6->fibs,
836  ({
837  vnet_sw_interface_t * si;
838 
839  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
840 
841  if (fib->table_id != target_fib_id)
842  continue;
843 
844  vec_reset_length (sw_if_indices_to_shut);
845 
846  /* Set the flow hash for this fib to the default */
847  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
848 
849  /* Shut down interfaces in this FIB / clean out intfc routes */
850  pool_foreach (si, im->sw_interfaces,
851  ({
852  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
853  fib->index)
854  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
855  }));
856 
857  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
858  sw_if_index = sw_if_indices_to_shut[i];
859 
860  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
862  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
863  }
864 
866 
867  rv = 0;
868  break;
869  })); /* pool_foreach (fib) */
870  /* *INDENT-ON* */
871 
872  dsunlock (sm);
873  return rv;
874 }
875 
876 static void
878 {
879  int rv;
880  vl_api_reset_fib_reply_t *rmp;
881 
882  if (mp->is_ipv6)
883  rv = ip6_reset_fib_t_handler (mp);
884  else
885  rv = ip4_reset_fib_t_handler (mp);
886 
887  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
888 }
889 
890 static void
892 {
894  u32 sw_if_index;
895  int rv;
896 
897  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address, 0, 0);
898 
899  /* *INDENT-OFF* */
900  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_REPLY,
901  ({
902  rmp->sw_if_index = ntohl (sw_if_index);
903  }));
904  /* *INDENT-ON* */
905 }
906 
909 {
911  u32 sw_if_index;
912  u8 is_specified = mp->is_specified;
913  u32 user_instance = ntohl (mp->user_instance);
914  int rv;
915 
916  rv = vnet_create_loopback_interface (&sw_if_index, mp->mac_address,
917  is_specified, user_instance);
918 
919  /* *INDENT-OFF* */
920  REPLY_MACRO2(VL_API_CREATE_LOOPBACK_INSTANCE_REPLY,
921  ({
922  rmp->sw_if_index = ntohl (sw_if_index);
923  }));
924  /* *INDENT-ON* */
925 }
926 
927 static void
929 {
930  vl_api_delete_loopback_reply_t *rmp;
931  u32 sw_if_index;
932  int rv;
933 
934  sw_if_index = ntohl (mp->sw_if_index);
935  rv = vnet_delete_loopback_interface (sw_if_index);
936 
937  REPLY_MACRO (VL_API_DELETE_LOOPBACK_REPLY);
938 }
939 
940 static void
942 {
944  int rv = 0;
945 
946  /* *INDENT-OFF* */
947  REPLY_MACRO2(VL_API_CONTROL_PING_REPLY,
948  ({
949  rmp->vpe_pid = ntohl (getpid());
950  }));
951  /* *INDENT-ON* */
952 }
953 
954 static void
955 shmem_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
956 {
957  u8 **shmem_vecp = (u8 **) arg;
958  u8 *shmem_vec;
959  void *oldheap;
960  api_main_t *am = &api_main;
961  u32 offset;
962 
963  shmem_vec = *shmem_vecp;
964 
965  offset = vec_len (shmem_vec);
966 
967  pthread_mutex_lock (&am->vlib_rp->mutex);
968  oldheap = svm_push_data_heap (am->vlib_rp);
969 
970  vec_validate (shmem_vec, offset + buffer_bytes - 1);
971 
972  clib_memcpy (shmem_vec + offset, buffer, buffer_bytes);
973 
974  svm_pop_heap (oldheap);
975  pthread_mutex_unlock (&am->vlib_rp->mutex);
976 
977  *shmem_vecp = shmem_vec;
978 }
979 
980 
981 static void
983 {
984  vl_api_cli_reply_t *rp;
987  api_main_t *am = &api_main;
988  unformat_input_t input;
989  u8 *shmem_vec = 0;
990  void *oldheap;
991 
993  if (!q)
994  return;
995 
996  rp = vl_msg_api_alloc (sizeof (*rp));
997  rp->_vl_msg_id = ntohs (VL_API_CLI_REPLY);
998  rp->context = mp->context;
999 
1000  unformat_init_vector (&input, (u8 *) (uword) mp->cmd_in_shmem);
1001 
1002  vlib_cli_input (vm, &input, shmem_cli_output, (uword) & shmem_vec);
1003 
1004  pthread_mutex_lock (&am->vlib_rp->mutex);
1005  oldheap = svm_push_data_heap (am->vlib_rp);
1006 
1007  vec_add1 (shmem_vec, 0);
1008 
1009  svm_pop_heap (oldheap);
1010  pthread_mutex_unlock (&am->vlib_rp->mutex);
1011 
1012  rp->reply_in_shmem = (uword) shmem_vec;
1013 
1014  vl_msg_api_send_shmem (q, (u8 *) & rp);
1015 }
1016 
1017 static void
1018 inband_cli_output (uword arg, u8 * buffer, uword buffer_bytes)
1019 {
1020  u8 **mem_vecp = (u8 **) arg;
1021  u8 *mem_vec = *mem_vecp;
1022  u32 offset = vec_len (mem_vec);
1023 
1024  vec_validate (mem_vec, offset + buffer_bytes - 1);
1025  clib_memcpy (mem_vec + offset, buffer, buffer_bytes);
1026  *mem_vecp = mem_vec;
1027 }
1028 
1029 static void
1031 {
1033  int rv = 0;
1036  unformat_input_t input;
1037  u8 *out_vec = 0;
1038 
1040  if (!q)
1041  return;
1042 
1043  unformat_init_string (&input, (char *) mp->cmd, ntohl (mp->length));
1044  vlib_cli_input (vm, &input, inband_cli_output, (uword) & out_vec);
1045 
1046  u32 len = vec_len (out_vec);
1047  /* *INDENT-OFF* */
1048  REPLY_MACRO3(VL_API_CLI_INBAND_REPLY, len,
1049  ({
1050  rmp->length = htonl (len);
1051  clib_memcpy (rmp->reply, out_vec, len);
1052  }));
1053  /* *INDENT-ON* */
1054  vec_free (out_vec);
1055 }
1056 
1057 static void
1059 {
1060  int rv;
1061  vl_api_set_arp_neighbor_limit_reply_t *rmp;
1062  vnet_main_t *vnm = vnet_get_main ();
1063  clib_error_t *error;
1064 
1065  vnm->api_errno = 0;
1066 
1067  if (mp->is_ipv6)
1068  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
1069  else
1070  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
1071 
1072  if (error)
1073  {
1074  clib_error_report (error);
1075  rv = VNET_API_ERROR_UNSPECIFIED;
1076  }
1077  else
1078  {
1079  rv = vnm->api_errno;
1080  }
1081 
1082  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
1083 }
1084 
1087 {
1089  vl_api_classify_set_interface_ip_table_reply_t *rmp;
1090  int rv;
1091 
1092  VALIDATE_SW_IF_INDEX (mp);
1093 
1094  u32 table_index = ntohl (mp->table_index);
1095  u32 sw_if_index = ntohl (mp->sw_if_index);
1096 
1097  if (mp->is_ipv6)
1098  rv = vnet_set_ip6_classify_intfc (vm, sw_if_index, table_index);
1099  else
1100  rv = vnet_set_ip4_classify_intfc (vm, sw_if_index, table_index);
1101 
1103 
1104  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_IP_TABLE_REPLY);
1105 }
1106 
1109 {
1110  vl_api_classify_set_interface_l2_tables_reply_t *rmp;
1111  int rv;
1112  u32 sw_if_index, ip4_table_index, ip6_table_index, other_table_index;
1113  int enable;
1114 
1115  ip4_table_index = ntohl (mp->ip4_table_index);
1116  ip6_table_index = ntohl (mp->ip6_table_index);
1117  other_table_index = ntohl (mp->other_table_index);
1118  sw_if_index = ntohl (mp->sw_if_index);
1119 
1120  VALIDATE_SW_IF_INDEX (mp);
1121 
1122  if (mp->is_input)
1123  rv = vnet_l2_input_classify_set_tables (sw_if_index, ip4_table_index,
1124  ip6_table_index,
1125  other_table_index);
1126  else
1127  rv = vnet_l2_output_classify_set_tables (sw_if_index, ip4_table_index,
1128  ip6_table_index,
1129  other_table_index);
1130 
1131  if (rv == 0)
1132  {
1133  if (ip4_table_index != ~0 || ip6_table_index != ~0
1134  || other_table_index != ~0)
1135  enable = 1;
1136  else
1137  enable = 0;
1138 
1139  if (mp->is_input)
1140  vnet_l2_input_classify_enable_disable (sw_if_index, enable);
1141  else
1142  vnet_l2_output_classify_enable_disable (sw_if_index, enable);
1143  }
1144 
1146 
1147  REPLY_MACRO (VL_API_CLASSIFY_SET_INTERFACE_L2_TABLES_REPLY);
1148 }
1149 
1151  u32 sw_if_index, u32 enable);
1152 
1153 static void
1155  mp)
1156 {
1157  int rv;
1158  vl_api_l2_interface_efp_filter_reply_t *rmp;
1159  vnet_main_t *vnm = vnet_get_main ();
1160 
1161  // enable/disable the feature
1163  rv = vnm->api_errno;
1164 
1165  REPLY_MACRO (VL_API_L2_INTERFACE_EFP_FILTER_REPLY);
1166 }
1167 
1168 static void
1170 {
1172  int rv = 0;
1173  char *vpe_api_get_build_directory (void);
1174  char *vpe_api_get_version (void);
1175  char *vpe_api_get_build_date (void);
1176 
1179 
1180  if (!q)
1181  return;
1182 
1183  /* *INDENT-OFF* */
1184  REPLY_MACRO2(VL_API_SHOW_VERSION_REPLY,
1185  ({
1186  strncpy ((char *) rmp->program, "vpe", ARRAY_LEN(rmp->program)-1);
1187  strncpy ((char *) rmp->build_directory, vpe_api_get_build_directory(),
1188  ARRAY_LEN(rmp->build_directory)-1);
1189  strncpy ((char *) rmp->version, vpe_api_get_version(),
1190  ARRAY_LEN(rmp->version)-1);
1191  strncpy ((char *) rmp->build_date, vpe_api_get_build_date(),
1192  ARRAY_LEN(rmp->build_date)-1);
1193  }));
1194  /* *INDENT-ON* */
1195 }
1196 
1197 static void
1199 {
1202  vlib_node_t *n;
1203  int rv = 0;
1204  u32 node_index = ~0;
1205 
1206  n = vlib_get_node_by_name (vm, mp->node_name);
1207 
1208  if (n == 0)
1209  rv = VNET_API_ERROR_NO_SUCH_NODE;
1210  else
1211  node_index = n->index;
1212 
1213  /* *INDENT-OFF* */
1214  REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
1215  ({
1216  rmp->node_index = ntohl(node_index);
1217  }));
1218  /* *INDENT-ON* */
1219 }
1220 
1221 static void
1223 {
1226  vlib_node_t *node, *next_node;
1227  int rv = 0;
1228  u32 next_node_index = ~0, next_index = ~0;
1229  uword *p;
1230 
1231  node = vlib_get_node_by_name (vm, mp->node_name);
1232 
1233  if (node == 0)
1234  {
1235  rv = VNET_API_ERROR_NO_SUCH_NODE;
1236  goto out;
1237  }
1238 
1239  next_node = vlib_get_node_by_name (vm, mp->next_name);
1240 
1241  if (next_node == 0)
1242  {
1243  rv = VNET_API_ERROR_NO_SUCH_NODE2;
1244  goto out;
1245  }
1246  else
1247  next_node_index = next_node->index;
1248 
1249  p = hash_get (node->next_slot_by_node, next_node_index);
1250 
1251  if (p == 0)
1252  {
1253  rv = VNET_API_ERROR_NO_SUCH_ENTRY;
1254  goto out;
1255  }
1256  else
1257  next_index = p[0];
1258 
1259 out:
1260  /* *INDENT-OFF* */
1261  REPLY_MACRO2(VL_API_GET_NEXT_INDEX_REPLY,
1262  ({
1263  rmp->next_index = ntohl(next_index);
1264  }));
1265  /* *INDENT-ON* */
1266 }
1267 
1268 static void
1270 {
1273  vlib_node_t *n, *next;
1274  int rv = 0;
1275  u32 next_index = ~0;
1276 
1277  n = vlib_get_node_by_name (vm, mp->node_name);
1278 
1279  if (n == 0)
1280  {
1281  rv = VNET_API_ERROR_NO_SUCH_NODE;
1282  goto out;
1283  }
1284 
1285  next = vlib_get_node_by_name (vm, mp->next_name);
1286 
1287  if (next == 0)
1288  rv = VNET_API_ERROR_NO_SUCH_NODE2;
1289  else
1290  next_index = vlib_node_add_next (vm, n->index, next->index);
1291 
1292 out:
1293  /* *INDENT-OFF* */
1294  REPLY_MACRO2(VL_API_GET_NODE_INDEX_REPLY,
1295  ({
1296  rmp->next_index = ntohl(next_index);
1297  }));
1298  /* *INDENT-ON* */
1299 }
1300 
1301 static void
1303 {
1304  extern int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
1305  int is_add);
1306  vl_api_l2_patch_add_del_reply_t *rmp;
1307  int vnet_l2_patch_add_del (u32 rx_sw_if_index, u32 tx_sw_if_index,
1308  int is_add);
1309  int rv = 0;
1310 
1313 
1314  rv = vnet_l2_patch_add_del (ntohl (mp->rx_sw_if_index),
1315  ntohl (mp->tx_sw_if_index),
1316  (int) (mp->is_add != 0));
1317 
1320 
1321  REPLY_MACRO (VL_API_L2_PATCH_ADD_DEL_REPLY);
1322 }
1323 
1324 static void
1326  mp)
1327 {
1328  vl_api_interface_name_renumber_reply_t *rmp;
1329  int rv = 0;
1330 
1331  VALIDATE_SW_IF_INDEX (mp);
1332 
1334  (ntohl (mp->sw_if_index), ntohl (mp->new_show_dev_instance));
1335 
1337 
1338  REPLY_MACRO (VL_API_INTERFACE_NAME_RENUMBER_REPLY);
1339 }
1340 
1341 static int
1342 arp_change_data_callback (u32 pool_index, u8 * new_mac,
1343  u32 sw_if_index, u32 address)
1344 {
1346  vlib_main_t *vm = am->vlib_main;
1347  vl_api_ip4_arp_event_t *event;
1348 
1349  if (pool_is_free_index (am->arp_events, pool_index))
1350  return 1;
1351 
1352  event = pool_elt_at_index (am->arp_events, pool_index);
1353  if (eth_mac_equal (event->new_mac, new_mac) &&
1354  sw_if_index == ntohl (event->sw_if_index))
1355  {
1356  return 1;
1357  }
1358 
1359  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
1360  event->sw_if_index = htonl (sw_if_index);
1361  return 0;
1362 }
1363 
1364 static int
1365 nd_change_data_callback (u32 pool_index, u8 * new_mac,
1366  u32 sw_if_index, ip6_address_t * address)
1367 {
1369  vlib_main_t *vm = am->vlib_main;
1370  vl_api_ip6_nd_event_t *event;
1371 
1372  if (pool_is_free_index (am->nd_events, pool_index))
1373  return 1;
1374 
1375  event = pool_elt_at_index (am->nd_events, pool_index);
1376  if (eth_mac_equal (event->new_mac, new_mac) &&
1377  sw_if_index == ntohl (event->sw_if_index))
1378  {
1379  return 1;
1380  }
1381 
1382  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
1383  event->sw_if_index = htonl (sw_if_index);
1384  return 0;
1385 }
1386 
1387 static int
1388 arp_change_delete_callback (u32 pool_index, u8 * notused)
1389 {
1391 
1392  if (pool_is_free_index (am->arp_events, pool_index))
1393  return 1;
1394 
1395  pool_put_index (am->arp_events, pool_index);
1396  return 0;
1397 }
1398 
1399 static int
1400 nd_change_delete_callback (u32 pool_index, u8 * notused)
1401 {
1403 
1404  if (pool_is_free_index (am->nd_events, pool_index))
1405  return 1;
1406 
1407  pool_put_index (am->nd_events, pool_index);
1408  return 0;
1409 }
1410 
1412 
1413 enum
1415 
1416 static uword
1418 {
1419  /* These cross the longjmp boundry (vlib_process_wait_for_event)
1420  * and need to be volatile - to prevent them from being optimized into
1421  * a register - which could change during suspension */
1422 
1423  volatile wc_arp_report_t arp_prev = { 0 };
1424  volatile wc_nd_report_t nd_prev = { 0 };
1425  volatile f64 last_arp = vlib_time_now (vm);
1426  volatile f64 last_nd = vlib_time_now (vm);
1427 
1428  while (1)
1429  {
1431  uword event_type;
1432  void *event_data = vlib_process_get_event_data (vm, &event_type);
1433 
1434  f64 now = vlib_time_now (vm);
1435  int i;
1436  if (event_type == WC_ARP_REPORT)
1437  {
1438  wc_arp_report_t *arp_events = event_data;
1439  for (i = 0; i < vec_len (arp_events); i++)
1440  {
1441  /* discard dup event */
1442  if (arp_prev.ip4 == arp_events[i].ip4 &&
1443  eth_mac_equal ((u8 *) arp_prev.mac, arp_events[i].mac) &&
1444  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
1445  (now - last_arp) < 10.0)
1446  {
1447  continue;
1448  }
1449  arp_prev = arp_events[i];
1450  last_arp = now;
1452  /* *INDENT-OFF* */
1453  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
1454  ({
1455  unix_shared_memory_queue_t *q;
1456  q = vl_api_client_index_to_input_queue (reg->client_index);
1457  if (q && q->cursize < q->maxsize)
1458  {
1459  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
1460  memset (event, 0, sizeof *event);
1461  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
1462  event->client_index = reg->client_index;
1463  event->pid = reg->client_pid;
1464  event->mac_ip = 1;
1465  event->address = arp_events[i].ip4;
1466  event->sw_if_index = htonl(arp_events[i].sw_if_index);
1467  memcpy(event->new_mac, arp_events[i].mac, sizeof event->new_mac);
1468  vl_msg_api_send_shmem (q, (u8 *) &event);
1469  }
1470  }));
1471  /* *INDENT-ON* */
1472  }
1473  }
1474  else if (event_type == WC_ND_REPORT)
1475  {
1476  wc_nd_report_t *nd_events = event_data;
1477  for (i = 0; i < vec_len (nd_events); i++)
1478  {
1479  /* discard dup event */
1481  ((ip6_address_t *) & nd_prev.ip6, &nd_events[i].ip6)
1482  && eth_mac_equal ((u8 *) nd_prev.mac, nd_events[i].mac)
1483  && nd_prev.sw_if_index == nd_events[i].sw_if_index
1484  && (now - last_nd) < 10.0)
1485  {
1486  continue;
1487  }
1488  nd_prev = nd_events[i];
1489  last_nd = now;
1491  /* *INDENT-OFF* */
1492  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
1493  ({
1494  unix_shared_memory_queue_t *q;
1495  q = vl_api_client_index_to_input_queue (reg->client_index);
1496  if (q && q->cursize < q->maxsize)
1497  {
1498  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
1499  memset (event, 0, sizeof *event);
1500  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
1501  event->client_index = reg->client_index;
1502  event->pid = reg->client_pid;
1503  event->mac_ip = 1;
1504  memcpy(event->address, nd_events[i].ip6.as_u8, sizeof event->address);
1505  event->sw_if_index = htonl(nd_events[i].sw_if_index);
1506  memcpy(event->new_mac, nd_events[i].mac, sizeof event->new_mac);
1507  vl_msg_api_send_shmem (q, (u8 *) &event);
1508  }
1509  }));
1510  /* *INDENT-ON* */
1511  }
1512  }
1513  vlib_process_put_event_data (vm, event_data);
1514  }
1515 
1516  return 0;
1517 }
1518 
1519 /* *INDENT-OFF* */
1520 VLIB_REGISTER_NODE (wc_arp_process_node,static) = {
1521  .function = wc_arp_process,
1522  .type = VLIB_NODE_TYPE_PROCESS,
1523  .name = "wildcard-ip4-arp-publisher-process",
1524 };
1525 /* *INDENT-ON* */
1526 
1527 static void
1529 {
1531  vnet_main_t *vnm = vnet_get_main ();
1532  vl_api_want_ip4_arp_events_reply_t *rmp;
1533  int rv = 0;
1534 
1535  if (mp->address == 0)
1536  {
1537  uword *p =
1538  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
1540  if (p)
1541  {
1542  if (mp->enable_disable)
1543  {
1544  clib_warning ("pid %d: already enabled...", mp->pid);
1545  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1546  goto reply;
1547  }
1548  else
1549  {
1550  rp =
1551  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
1552  pool_put (am->wc_ip4_arp_events_registrations, rp);
1553  hash_unset (am->wc_ip4_arp_events_registration_hash,
1554  mp->client_index);
1555  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
1557  goto reply;
1558  }
1559  }
1560  if (mp->enable_disable == 0)
1561  {
1562  clib_warning ("pid %d: already disabled...", mp->pid);
1563  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1564  goto reply;
1565  }
1566  pool_get (am->wc_ip4_arp_events_registrations, rp);
1567  rp->client_index = mp->client_index;
1568  rp->client_pid = mp->pid;
1569  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
1570  rp - am->wc_ip4_arp_events_registrations);
1571  wc_arp_set_publisher_node (wc_arp_process_node.index, WC_ARP_REPORT);
1572  goto reply;
1573  }
1574 
1575  if (mp->enable_disable)
1576  {
1577  vl_api_ip4_arp_event_t *event;
1578  pool_get (am->arp_events, event);
1581  mp->pid, &mp->address /* addr, in net byte order */ ,
1582  vpe_resolver_process_node.index,
1583  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
1584 
1585  if (rv)
1586  {
1587  pool_put (am->arp_events, event);
1588  goto reply;
1589  }
1590  memset (event, 0, sizeof (*event));
1591 
1592  /* Python API expects events to have no context */
1593  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
1594  event->client_index = mp->client_index;
1595  event->address = mp->address;
1596  event->pid = mp->pid;
1597  if (mp->address == 0)
1598  event->mac_ip = 1;
1599  }
1600  else
1601  {
1604  mp->pid, &mp->address /* addr, in net byte order */ ,
1605  vpe_resolver_process_node.index,
1606  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
1607  }
1608 reply:
1609  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
1610 }
1611 
1612 static void
1614 {
1616  vnet_main_t *vnm = vnet_get_main ();
1617  vl_api_want_ip6_nd_events_reply_t *rmp;
1618  int rv = 0;
1619 
1621  {
1622  uword *p =
1623  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
1625  if (p)
1626  {
1627  if (mp->enable_disable)
1628  {
1629  clib_warning ("pid %d: already enabled...", mp->pid);
1630  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1631  goto reply;
1632  }
1633  else
1634  {
1635  rp =
1636  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
1637  pool_put (am->wc_ip6_nd_events_registrations, rp);
1638  hash_unset (am->wc_ip6_nd_events_registration_hash,
1639  mp->client_index);
1640  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
1641  wc_nd_set_publisher_node (~0, 2);
1642  goto reply;
1643  }
1644  }
1645  if (mp->enable_disable == 0)
1646  {
1647  clib_warning ("pid %d: already disabled...", mp->pid);
1648  rv = VNET_API_ERROR_INVALID_REGISTRATION;
1649  goto reply;
1650  }
1651  pool_get (am->wc_ip6_nd_events_registrations, rp);
1652  rp->client_index = mp->client_index;
1653  rp->client_pid = mp->pid;
1654  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
1655  rp - am->wc_ip6_nd_events_registrations);
1656  wc_nd_set_publisher_node (wc_arp_process_node.index, WC_ND_REPORT);
1657  goto reply;
1658  }
1659 
1660  if (mp->enable_disable)
1661  {
1662  vl_api_ip6_nd_event_t *event;
1663  pool_get (am->nd_events, event);
1664 
1667  mp->pid, mp->address /* addr, in net byte order */ ,
1668  vpe_resolver_process_node.index,
1669  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
1670 
1671  if (rv)
1672  {
1673  pool_put (am->nd_events, event);
1674  goto reply;
1675  }
1676  memset (event, 0, sizeof (*event));
1677 
1678  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
1679  event->client_index = mp->client_index;
1680  clib_memcpy (event->address, mp->address, sizeof event->address);
1681  event->pid = mp->pid;
1682  }
1683  else
1684  {
1687  mp->pid, mp->address /* addr, in net byte order */ ,
1688  vpe_resolver_process_node.index,
1689  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
1690  }
1691 reply:
1692  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
1693 }
1694 
1697 {
1699  vl_api_input_acl_set_interface_reply_t *rmp;
1700  int rv;
1701 
1702  VALIDATE_SW_IF_INDEX (mp);
1703 
1704  u32 ip4_table_index = ntohl (mp->ip4_table_index);
1705  u32 ip6_table_index = ntohl (mp->ip6_table_index);
1706  u32 l2_table_index = ntohl (mp->l2_table_index);
1707  u32 sw_if_index = ntohl (mp->sw_if_index);
1708 
1709  rv = vnet_set_input_acl_intfc (vm, sw_if_index, ip4_table_index,
1710  ip6_table_index, l2_table_index, mp->is_add);
1711 
1713 
1714  REPLY_MACRO (VL_API_INPUT_ACL_SET_INTERFACE_REPLY);
1715 }
1716 
1717 static void
1719 {
1720  int rv = 0;
1721  u8 *vector = 0;
1722  api_main_t *am = &api_main;
1724  void *oldheap;
1726 
1727  pthread_mutex_lock (&am->vlib_rp->mutex);
1728  oldheap = svm_push_data_heap (am->vlib_rp);
1729 
1730  /*
1731  * Keep the number of memcpy ops to a minimum (e.g. 1).
1732  */
1733  vec_validate (vector, 16384);
1734  vec_reset_length (vector);
1735 
1736  /* $$$$ FIXME */
1737  vector = vlib_node_serialize (&vm->node_main, vector,
1738  (u32) ~ 0 /* all threads */ ,
1739  1 /* include nexts */ ,
1740  1 /* include stats */ );
1741 
1742  svm_pop_heap (oldheap);
1743  pthread_mutex_unlock (&am->vlib_rp->mutex);
1744 
1745  /* *INDENT-OFF* */
1746  REPLY_MACRO2(VL_API_GET_NODE_GRAPH_REPLY,
1747  ({
1748  rmp->reply_in_shmem = (uword) vector;
1749  }));
1750  /* *INDENT-ON* */
1751 }
1752 
1753 static void
1755 {
1756  int rv = 0;
1757  vl_api_ioam_enable_reply_t *rmp;
1758  clib_error_t *error;
1759 
1760  /* Ignoring the profile id as currently a single profile
1761  * is supported */
1762  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
1763  mp->seqno, mp->analyse);
1764  if (error)
1765  {
1766  clib_error_report (error);
1767  rv = clib_error_get_code (error);
1768  }
1769 
1770  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
1771 }
1772 
1773 static void
1775 {
1776  int rv = 0;
1777  vl_api_ioam_disable_reply_t *rmp;
1778  clib_error_t *error;
1779 
1780  error = clear_ioam_rewrite_fn ();
1781  if (error)
1782  {
1783  clib_error_report (error);
1784  rv = clib_error_get_code (error);
1785  }
1786 
1787  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
1788 }
1789 
1790 static void
1792 {
1794  int rv = 0;
1795 
1796  pg_main_t *pg = &pg_main;
1797  u32 pg_if_id = pg_interface_add_or_get (pg, ntohl (mp->interface_id));
1798  pg_interface_t *pi = pool_elt_at_index (pg->interfaces, pg_if_id);
1799 
1800  /* *INDENT-OFF* */
1801  REPLY_MACRO2(VL_API_PG_CREATE_INTERFACE_REPLY,
1802  ({
1803  rmp->sw_if_index = ntohl(pi->sw_if_index);
1804  }));
1805  /* *INDENT-ON* */
1806 }
1807 
1808 static void
1810 {
1811  vl_api_pg_capture_reply_t *rmp;
1812  int rv = 0;
1813 
1814  vnet_main_t *vnm = vnet_get_main ();
1816  vnet_hw_interface_t *hi = 0;
1817 
1818  u8 *intf_name = format (0, "pg%d", ntohl (mp->interface_id), 0);
1819  u32 hw_if_index = ~0;
1820  uword *p = hash_get_mem (im->hw_interface_by_name, intf_name);
1821  if (p)
1822  hw_if_index = *p;
1823  vec_free (intf_name);
1824 
1825  if (hw_if_index != ~0)
1826  {
1827  pg_capture_args_t _a, *a = &_a;
1828 
1829  u32 len = ntohl (mp->pcap_name_length);
1830  u8 *pcap_file_name = vec_new (u8, len);
1831  clib_memcpy (pcap_file_name, mp->pcap_file_name, len);
1832 
1833  hi = vnet_get_sup_hw_interface (vnm, hw_if_index);
1834  a->hw_if_index = hw_if_index;
1835  a->dev_instance = hi->dev_instance;
1836  a->is_enabled = mp->is_enabled;
1837  a->pcap_file_name = pcap_file_name;
1838  a->count = ntohl (mp->count);
1839 
1840  clib_error_t *e = pg_capture (a);
1841  if (e)
1842  {
1843  clib_error_report (e);
1844  rv = VNET_API_ERROR_CANNOT_CREATE_PCAP_FILE;
1845  }
1846 
1847  vec_free (pcap_file_name);
1848  }
1849  REPLY_MACRO (VL_API_PG_CAPTURE_REPLY);
1850 }
1851 
1852 static void
1854 {
1855  vl_api_pg_enable_disable_reply_t *rmp;
1856  int rv = 0;
1857 
1858  pg_main_t *pg = &pg_main;
1859  u32 stream_index = ~0;
1860 
1861  int is_enable = mp->is_enabled != 0;
1862  u32 len = ntohl (mp->stream_name_length) - 1;
1863 
1864  if (len > 0)
1865  {
1866  u8 *stream_name = vec_new (u8, len);
1867  clib_memcpy (stream_name, mp->stream_name, len);
1868  uword *p = hash_get_mem (pg->stream_index_by_name, stream_name);
1869  if (p)
1870  stream_index = *p;
1871  vec_free (stream_name);
1872  }
1873 
1874  pg_enable_disable (stream_index, is_enable);
1875 
1876  REPLY_MACRO (VL_API_PG_ENABLE_DISABLE_REPLY);
1877 }
1878 
1879 static void
1882 {
1883  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
1884  int rv = 0;
1885 
1886  u8 is_ipv6 = mp->is_ipv6;
1887  u8 is_add = mp->is_add;
1888  u8 mask_length = mp->mask_length;
1889  ip4_address_t ip4_addr;
1890  ip6_address_t ip6_addr;
1891  u16 *low_ports = 0;
1892  u16 *high_ports = 0;
1893  u32 vrf_id;
1894  u16 tmp_low, tmp_high;
1895  u8 num_ranges;
1896  int i;
1897 
1898  // Validate port range
1899  num_ranges = mp->number_of_ranges;
1900  if (num_ranges > 32)
1901  { // This is size of array in VPE.API
1902  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1903  goto reply;
1904  }
1905 
1906  vec_reset_length (low_ports);
1907  vec_reset_length (high_ports);
1908 
1909  for (i = 0; i < num_ranges; i++)
1910  {
1911  tmp_low = mp->low_ports[i];
1912  tmp_high = mp->high_ports[i];
1913  // If tmp_low <= tmp_high then only need to check tmp_low = 0
1914  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
1915  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
1916  {
1917  rv = VNET_API_ERROR_INVALID_VALUE;
1918  goto reply;
1919  }
1920  vec_add1 (low_ports, tmp_low);
1921  vec_add1 (high_ports, tmp_high + 1);
1922  }
1923 
1924  // Validate mask_length
1925  if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
1926  {
1927  rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
1928  goto reply;
1929  }
1930 
1931  vrf_id = ntohl (mp->vrf_id);
1932 
1933  if (vrf_id < 1)
1934  {
1935  rv = VNET_API_ERROR_INVALID_VALUE;
1936  goto reply;
1937  }
1938 
1939 
1940  if (is_ipv6)
1941  {
1942  clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
1944  mask_length,
1945  vrf_id,
1946  low_ports,
1947  high_ports, is_add);
1948  }
1949  else
1950  {
1951  clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
1953  mask_length,
1954  vrf_id,
1955  low_ports,
1956  high_ports, is_add);
1957  }
1958 
1959 reply:
1960  vec_free (low_ports);
1961  vec_free (high_ports);
1962  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
1963 }
1964 
1965 static void
1968 {
1970  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
1971  ip4_main_t *im = &ip4_main;
1972  int rv;
1973  u32 sw_if_index;
1976  uword *p = 0;
1977  int i;
1978 
1980  ntohl (mp->tcp_out_vrf_id);
1982  ntohl (mp->udp_out_vrf_id);
1984  ntohl (mp->tcp_in_vrf_id);
1986  ntohl (mp->udp_in_vrf_id);
1987 
1988 
1989  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
1990  {
1991  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
1992  {
1993  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
1994 
1995  if (p == 0)
1996  {
1997  rv = VNET_API_ERROR_INVALID_VALUE;
1998  goto reply;
1999  }
2000 
2001  fib_index[i] = p[0];
2002  }
2003  else
2004  fib_index[i] = ~0;
2005  }
2006  sw_if_index = ntohl (mp->sw_if_index);
2007 
2008  VALIDATE_SW_IF_INDEX (mp);
2009 
2010  rv =
2011  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
2012  mp->is_add);
2013 
2015 reply:
2016 
2017  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
2018 }
2019 
2020 static void
2022 {
2023  vl_api_delete_subif_reply_t *rmp;
2024  int rv;
2025 
2026  rv = vnet_delete_sub_interface (ntohl (mp->sw_if_index));
2027 
2028  REPLY_MACRO (VL_API_DELETE_SUBIF_REPLY);
2029 }
2030 
2031 static void
2033 {
2034  vl_api_punt_reply_t *rmp;
2036  int rv = 0;
2037  clib_error_t *error;
2038 
2039  error = vnet_punt_add_del (vm, mp->ipv, mp->l4_protocol,
2040  ntohs (mp->l4_port), mp->is_add);
2041  if (error)
2042  {
2043  rv = -1;
2044  clib_error_report (error);
2045  }
2046 
2047  REPLY_MACRO (VL_API_PUNT_REPLY);
2048 }
2049 
2050 static void
2052 {
2055  int rv = 0;
2056  clib_error_t *error;
2058  u32 handle;
2059 
2060  error = vnet_punt_socket_add (vm, ntohl (mp->header_version),
2061  mp->is_ip4, mp->l4_protocol,
2062  ntohs (mp->l4_port), (char *) mp->pathname);
2063  if (error)
2064  {
2065  rv = -1;
2066  clib_error_report (error);
2067  }
2068 
2070  if (!q)
2071  return;
2072 
2073  rmp = vl_msg_api_alloc (sizeof (*rmp));
2074  rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_REGISTER_REPLY);
2075  rmp->context = mp->context;
2076  rmp->retval = htonl (rv);
2077  char *p = vnet_punt_get_server_pathname ();
2078  /* Abstract pathnames start with \0 */
2079  memcpy ((char *) rmp->pathname, p, sizeof (rmp->pathname));
2080  vl_msg_api_send_shmem (q, (u8 *) & rmp);
2081 }
2082 
2083 static void
2085 {
2086  vl_api_punt_socket_deregister_reply_t *rmp;
2088  int rv = 0;
2089  clib_error_t *error;
2091  u32 handle;
2092 
2093  error = vnet_punt_socket_del (vm, mp->is_ip4, mp->l4_protocol,
2094  ntohs (mp->l4_port));
2095  if (error)
2096  {
2097  rv = -1;
2098  clib_error_report (error);
2099  }
2100 
2102  if (!q)
2103  return;
2104 
2105  rmp = vl_msg_api_alloc (sizeof (*rmp));
2106  rmp->_vl_msg_id = htons (VL_API_PUNT_SOCKET_DEREGISTER_REPLY);
2107  rmp->context = mp->context;
2108  rmp->retval = htonl (rv);
2109  vl_msg_api_send_shmem (q, (u8 *) & rmp);
2110 }
2111 
2112 static void
2114 {
2115  vl_api_feature_enable_disable_reply_t *rmp;
2116  int rv = 0;
2117 
2118  VALIDATE_SW_IF_INDEX (mp);
2119 
2120  u8 *arc_name = format (0, "%s%c", mp->arc_name, 0);
2121  u8 *feature_name = format (0, "%s%c", mp->feature_name, 0);
2122 
2124  vnet_get_feature_reg ((const char *) arc_name,
2125  (const char *) feature_name);
2126  if (reg == 0)
2127  rv = VNET_API_ERROR_INVALID_VALUE;
2128  else
2129  {
2130  u32 sw_if_index = ntohl (mp->sw_if_index);
2131  clib_error_t *error = 0;
2132 
2133  if (reg->enable_disable_cb)
2134  error = reg->enable_disable_cb (sw_if_index, mp->enable);
2135  if (!error)
2136  vnet_feature_enable_disable ((const char *) arc_name,
2137  (const char *) feature_name,
2138  sw_if_index, mp->enable, 0, 0);
2139  else
2140  {
2141  clib_error_report (error);
2142  rv = VNET_API_ERROR_CANNOT_ENABLE_DISABLE_FEATURE;
2143  }
2144  }
2145 
2146  vec_free (feature_name);
2147  vec_free (arc_name);
2148 
2150 
2151  REPLY_MACRO (VL_API_FEATURE_ENABLE_DISABLE_REPLY);
2152 }
2153 
2154 #define BOUNCE_HANDLER(nn) \
2155 static void vl_api_##nn##_t_handler ( \
2156  vl_api_##nn##_t *mp) \
2157 { \
2158  vpe_client_registration_t *reg; \
2159  vpe_api_main_t * vam = &vpe_api_main; \
2160  unix_shared_memory_queue_t * q; \
2161  \
2162  /* One registration only... */ \
2163  pool_foreach(reg, vam->nn##_registrations, \
2164  ({ \
2165  q = vl_api_client_index_to_input_queue (reg->client_index); \
2166  if (q) { \
2167  /* \
2168  * If the queue is stuffed, turf the msg and complain \
2169  * It's unlikely that the intended recipient is \
2170  * alive; avoid deadlock at all costs. \
2171  */ \
2172  if (q->cursize == q->maxsize) { \
2173  clib_warning ("ERROR: receiver queue full, drop msg"); \
2174  vl_msg_api_free (mp); \
2175  return; \
2176  } \
2177  vl_msg_api_send_shmem (q, (u8 *)&mp); \
2178  return; \
2179  } \
2180  })); \
2181  vl_msg_api_free (mp); \
2182 }
2183 
2184 static void setup_message_id_table (api_main_t * am);
2185 
2186 /*
2187  * vpe_api_hookup
2188  * Add vpe's API message handlers to the table.
2189  * vlib has alread mapped shared memory and
2190  * added the client registration handlers.
2191  * See .../open-repo/vlib/memclnt_vlib.c:memclnt_process()
2192  */
2193 static clib_error_t *
2195 {
2196  api_main_t *am = &api_main;
2197 
2198 #define _(N,n) \
2199  vl_msg_api_set_handlers(VL_API_##N, #n, \
2200  vl_api_##n##_t_handler, \
2201  vl_noop_handler, \
2202  vl_api_##n##_t_endian, \
2203  vl_api_##n##_t_print, \
2204  sizeof(vl_api_##n##_t), 1);
2206 #undef _
2207 
2208  /*
2209  * Trace space for classifier mask+match
2210  */
2211  am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_TABLE].size += 5 * sizeof (u32x4);
2212  am->api_trace_cfg[VL_API_CLASSIFY_ADD_DEL_SESSION].size
2213  += 5 * sizeof (u32x4);
2214 
2215  /*
2216  * Thread-safe API messages
2217  */
2218  am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
2219  am->is_mp_safe[VL_API_GET_NODE_GRAPH] = 1;
2220 
2221  /*
2222  * Set up the (msg_name, crc, message-id) table
2223  */
2225 
2226  return 0;
2227 }
2228 
2230 
2231 static clib_error_t *
2233 {
2235 
2236  am->vlib_main = vm;
2237  am->vnet_main = vnet_get_main ();
2238 #define _(a) \
2239  am->a##_registration_hash = hash_create (0, sizeof (uword));
2241 #undef _
2242 
2243  vl_set_memory_region_name ("/vpe-api");
2244  vl_enable_disable_memory_api (vm, 1 /* enable it */ );
2245 
2246  return 0;
2247 }
2248 
2250 
2251 
2252 static clib_error_t *
2254 {
2255  u8 *chroot_path;
2256  u64 baseva, size, pvt_heap_size;
2257  int uid, gid, rv;
2258  const int max_buf_size = 4096;
2259  char *s, *buf;
2260  struct passwd _pw, *pw;
2261  struct group _grp, *grp;
2262  clib_error_t *e;
2263  buf = vec_new (char, 128);
2264  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
2265  {
2266  if (unformat (input, "prefix %s", &chroot_path))
2267  {
2268  vec_add1 (chroot_path, 0);
2269  vl_set_memory_root_path ((char *) chroot_path);
2270  }
2271  else if (unformat (input, "uid %d", &uid))
2272  vl_set_memory_uid (uid);
2273  else if (unformat (input, "gid %d", &gid))
2274  vl_set_memory_gid (gid);
2275  else if (unformat (input, "baseva %llx", &baseva))
2276  vl_set_global_memory_baseva (baseva);
2277  else if (unformat (input, "global-size %lldM", &size))
2278  vl_set_global_memory_size (size * (1ULL << 20));
2279  else if (unformat (input, "global-size %lldG", &size))
2280  vl_set_global_memory_size (size * (1ULL << 30));
2281  else if (unformat (input, "global-size %lld", &size))
2283  else if (unformat (input, "global-pvt-heap-size %lldM", &pvt_heap_size))
2284  vl_set_global_pvt_heap_size (pvt_heap_size * (1ULL << 20));
2285  else if (unformat (input, "global-pvt-heap-size size %lld",
2286  &pvt_heap_size))
2287  vl_set_global_pvt_heap_size (pvt_heap_size);
2288  else if (unformat (input, "api-pvt-heap-size %lldM", &pvt_heap_size))
2289  vl_set_api_pvt_heap_size (pvt_heap_size * (1ULL << 20));
2290  else if (unformat (input, "api-pvt-heap-size size %lld",
2291  &pvt_heap_size))
2292  vl_set_api_pvt_heap_size (pvt_heap_size);
2293  else if (unformat (input, "api-size %lldM", &size))
2294  vl_set_api_memory_size (size * (1ULL << 20));
2295  else if (unformat (input, "api-size %lldG", &size))
2296  vl_set_api_memory_size (size * (1ULL << 30));
2297  else if (unformat (input, "api-size %lld", &size))
2298  vl_set_api_memory_size (size);
2299  else if (unformat (input, "uid %s", &s))
2300  {
2301  /* lookup the username */
2302  pw = NULL;
2303  while (((rv =
2304  getpwnam_r (s, &_pw, buf, vec_len (buf), &pw)) == ERANGE)
2305  && (vec_len (buf) <= max_buf_size))
2306  {
2307  vec_resize (buf, vec_len (buf) * 2);
2308  }
2309  if (rv < 0)
2310  {
2311  e = clib_error_return_code (0, rv,
2314  "cannot fetch username %s", s);
2315  vec_free (s);
2316  vec_free (buf);
2317  return e;
2318  }
2319  if (pw == NULL)
2320  {
2321  e =
2322  clib_error_return_fatal (0, "username %s does not exist", s);
2323  vec_free (s);
2324  vec_free (buf);
2325  return e;
2326  }
2327  vec_free (s);
2328  vl_set_memory_uid (pw->pw_uid);
2329  }
2330  else if (unformat (input, "gid %s", &s))
2331  {
2332  /* lookup the group name */
2333  grp = NULL;
2334  while (((rv =
2335  getgrnam_r (s, &_grp, buf, vec_len (buf), &grp)) == ERANGE)
2336  && (vec_len (buf) <= max_buf_size))
2337  {
2338  vec_resize (buf, vec_len (buf) * 2);
2339  }
2340  if (rv != 0)
2341  {
2342  e = clib_error_return_code (0, rv,
2345  "cannot fetch group %s", s);
2346  vec_free (s);
2347  vec_free (buf);
2348  return e;
2349  }
2350  if (grp == NULL)
2351  {
2352  e = clib_error_return_fatal (0, "group %s does not exist", s);
2353  vec_free (s);
2354  vec_free (buf);
2355  return e;
2356  }
2357  vec_free (s);
2358  vec_free (buf);
2359  vl_set_memory_gid (grp->gr_gid);
2360  }
2361  else
2362  return clib_error_return (0, "unknown input `%U'",
2363  format_unformat_error, input);
2364  }
2365  return 0;
2366 }
2367 
2369 
2370 void *
2372 {
2373  return (void *) &unformat_vnet_sw_interface;
2374 }
2375 
2376 static u8 *
2377 format_arp_event (u8 * s, va_list * args)
2378 {
2379  vl_api_ip4_arp_event_t *event = va_arg (*args, vl_api_ip4_arp_event_t *);
2380 
2381  s = format (s, "pid %d: ", ntohl (event->pid));
2382  s = format (s, "resolution for %U", format_ip4_address, &event->address);
2383  return s;
2384 }
2385 
2386 static u8 *
2387 format_nd_event (u8 * s, va_list * args)
2388 {
2389  vl_api_ip6_nd_event_t *event = va_arg (*args, vl_api_ip6_nd_event_t *);
2390 
2391  s = format (s, "pid %d: ", ntohl (event->pid));
2392  s = format (s, "resolution for %U", format_ip6_address, event->address);
2393  return s;
2394 }
2395 
2396 static clib_error_t *
2398  unformat_input_t * input, vlib_cli_command_t * cmd)
2399 {
2401  vl_api_ip4_arp_event_t *arp_event;
2402  vl_api_ip6_nd_event_t *nd_event;
2403 
2404  if (pool_elts (am->arp_events) == 0 && pool_elts (am->nd_events) == 0 &&
2405  pool_elts (am->wc_ip4_arp_events_registrations) == 0 &&
2406  pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2407  {
2408  vlib_cli_output (vm, "No active arp or nd event registrations");
2409  return 0;
2410  }
2411 
2412  /* *INDENT-OFF* */
2413  pool_foreach (arp_event, am->arp_events,
2414  ({
2415  vlib_cli_output (vm, "%U", format_arp_event, arp_event);
2416  }));
2417 
2419  pool_foreach(reg, am->wc_ip4_arp_events_registrations,
2420  ({
2421  vlib_cli_output (vm, "pid %d: bd mac/ip4 binding events",
2422  ntohl (reg->client_pid));
2423  }));
2424 
2425  pool_foreach (nd_event, am->nd_events,
2426  ({
2427  vlib_cli_output (vm, "%U", format_nd_event, nd_event);
2428  }));
2429 
2430  pool_foreach(reg, am->wc_ip6_nd_events_registrations,
2431  ({
2432  vlib_cli_output (vm, "pid %d: bd mac/ip6 binding events",
2433  ntohl (reg->client_pid));
2434  }));
2435  /* *INDENT-ON* */
2436 
2437  return 0;
2438 }
2439 
2440 /* *INDENT-OFF* */
2441 VLIB_CLI_COMMAND (show_ip_arp_nd_events, static) = {
2442  .path = "show arp-nd-event registrations",
2443  .function = show_ip_arp_nd_events_fn,
2444  .short_help = "Show ip4 arp and ip6 nd event registrations",
2445 };
2446 /* *INDENT-ON* */
2447 
2448 #define vl_msg_name_crc_list
2449 #include <vpp/api/vpe_all_api_h.h>
2450 #undef vl_msg_name_crc_list
2451 
2452 static void
2454 {
2455 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
2456  foreach_vl_msg_name_crc_memclnt;
2457  foreach_vl_msg_name_crc_vpe;
2458 #undef _
2459 }
2460 
2461 
2462 /*
2463  * fd.io coding-style-patch-verification: ON
2464  *
2465  * Local Variables:
2466  * eval: (c-set-style "gnu")
2467  * End:
2468  */
u32 sw_if_index
Definition: pg.h:294
static vlib_node_registration_t wc_arp_process_node
(constructor) VLIB_REGISTER_NODE (wc_arp_process_node)
Definition: api.c:1411
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:432
static void vl_api_create_loopback_t_handler(vl_api_create_loopback_t *mp)
Definition: api.c:891
static void vl_api_feature_enable_disable_t_handler(vl_api_feature_enable_disable_t *mp)
Definition: api.c:2113
vmrglw vmrglh hi
#define BAD_RX_SW_IF_INDEX_LABEL
Proxy ARP add / del request.
Definition: vpe.api:101
void vl_set_api_memory_size(u64 size)
clib_error_t * pg_capture(pg_capture_args_t *a)
Definition: cli.c:81
static clib_error_t * memclnt_delete_callback(u32 client_index)
Definition: api.c:166
static void vl_api_want_ip4_arp_events_t_handler(vl_api_want_ip4_arp_events_t *mp)
Definition: api.c:1528
#define hash_set(h, key, value)
Definition: hash.h:254
Register for ip6 nd resolution events.
Definition: vpe.api:626
#define VALIDATE_TX_SW_IF_INDEX(mp)
static void handle_ip4_arp_event(u32 pool_index)
Definition: api.c:201
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
vnet_main_t * vnet_main
void vl_enable_disable_memory_api(vlib_main_t *vm, int yesno)
Definition: memory_vlib.c:898
static void vl_api_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: api.c:877
Reset fib table request.
Definition: vpe.api:188
static void svm_pop_heap(void *oldheap)
Definition: svm.h:94
Reply for get next node index.
Definition: vpe.api:746
static void vl_api_interface_name_renumber_t_handler(vl_api_interface_name_renumber_t *mp)
Definition: api.c:1325
vpe parser cli string response
Definition: vpe.api:308
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
#define foreach_vpe_api_msg
Definition: api.c:102
#define hash_unset(h, key)
Definition: hash.h:260
a
Definition: bitmap.h:516
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:619
static void vl_api_cli_t_handler(vl_api_cli_t *mp)
Definition: api.c:982
void vlib_cli_input(vlib_main_t *vm, unformat_input_t *input, vlib_cli_output_function_t *function, uword function_arg)
Definition: cli.c:643
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static vnet_hw_interface_t * vnet_get_sup_hw_interface(vnet_main_t *vnm, u32 sw_if_index)
Definition: pg.h:310
static int arp_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, u32 address)
Definition: api.c:1342
int vnet_set_ip6_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 table_index)
Definition: ip6_forward.c:3397
void vl_set_memory_gid(int gid)
vnet_interface_main_t interface_main
Definition: vnet.h:56
Control ping from client to api server request.
Definition: vpe.api:264
int size
for sanity checking
Definition: api_common.h:71
u8 as_u8[16]
Definition: ip6_packet.h:48
OAM event structure.
Definition: vpe.api:144
Fixed length block allocator.
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:55
iOAM disable
Definition: vpe.api:720
u32 index
Definition: node.h:237
Set max allowed ARP or ip6 neighbor entries request.
Definition: vpe.api:328
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:221
int vnet_add_del_ip6_nd_change_event(vnet_main_t *vnm, void *data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
VLIB_API_INIT_FUNCTION(vpe_api_hookup)
uword * stream_index_by_name
Definition: pg.h:319
clib_error_t * ip4_set_arp_limit(u32 arp_limit)
Definition: arp.c:1443
static void vl_api_sw_interface_set_mpls_enable_t_handler(vl_api_sw_interface_set_mpls_enable_t *mp)
Definition: api.c:695
static clib_error_t * api_segment_config(vlib_main_t *vm, unformat_input_t *input)
Definition: api.c:2253
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:518
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1268
static void vl_api_punt_t_handler(vl_api_punt_t *mp)
Definition: api.c:2032
struct _vlib_node_registration vlib_node_registration_t
void vnet_l2_input_classify_enable_disable(u32 sw_if_index, int enable_disable)
Enable/disable l2 input classification on a specific interface.
static void vl_api_set_arp_neighbor_limit_t_handler(vl_api_set_arp_neighbor_limit_t *mp)
Definition: api.c:1058
u8 cmd[length]
Definition: vpe.api:300
u32 hw_if_index
Definition: pg.h:366
#define hash_set_mem(h, key, value)
Definition: hash.h:274
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
uword * sub_interface_sw_if_index_by_id
Definition: interface.h:471
vlib_main_t * vlib_main
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
unformat_function_t unformat_vnet_sw_interface
u8 * vlib_node_serialize(vlib_node_main_t *nm, u8 *vector, u32 max_threads, int include_nexts, int include_stats)
Enable / disable packet generator request.
Definition: vpe.api:801
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
static void vl_api_proxy_arp_add_del_t_handler(vl_api_proxy_arp_add_del_t *mp)
Definition: api.c:635
static uword vlib_node_add_next(vlib_main_t *vm, uword node, uword next_node)
Definition: node_funcs.h:1108
trace_cfg_t * api_trace_cfg
Current trace configuration.
Definition: api_common.h:229
static void vl_api_l2_patch_add_del_t_handler(vl_api_l2_patch_add_del_t *mp)
Definition: api.c:1302
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Process a vpe parser cli string request.
Definition: vpe.api:289
resolve_t
Definition: api.c:152
pub_sub_handler(oam_events, OAM_EVENTS)
u8 pcap_file_name[pcap_name_length]
Definition: vpe.api:792
PacketGenerator capture packets on given interface request.
Definition: vpe.api:784
void vl_set_memory_uid(int uid)
format_function_t format_ip4_address
Definition: format.h:79
static void vl_api_get_next_index_t_handler(vl_api_get_next_index_t *mp)
Definition: api.c:1222
Get node index using name request.
Definition: vpe.api:475
Proxy ARP add / del request.
Definition: vpe.api:117
#define VNET_SW_INTERFACE_FLAG_PROXY_ARP
Definition: interface.h:577
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:437
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:542
static void vl_api_get_node_graph_t_handler(vl_api_get_node_graph_t *mp)
Definition: api.c:1718
static void * svm_push_data_heap(svm_region_t *rp)
Definition: svm.h:86
#define MODE_L2_BRIDGE
Definition: l2_input.h:202
u32 context
Definition: vpe.api:292
vnet_feature_registration_t * vnet_get_feature_reg(const char *arc_name, const char *node_name)
Definition: feature.c:142
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
Definition: vec.h:306
static uword ip6_address_is_equal(ip6_address_t *a, ip6_address_t *b)
Definition: ip6_packet.h:208
Set interface source and L4 port-range request.
Definition: vpe.api:844
u32 index
Definition: ip4_fib.h:54
Reply for the vlan subinterface create request.
Definition: vpe.api:72
unsigned long long u32x4
Definition: ixge.c:28
#define clib_error_return_fatal(e, args...)
Definition: error.h:105
struct _vl_api_ip4_arp_event * arp_events
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
void fib_table_flush(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Flush all entries from a table for the source.
Definition: fib_table.c:1275
#define clib_error_return(e, args...)
Definition: error.h:99
svm_region_t * vlib_rp
Binary api segment descriptor.
Definition: api_common.h:235
get_node_graph_reply
Definition: vpe.api:689
unsigned long u64
Definition: types.h:89
Set/unset input ACL interface.
Definition: vpe.api:664
int vnet_l2_output_classify_set_tables(u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 other_table_index)
Set l2 per-protocol, per-interface output classification tables.
static void vl_api_want_ip6_nd_events_t_handler(vl_api_want_ip6_nd_events_t *mp)
Definition: api.c:1613
#define vec_resize(V, N)
Resize a vector (no header, unspecified alignment) Add N elements to end of given vector V...
Definition: vec.h:237
static clib_error_t * vpe_api_init(vlib_main_t *vm)
Definition: api.c:2232
static void vl_api_punt_socket_deregister_t_handler(vl_api_punt_socket_deregister_t *mp)
Definition: api.c:2084
static int ip6_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: api.c:818
int vnet_set_ip4_classify_intfc(vlib_main_t *vm, u32 sw_if_index, u32 table_index)
Definition: ip4_forward.c:3069
uword * bd_index_by_bd_id
Definition: l2_bd.h:27
#define IP6_ND_EVENT
Definition: api.c:194
void * vl_msg_api_alloc(int nbytes)
u8 * pcap_file_name
Definition: pg.h:369
stats_main_t stats_main
Definition: stats.c:23
u32 set_int_l2_mode(vlib_main_t *vm, vnet_main_t *vnet_main, u32 mode, u32 sw_if_index, u32 bd_index, u32 bvi, u32 shg, u32 xc_sw_if_index)
Set the subinterface to run in l2 or l3 mode.
Definition: l2_input.c:565
void unformat_init_string(unformat_input_t *input, char *string, int string_len)
Definition: unformat.c:1023
Configure IP source and L4 port-range check.
Definition: vpe.api:823
uword * hw_interface_by_name
Definition: interface.h:648
u64 cmd_in_shmem
Definition: vpe.api:293
vnet_api_error_t api_errno
Definition: vnet.h:76
void dsunlock(stats_main_t *sm)
Definition: stats.c:226
static uword resolver_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: api.c:299
#define hash_get(h, key)
Definition: hash.h:248
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:458
static void vl_api_pg_enable_disable_t_handler(vl_api_pg_enable_disable_t *mp)
Definition: api.c:1853
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
Definition: ip4.h:121
static void shmem_cli_output(uword arg, u8 *buffer, uword buffer_bytes)
Definition: api.c:955
static void vl_api_pg_create_interface_t_handler(vl_api_pg_create_interface_t *mp)
Definition: api.c:1791
static void vl_api_get_node_index_t_handler(vl_api_get_node_index_t *mp)
Definition: api.c:1198
char * vpe_api_get_version(void)
Definition: version.c:75
static void vl_api_bd_ip_mac_add_del_t_handler(vl_api_bd_ip_mac_add_del_t *mp)
Definition: api.c:440
struct _unformat_input_t unformat_input_t
static void vl_api_sw_interface_set_l2_bridge_t_handler(vl_api_sw_interface_set_l2_bridge_t *mp)
Definition: api.c:406
Set/unset l2 classification tables for an interface request.
Definition: vpe.api:446
void send_oam_event(oam_target_t *t)
Definition: api.c:711
static u8 * format_nd_event(u8 *s, va_list *args)
Definition: api.c:2387
Set bridge domain ip to mac entry request.
Definition: vpe.api:411
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:270
u8 stream_name[stream_name_length]
Definition: vpe.api:807
u32 pcap_name_length
Definition: vpe.api:791
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:662
static void vl_api_pg_capture_t_handler(vl_api_pg_capture_t *mp)
Definition: api.c:1809
#define REPLY_MACRO(t)
#define BAD_TX_SW_IF_INDEX_LABEL
vnet_main_t vnet_main
Definition: misc.c:43
Create loopback interface instance response.
Definition: vpe.api:241
u32 index
Definition: ip6.h:73
u32 pg_interface_add_or_get(pg_main_t *pg, uword stream_index)
Definition: stream.c:182
u8 l4_protocol
Definition: vpe.api:880
Tell client about an ip4 arp resolution event.
Definition: vpe.api:609
void vl_set_global_memory_baseva(u64 baseva)
static void vl_api_classify_set_interface_ip_table_t_handler(vl_api_classify_set_interface_ip_table_t *mp)
Definition: api.c:1086
Enable or Disable MPLS on and interface.
Definition: vpe.api:85
IOAM enable : Enable in-band OAM.
Definition: vpe.api:703
static void vl_api_punt_socket_register_t_handler(vl_api_punt_socket_register_t *mp)
Definition: api.c:2051
u32 client_index
Definition: vpe.api:291
#define REPLY_MACRO3(t, n, body)
struct _vl_api_ip6_nd_event * nd_events
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:182
IP Set the next node for a given node response.
Definition: vpe.api:501
Get node index using name request.
Definition: vpe.api:463
void unformat_init_vector(unformat_input_t *input, u8 *vector_string)
Definition: unformat.c:1031
int vnet_create_loopback_interface(u32 *sw_if_indexp, u8 *mac_address, u8 is_specified, u32 user_instance)
Definition: interface.c:558
static void vl_api_add_node_next_t_handler(vl_api_add_node_next_t *mp)
Definition: api.c:1269
void wc_nd_set_publisher_node(uword node_index, uword event_type)
Definition: ip6_neighbor.c:259
The IPv4 FIB.
Definition: ip4_fib.h:39
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:482
#define BAD_SW_IF_INDEX_LABEL
#define VLIB_EARLY_CONFIG_FUNCTION(x, n,...)
Definition: init.h:140
PacketGenerator create interface request.
Definition: vpe.api:758
api_main_t api_main
Definition: api_shared.c:35
static int nd_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, ip6_address_t *address)
Definition: api.c:1365
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
clib_error_t * vnet_punt_socket_add(vlib_main_t *vm, u32 header_version, bool is_ip4, u8 protocol, u16 port, char *client_pathname)
Definition: punt.c:567
mpls_main_t mpls_main
Definition: mpls.c:25
format_function_t format_ip6_address
Definition: format.h:95
static void vl_api_proxy_arp_intfc_enable_disable_t_handler(vl_api_proxy_arp_intfc_enable_disable_t *mp)
Definition: api.c:670
vlib_main_t * vm
Definition: buffer.c:283
int vnet_delete_sub_interface(u32 sw_if_index)
Definition: interface.c:737
static vlib_node_registration_t vpe_resolver_process_node
(constructor) VLIB_REGISTER_NODE (vpe_resolver_process_node)
Definition: api.c:158
u32 bd_add_del_ip_mac(u32 bd_index, u8 *ip_addr, u8 *mac_addr, u8 is_ip6, u8 is_add)
Add/delete IP address to MAC address mapping.
Definition: l2_bd.c:723
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:336
int vnet_delete_loopback_interface(u32 sw_if_index)
Definition: interface.c:710
Definition: ip6.h:67
static void vl_api_ioam_disable_t_handler(vl_api_ioam_disable_t *mp)
Definition: api.c:1774
Set/unset the classification table for an interface request.
Definition: vpe.api:429
#define clib_warning(format, args...)
Definition: error.h:59
char * vpe_api_get_build_directory(void)
Definition: version.c:69
void vl_set_global_pvt_heap_size(u64 size)
#define clib_memcpy(a, b, c)
Definition: string.h:69
unix_shared_memory_queue_t * vl_api_client_index_to_input_queue(u32 index)
int mpls_sw_interface_enable_disable(mpls_main_t *mm, u32 sw_if_index, u8 is_enable, u8 is_api)
Definition: interface.c:39
void vl_set_memory_region_name(const char *name)
Definition: memory_vlib.c:1330
ip6_address_t ip6
Definition: ip6_neighbor.h:95
Feature path enable/disable request.
Definition: vpe.api:923
static void inband_cli_output(uword arg, u8 *buffer, uword buffer_bytes)
Definition: api.c:1018
clib_error_t * ip6_ioam_enable(int has_trace_option, int has_pot_option, int has_seqno_option, int has_analyse_option)
static void vl_api_show_version_t_handler(vl_api_show_version_t *mp)
Definition: api.c:1169
void wc_arp_set_publisher_node(uword node_index, uword event_type)
Definition: arp.c:1554
Definitions for punt infrastructure.
int vnet_l2_input_classify_set_tables(u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 other_table_index)
Set l2 per-protocol, per-interface input classification tables.
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:267
Delete sub interface request.
Definition: vpe.api:861
#define ARRAY_LEN(x)
Definition: clib.h:59
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
int ip4_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
#define VALIDATE_RX_SW_IF_INDEX(mp)
char * vnet_punt_get_server_pathname(void)
Definition: punt.c:70
int vnet_proxy_arp_add_del(ip4_address_t *lo_addr, ip4_address_t *hi_addr, u32 fib_index, int is_del)
Definition: arp.c:1944
Delete loopback interface request.
Definition: vpe.api:253
static void vl_api_sw_interface_set_vpath_t_handler(vl_api_sw_interface_set_vpath_t *mp)
Definition: api.c:351
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
Set L2 XConnect between two interfaces request.
Definition: vpe.api:373
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:572
void vl_msg_api_send_shmem(unix_shared_memory_queue_t *q, u8 *elem)
static u32 bd_find_or_add_bd_index(bd_main_t *bdm, u32 bd_id)
Get or create a bridge domain.
Definition: l2_bd.h:171
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:293
#define ASSERT(truth)
static void vl_api_ip_source_and_port_range_check_interface_add_del_t_handler(vl_api_ip_source_and_port_range_check_interface_add_del_t *mp)
Definition: api.c:1967
static uword ip6_address_is_zero(ip6_address_t *a)
Definition: ip6_packet.h:266
static clib_error_t * show_ip_arp_nd_events_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: api.c:2397
unsigned int u32
Definition: types.h:88
static void vl_api_classify_set_interface_l2_tables_t_handler(vl_api_classify_set_interface_l2_tables_t *mp)
Definition: api.c:1108
int ip6_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
static void vl_api_cli_inband_t_handler(vl_api_cli_inband_t *mp)
Definition: api.c:1030
ip6_main_t ip6_main
Definition: ip6_forward.c:3043
#define RESOLUTION_EVENT
Definition: api.c:191
static void setup_message_id_table(api_main_t *am)
Definition: api.c:2453
int vpe_oam_add_del_target(ip4_address_t *src_address, ip4_address_t *dst_address, u32 fib_id, int is_add)
Definition: oam.c:60
void pg_enable_disable(u32 stream_index, int is_enable)
Definition: cli.c:58
clib_error_t * vnet_punt_socket_del(vlib_main_t *vm, bool is_ip4, u8 l4_protocol, u16 port)
Definition: punt.c:600
IPv4 main type.
Definition: ip4.h:95
int stats_memclnt_delete_callback(u32 client_index)
Definition: stats.c:2309
u64 size
Definition: vhost-user.h:76
u16 l4_port
Definition: vpe.api:881
Control ping from the client to the server response.
Definition: vpe.api:276
static void vl_api_create_vlan_subif_t_handler(vl_api_create_vlan_subif_t *mp)
Definition: api.c:472
Bitmaps built as vectors of machine words.
Set the next node for a given node request.
Definition: vpe.api:488
uword * next_slot_by_node
Definition: node.h:302
void handle_ip6_nd_event(u32 pool_index)
Definition: api.c:250
#define clib_error_report(e)
Definition: error.h:113
Query relative index via node names.
Definition: vpe.api:733
show version
Definition: vpe.api:553
#define BAD_BD_ID_LABEL
From the control plane API.
Definition: fib_entry.h:62
void l2_efp_filter_configure(vnet_main_t *vnet_main, u32 sw_if_index, u32 enable)
Enable/disable the EFP Filter check on the subinterface.
#define VALIDATE_BD_ID(mp)
Punt traffic to the host via socket.
Definition: vpe.api:892
OAM add / del target request.
Definition: vpe.api:172
static void * clib_mem_alloc(uword size)
Definition: mem.h:112
VL_MSG_API_REAPER_FUNCTION(memclnt_delete_callback)
#define MODE_L2_XC
Definition: l2_input.h:203
void vl_set_api_pvt_heap_size(u64 size)
static void vl_api_delete_subif_t_handler(vl_api_delete_subif_t *mp)
Definition: api.c:2021
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: api.c:1754
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
u64 uword
Definition: types.h:112
static void vl_api_l2_interface_efp_filter_t_handler(vl_api_l2_interface_efp_filter_t *mp)
Definition: api.c:1154
u32 l2input_intf_bitmap_enable(u32 sw_if_index, u32 feature_bitmap, u32 enable)
Enable (or disable) the feature in the bitmap for the given interface.
Definition: l2_input.c:534
void dslock(stats_main_t *sm, int release_hint, int tag)
Definition: stats.c:193
template key/value backing page structure
Definition: bihash_doc.h:44
Add / del route request.
Definition: ip.api:381
static void vl_api_create_loopback_instance_t_handler(vl_api_create_loopback_instance_t *mp)
Definition: api.c:908
Interface bridge mode request.
Definition: vpe.api:391
unsigned short u16
Definition: types.h:57
Create loopback interface instance request.
Definition: vpe.api:227
u64 reply_in_shmem
Definition: vpe.api:312
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:489
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
static uword wc_arp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: api.c:1417
static void vl_api_sw_interface_set_l2_xconnect_t_handler(vl_api_sw_interface_set_l2_xconnect_t *mp)
Definition: api.c:376
vlib_node_main_t node_main
Definition: main.h:129
void * get_unformat_vnet_sw_interface(void)
Definition: api.c:2371
static void vl_api_create_subif_t_handler(vl_api_create_subif_t *mp)
Definition: api.c:552
L2 interface ethernet flow point filtering enable/disable request.
Definition: vpe.api:514
static u8 * format_arp_event(u8 *s, va_list *args)
Definition: api.c:2377
int vnet_l2_patch_add_del(u32 rx_sw_if_index, u32 tx_sw_if_index, int is_add)
Definition: l2_patch.c:247
PacketGenerator create interface response.
Definition: vpe.api:769
void vnet_l2_output_classify_enable_disable(u32 sw_if_index, int enable_disable)
Enable/disable l2 input classification on a specific interface.
Create loopback interface request.
Definition: vpe.api:201
#define clib_error_get_code(err)
Definition: error.h:77
show version response
Definition: vpe.api:566
int ip4_source_and_port_range_check_add_del(ip4_address_t *address, u32 length, u32 vrf_id, u16 *low_ports, u16 *high_ports, int is_add)
static void vl_api_delete_loopback_t_handler(vl_api_delete_loopback_t *mp)
Definition: api.c:928
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
Create a new subinterface with the given vlan id.
Definition: vpe.api:59
Create loopback interface response.
Definition: vpe.api:213
u32 dev_instance
Definition: pg.h:367
L2 interface patch add / del request.
Definition: vpe.api:343
#define hash_get_mem(h, key)
Definition: hash.h:268
static void vl_api_control_ping_t_handler(vl_api_control_ping_t *mp)
Definition: api.c:941
Tell client about an ip6 nd resolution or mac/ip event.
Definition: vpe.api:643
struct clib_bihash_value offset
template key/value backing page structure
clib_error_t * vnet_punt_add_del(vlib_main_t *vm, u8 ipv, u8 protocol, u16 port, bool is_add)
Request IP traffic punt to the local TCP/IP stack.
Definition: punt.c:630
Interface set vpath request.
Definition: vpe.api:358
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
char * vpe_api_get_build_date(void)
Definition: version.c:81
u8 * is_mp_safe
Message is mp safe vector.
Definition: api_common.h:205
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1175
static void vlib_process_put_event_data(vlib_main_t *vm, void *event_data)
Definition: node_funcs.h:526
static u32 eth_mac_equal(u8 *mac1, u8 *mac2)
Definition: ethernet.h:519
static void vl_api_input_acl_set_interface_t_handler(vl_api_input_acl_set_interface_t *mp)
Definition: api.c:1696
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
static int ip4_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: api.c:750
Register for ip4 arp resolution events.
Definition: vpe.api:592
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:100
pg_main_t pg_main
Definition: init.c:44
u8 is_enabled
Definition: pg.h:368
clib_error_t * clear_ioam_rewrite_fn(void)
int vnet_set_input_acl_intfc(vlib_main_t *vm, u32 sw_if_index, u32 ip4_table_index, u32 ip6_table_index, u32 l2_table_index, u32 is_add)
Definition: input_acl.c:59
static int nd_change_delete_callback(u32 pool_index, u8 *notused)
Definition: api.c:1400
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:546
#define IP4_ARP_EVENT
Definition: api.c:193
void vl_set_global_memory_size(u64 size)
static void vl_api_oam_add_del_t_handler(vl_api_oam_add_del_t *mp)
Definition: api.c:736
static void vl_api_ip_source_and_port_range_check_add_del_t_handler(vl_api_ip_source_and_port_range_check_add_del_t *mp)
Definition: api.c:1881
void vl_set_memory_root_path(const char *root_path)
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:598
static int arp_change_delete_callback(u32 pool_index, u8 *notused)
Definition: api.c:1388
u32 flags
Definition: vhost-user.h:77
bd_main_t bd_main
Definition: l2_bd.c:44
int ip6_source_and_port_range_check_add_del(ip6_address_t *address, u32 length, u32 vrf_id, u16 *low_ports, u16 *high_ports, int is_add)
static uword vnet_sw_interface_get_flags(vnet_main_t *vnm, u32 sw_if_index)
#define RESOLUTION_PENDING_EVENT
Definition: api.c:192
static clib_error_t * vpe_api_hookup(vlib_main_t *vm)
Definition: api.c:2194
struct fib_table_t_ * fibs
Definition: ip6.h:161
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
int vnet_add_del_ip4_arp_change_event(vnet_main_t *vnm, void *data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
Definition: arp.c:717
Punt traffic to the host.
Definition: vpe.api:875
pg_interface_t * interfaces
Definition: pg.h:322
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
#define foreach_registration_hash
pthread_mutex_t mutex
Definition: svm_common.h:37
int vnet_feature_enable_disable(const char *arc_name, const char *node_name, u32 sw_if_index, int enable_disable, void *feature_config, u32 n_feature_config_bytes)
Definition: feature.c:229
CLIB vectors are ubiquitous dynamically resized arrays with by user defined "headers".
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:35
struct _vnet_feature_registration vnet_feature_registration_t
feature registration object
#define MODE_L3
Definition: l2_input.h:201
struct _unix_shared_memory_queue unix_shared_memory_queue_t
Segment Routing data structures definitions.
clib_error_t * ip6_set_neighbor_limit(u32 neighbor_limit)
int set_ip_source_and_port_range_check(vlib_main_t *vm, u32 *fib_index, u32 sw_if_index, u32 is_add)
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128