FD.io VPP  v19.08.1-401-g8e4ed521a
Vector Packet Processing
ip_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * ip_api.c - vnet ip api
4  *
5  * Copyright (c) 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 <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/ethernet/ethernet.h>
27 #include <vnet/ip/ip.h>
28 #include <vnet/ip/ip_neighbor.h>
29 #include <vnet/ip/ip_types_api.h>
30 #include <vnet/ip/ip6_neighbor.h>
31 #include <vnet/ip/ip_punt_drop.h>
32 #include <vnet/ip/ip_types_api.h>
33 #include <vnet/fib/fib_table.h>
34 #include <vnet/fib/fib_api.h>
36 #include <vnet/mfib/ip6_mfib.h>
37 #include <vnet/mfib/ip4_mfib.h>
38 #include <vnet/mfib/mfib_signal.h>
39 #include <vnet/mfib/mfib_entry.h>
40 #include <vnet/mfib/mfib_api.h>
42 #include <vnet/fib/ip4_fib.h>
43 #include <vnet/fib/ip6_fib.h>
44 #include <vnet/fib/fib_path_list.h>
45 #include <vnet/ip/ip6_hop_by_hop.h>
48 #include <vnet/ethernet/arp.h>
49 #include <vnet/ip/ip_types_api.h>
50 
51 #include <vnet/vnet_msg_enum.h>
52 
53 #define vl_typedefs /* define message structures */
54 #include <vnet/vnet_all_api_h.h>
55 #undef vl_typedefs
56 
57 #define vl_endianfun /* define message structures */
58 #include <vnet/vnet_all_api_h.h>
59 #undef vl_endianfun
60 
61 /* instantiate all the print functions we know about */
62 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
63 #define vl_printfun
64 #include <vnet/vnet_all_api_h.h>
65 #undef vl_printfun
66 
68 
69 
70 #define foreach_ip_api_msg \
71 _(IP_TABLE_DUMP, ip_table_dump) \
72 _(IP_ROUTE_DUMP, ip_route_dump) \
73 _(IP_MTABLE_DUMP, ip_mtable_dump) \
74 _(IP_MROUTE_DUMP, ip_mroute_dump) \
75 _(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
76 _(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
77 _(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
78 _(IP_ADDRESS_DUMP, ip_address_dump) \
79 _(IP_UNNUMBERED_DUMP, ip_unnumbered_dump) \
80 _(IP_DUMP, ip_dump) \
81 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
82 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
83 _(IP_PROBE_NEIGHBOR, ip_probe_neighbor) \
84 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE, ip_scan_neighbor_enable_disable) \
85 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
86 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
87 _(WANT_IP6_RA_EVENTS, want_ip6_ra_events) \
88 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
89 _(PROXY_ARP_DUMP, proxy_arp_dump) \
90 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
91  _(PROXY_ARP_INTFC_DUMP, proxy_arp_intfc_dump) \
92 _(RESET_FIB, reset_fib) \
93 _(IP_ROUTE_ADD_DEL, ip_route_add_del) \
94 _(IP_TABLE_ADD_DEL, ip_table_add_del) \
95 _(IP_PUNT_POLICE, ip_punt_police) \
96 _(IP_PUNT_REDIRECT, ip_punt_redirect) \
97 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
98 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
99 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
100 _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
101 _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
102 _(IP6ND_SEND_ROUTER_SOLICITATION, ip6nd_send_router_solicitation) \
103 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
104 _(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \
105 _(IP_CONTAINER_PROXY_DUMP, ip_container_proxy_dump) \
106 _(IOAM_ENABLE, ioam_enable) \
107 _(IOAM_DISABLE, ioam_disable) \
108 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
109  ip_source_and_port_range_check_add_del) \
110 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
111  ip_source_and_port_range_check_interface_add_del) \
112 _(IP_SOURCE_CHECK_INTERFACE_ADD_DEL, \
113  ip_source_check_interface_add_del) \
114 _(IP_REASSEMBLY_SET, ip_reassembly_set) \
115 _(IP_REASSEMBLY_GET, ip_reassembly_get) \
116 _(IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable) \
117 _(IP_PUNT_REDIRECT_DUMP, ip_punt_redirect_dump)
118 
119 
120 static vl_api_ip_neighbor_flags_t
122 {
123  vl_api_ip_neighbor_flags_t v = IP_API_NEIGHBOR_FLAG_NONE;
124 
125  if (f & IP_NEIGHBOR_FLAG_STATIC)
129 
130  return (clib_host_to_net_u32 (v));
131 }
132 
133 static void
135  const ip46_address_t * ip_address,
136  const mac_address_t * mac,
139 {
141 
142  mp = vl_msg_api_alloc (sizeof (*mp));
143  clib_memset (mp, 0, sizeof (*mp));
144  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
145  mp->context = context;
146  mp->neighbor.sw_if_index = htonl (sw_if_index);
147  mp->neighbor.flags = ip_neighbor_flags_encode (flags);
148 
149  ip_address_encode (ip_address, IP46_TYPE_ANY, &mp->neighbor.ip_address);
150  mac_address_encode (mac, mp->neighbor.mac_address);
151 
152  vl_api_send_msg (reg, (u8 *) mp);
153 }
154 
155 static void
157 {
159 
161  if (!reg)
162  return;
163 
164  u32 sw_if_index = ntohl (mp->sw_if_index);
165 
166  if (mp->is_ipv6)
167  {
168  ip6_neighbor_t *n, *ns;
169 
170  ns = ip6_neighbors_entries (sw_if_index);
171  /* *INDENT-OFF* */
172  vec_foreach (n, ns)
173  {
174  ip46_address_t nh = {
175  .ip6 = {
176  .as_u64[0] = n->key.ip6_address.as_u64[0],
177  .as_u64[1] = n->key.ip6_address.as_u64[1],
178  },
179  };
181  &n->mac, n->flags,
182  reg, mp->context);
183  }
184  /* *INDENT-ON* */
185  vec_free (ns);
186  }
187  else
188  {
189  ethernet_arp_ip4_entry_t *n, *ns;
190 
191  ns = ip4_neighbor_entries (sw_if_index);
192  /* *INDENT-OFF* */
193  vec_foreach (n, ns)
194  {
195  ip46_address_t nh = {
196  .ip4 = {
197  .as_u32 = n->ip4_address.as_u32,
198  },
199  };
200 
202  &n->mac, n->flags,
203  reg, mp->context);
204  }
205  /* *INDENT-ON* */
206  vec_free (ns);
207  }
208 }
209 
210 static void
212  vl_api_registration_t * reg,
213  u32 context, const fib_table_t * table)
214 {
216 
217  mp = vl_msg_api_alloc (sizeof (*mp));
218  if (!mp)
219  return;
220  clib_memset (mp, 0, sizeof (*mp));
221  mp->_vl_msg_id = ntohs (VL_API_IP_TABLE_DETAILS);
222  mp->context = context;
223 
224  mp->table.is_ip6 = (table->ft_proto == FIB_PROTOCOL_IP6);
225  mp->table.table_id = htonl (table->ft_table_id);
226  memcpy (mp->table.name, table->ft_desc,
227  clib_min (vec_len (table->ft_desc), sizeof (mp->table.name)));
228 
229  vl_api_send_msg (reg, (u8 *) mp);
230 }
231 
232 static void
234 {
237  fib_table_t *fib_table;
238 
240  if (!reg)
241  return;
242 
243  /* *INDENT-OFF* */
244  pool_foreach (fib_table, ip4_main.fibs,
245  ({
246  send_ip_table_details(am, reg, mp->context, fib_table);
247  }));
248  pool_foreach (fib_table, ip6_main.fibs,
249  ({
250  /* don't send link locals */
251  if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
252  continue;
253  send_ip_table_details(am, reg, mp->context, fib_table);
254  }));
255  /* *INDENT-ON* */
256 }
257 
259 {
262 
263 static fib_table_walk_rc_t
265 {
267 
268  vec_add1 (ctx->feis, fei);
269 
270  return (FIB_TABLE_WALK_CONTINUE);
271 }
272 
273 static void
275  vl_api_registration_t * reg,
276  u32 context, fib_node_index_t fib_entry_index)
277 {
278  fib_route_path_t *rpaths, *rpath;
280  const fib_prefix_t *pfx;
281  vl_api_fib_path_t *fp;
282  int path_count;
283 
284  rpaths = NULL;
285  pfx = fib_entry_get_prefix (fib_entry_index);
286  rpaths = fib_entry_encode (fib_entry_index);
287 
288  path_count = vec_len (rpaths);
289  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
290  if (!mp)
291  return;
292  clib_memset (mp, 0, sizeof (*mp));
293  mp->_vl_msg_id = ntohs (VL_API_IP_ROUTE_DETAILS);
294  mp->context = context;
295 
296  ip_prefix_encode (pfx, &mp->route.prefix);
297  mp->route.table_id =
299  (fib_entry_get_fib_index (fib_entry_index), pfx->fp_proto));
300  mp->route.n_paths = path_count;
301  mp->route.stats_index =
303  (fib_entry_get_fib_index (fib_entry_index), pfx));
304 
305  fp = mp->route.paths;
306  vec_foreach (rpath, rpaths)
307  {
308  fib_api_path_encode (rpath, fp);
309  fp++;
310  }
311 
312  vl_api_send_msg (reg, (u8 *) mp);
313 }
314 
316 {
319 
320 static void
322 {
324  fib_node_index_t *fib_entry_index;
326  fib_protocol_t fproto;
327  u32 fib_index;
328 
330  if (!reg)
331  return;
332 
334  .feis = NULL,
335  };
336 
337  fproto = (mp->table.is_ip6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
338  fib_index = fib_table_find (fproto, ntohl (mp->table.table_id));
339 
340  if (INDEX_INVALID == fib_index)
341  return;
342 
343  fib_table_walk (fib_index, fproto, vl_api_ip_fib_dump_walk, &ctx);
344 
345  vec_foreach (fib_entry_index, ctx.feis)
346  {
347  send_ip_route_details (am, reg, mp->context, *fib_entry_index);
348  }
349 
350  vec_free (ctx.feis);
351 }
352 
353 static void
355  u32 context, const mfib_table_t * mfib_table)
356 {
358 
359  mp = vl_msg_api_alloc (sizeof (*mp));
360  if (!mp)
361  return;
362  memset (mp, 0, sizeof (*mp));
363  mp->_vl_msg_id = ntohs (VL_API_IP_MTABLE_DETAILS);
364  mp->context = context;
365 
366  mp->table.table_id = htonl (mfib_table->mft_table_id);
367  mp->table.is_ip6 = (FIB_PROTOCOL_IP6 == mfib_table->mft_proto);
368 
369  vl_api_send_msg (reg, (u8 *) mp);
370 }
371 
372 static void
374 {
376  mfib_table_t *mfib_table;
377 
379  if (!reg)
380  return;
381 
382  /* *INDENT-OFF* */
383  pool_foreach (mfib_table, ip4_main.mfibs,
384  ({
385  send_ip_mtable_details (reg, mp->context, mfib_table);
386  }));
387  pool_foreach (mfib_table, ip6_main.mfibs,
388  ({
389  send_ip_mtable_details (reg, mp->context, mfib_table);
390  }));
391  /* *INDENT-ON* */
392 }
393 
395 {
398 
399 static int
401 {
403 
404  vec_add1 (ctx->entries, fei);
405 
406  return (0);
407 }
408 
409 static void
411  vl_api_registration_t * reg,
412  u32 context, fib_node_index_t mfib_entry_index)
413 {
414  fib_route_path_t *rpaths, *rpath;
416  const mfib_prefix_t *pfx;
417  vl_api_mfib_path_t *fp;
418  int path_count;
419 
420  rpaths = NULL;
421  pfx = mfib_entry_get_prefix (mfib_entry_index);
422  rpaths = mfib_entry_encode (mfib_entry_index);
423 
424  path_count = vec_len (rpaths);
425  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
426  if (!mp)
427  return;
428  clib_memset (mp, 0, sizeof (*mp));
429  mp->_vl_msg_id = ntohs (VL_API_IP_MROUTE_DETAILS);
430  mp->context = context;
431 
432  ip_mprefix_encode (pfx, &mp->route.prefix);
433  mp->route.table_id =
435  (mfib_entry_get_fib_index (mfib_entry_index), pfx->fp_proto));
436  mp->route.n_paths = htonl (path_count);
437  fp = mp->route.paths;
438  vec_foreach (rpath, rpaths)
439  {
440  mfib_api_path_encode (rpath, fp);
441  fp++;
442  }
443 
444  vl_api_send_msg (reg, (u8 *) mp);
445  vec_free (rpaths);
446 }
447 
448 static void
450 {
453  fib_node_index_t *mfeip;
454  fib_protocol_t fproto;
455  u32 fib_index;
456 
458  .entries = NULL,
459  };
460 
462  if (!reg)
463  return;
464 
465  fproto = fib_ip_proto (mp->table.is_ip6);
466  fib_index = mfib_table_find (fproto, ntohl (mp->table.table_id));
467 
468  if (INDEX_INVALID == fib_index)
469  return;
470 
471  mfib_table_walk (fib_index, fproto, mfib_route_dump_walk, &ctx);
472 
474 
475  vec_foreach (mfeip, ctx.entries)
476  {
477  send_ip_mroute_details (am, reg, mp->context, *mfeip);
478  }
479 
480  vec_free (ctx.entries);
481 }
482 
483 static void
485  vlib_main_t * vm)
486 {
487  vl_api_ip_punt_police_reply_t *rmp;
488  int rv = 0;
489 
490  if (mp->is_ip6)
491  ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
492  else
493  ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
494 
495  REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
496 }
497 
498 static void
500  vlib_main_t * vm)
501 {
502  vl_api_ip_punt_redirect_reply_t *rmp;
503  int rv = 0;
504  ip46_type_t ipv;
505  ip46_address_t nh;
506 
508  goto bad_sw_if_index;
509 
510  ipv = ip_address_decode (&mp->punt.nh, &nh);
511  if (mp->is_add)
512  {
513  if (ipv == IP46_TYPE_IP6)
514  {
516  ntohl (mp->punt.tx_sw_if_index), &nh);
517  }
518  else if (ipv == IP46_TYPE_IP4)
519  {
521  ntohl (mp->punt.tx_sw_if_index), &nh);
522  }
523  }
524  else
525  {
526  if (ipv == IP46_TYPE_IP6)
527  {
529  }
530  else if (ipv == IP46_TYPE_IP4)
531  {
533  }
534  }
535 
537 
538  REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
539 }
540 
541 static ip_neighbor_flags_t
542 ip_neighbor_flags_decode (vl_api_ip_neighbor_flags_t v)
543 {
545 
546  v = clib_net_to_host_u32 (v);
547 
552 
553  return (f);
554 }
555 
556 static void
558  vlib_main_t * vm)
559 {
562  u32 stats_index = ~0;
563  ip46_address_t ip;
566  int rv;
567 
569 
570  flags = ip_neighbor_flags_decode (mp->neighbor.flags);
571  type = ip_address_decode (&mp->neighbor.ip_address, &ip);
572  mac_address_decode (mp->neighbor.mac_address, &mac);
573 
574  /*
575  * there's no validation here of the ND/ARP entry being added.
576  * The expectation is that the FIB will ensure that nothing bad
577  * will come of adding bogus entries.
578  */
579  if (mp->is_add)
580  rv = ip_neighbor_add (&ip, type, &mac,
581  ntohl (mp->neighbor.sw_if_index),
582  flags, &stats_index);
583  else
584  rv = ip_neighbor_del (&ip, type, ntohl (mp->neighbor.sw_if_index));
585 
587 
588  /* *INDENT-OFF* */
589  REPLY_MACRO2 (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY,
590  ({
591  rmp->stats_index = htonl (stats_index);
592  }));
593  /* *INDENT-ON* */
594 }
595 
596 void
598 {
599  u32 fib_index, mfib_index;
600 
601  /*
602  * ignore action on the default table - this is always present
603  * and cannot be added nor deleted from the API
604  */
605  if (0 != table_id)
606  {
607  /*
608  * The API holds only one lock on the table.
609  * i.e. it can be added many times via the API but needs to be
610  * deleted only once.
611  * The FIB index for unicast and multicast is not necessarily the
612  * same, since internal VPP systesm (like LISP and SR) create
613  * their own unicast tables.
614  */
615  fib_index = fib_table_find (fproto, table_id);
616  mfib_index = mfib_table_find (fproto, table_id);
617 
618  if (~0 != fib_index)
619  {
620  fib_table_unlock (fib_index, fproto,
621  (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
622  }
623  if (~0 != mfib_index)
624  {
625  mfib_table_unlock (mfib_index, fproto,
626  (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
627  }
628  }
629 }
630 
631 void
633 {
634  vl_api_ip_table_add_del_reply_t *rmp;
635  fib_protocol_t fproto = (mp->table.is_ip6 ?
637  u32 table_id = ntohl (mp->table.table_id);
638  int rv = 0;
639 
640  if (mp->is_add)
641  {
642  ip_table_create (fproto, table_id, 1, mp->table.name);
643  }
644  else
645  {
646  ip_table_delete (fproto, table_id, 1);
647  }
648 
649  REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
650 }
651 
652 static int
654 {
655  fib_route_path_t *rpaths = NULL, *rpath;
657  vl_api_fib_path_t *apath;
658  fib_prefix_t pfx;
659  u32 fib_index;
660  int rv, ii;
661 
662  entry_flags = FIB_ENTRY_FLAG_NONE;
663  ip_prefix_decode (&mp->route.prefix, &pfx);
664 
666  ntohl (mp->route.table_id), &fib_index);
667  if (0 != rv)
668  goto out;
669 
670  if (0 != mp->route.n_paths)
671  vec_validate (rpaths, mp->route.n_paths - 1);
672 
673  for (ii = 0; ii < mp->route.n_paths; ii++)
674  {
675  apath = &mp->route.paths[ii];
676  rpath = &rpaths[ii];
677 
678  rv = fib_api_path_decode (apath, rpath);
679 
680  if ((rpath->frp_flags & FIB_ROUTE_PATH_LOCAL) &&
681  (~0 == rpath->frp_sw_if_index))
683 
684  if (0 != rv)
685  goto out;
686  }
687 
688  rv = fib_api_route_add_del (mp->is_add,
689  mp->is_multipath,
690  fib_index, &pfx, entry_flags, rpaths);
691 
692  if (mp->is_add && 0 == rv)
693  *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
694 
695 out:
696  vec_free (rpaths);
697 
698  return (rv);
699 }
700 
701 void
703 {
705  u32 stats_index = ~0;
706  int rv;
707 
708  rv = ip_route_add_del_t_handler (mp, &stats_index);
709 
710  /* *INDENT-OFF* */
711  REPLY_MACRO2 (VL_API_IP_ROUTE_ADD_DEL_REPLY,
712  ({
713  rmp->stats_index = htonl (stats_index);
714  }))
715  /* *INDENT-ON* */
716 }
717 
718 void
720  u32 table_id, u8 is_api, const u8 * name)
721 {
722  u32 fib_index, mfib_index;
723 
724  /*
725  * ignore action on the default table - this is always present
726  * and cannot be added nor deleted from the API
727  */
728  if (0 != table_id)
729  {
730  /*
731  * The API holds only one lock on the table.
732  * i.e. it can be added many times via the API but needs to be
733  * deleted only once.
734  * The FIB index for unicast and multicast is not necessarily the
735  * same, since internal VPP systesm (like LISP and SR) create
736  * their own unicast tables.
737  */
738  fib_index = fib_table_find (fproto, table_id);
739  mfib_index = mfib_table_find (fproto, table_id);
740 
741  if (~0 == fib_index)
742  {
744  (is_api ?
746  FIB_SOURCE_CLI), name);
747  }
748  if (~0 == mfib_index)
749  {
751  (is_api ?
753  MFIB_SOURCE_CLI), name);
754  }
755  }
756 }
757 
758 static u32
760  u8 is_multipath,
761  u32 fib_index,
762  const mfib_prefix_t * prefix,
764  u32 rpf_id, fib_route_path_t * rpaths)
765 {
766  u32 mfib_entry_index = ~0;
767 
768  if (0 == vec_len (rpaths))
769  {
770  mfib_entry_index = mfib_table_entry_update (fib_index, prefix,
772  rpf_id, entry_flags);
773  }
774  else
775  {
776  if (is_add)
777  {
778  mfib_entry_index =
779  mfib_table_entry_paths_update (fib_index, prefix,
780  MFIB_SOURCE_API, rpaths);
781  }
782  else
783  {
784  mfib_table_entry_paths_remove (fib_index, prefix,
785  MFIB_SOURCE_API, rpaths);
786  }
787  }
788 
789  return (mfib_entry_index);
790 }
791 
792 static int
794  u32 * stats_index)
795 {
796  fib_route_path_t *rpath, *rpaths = NULL;
797  fib_node_index_t mfib_entry_index;
798  mfib_prefix_t pfx;
799  u32 fib_index;
800  int rv;
801  u16 ii;
802 
803  ip_mprefix_decode (&mp->route.prefix, &pfx);
804 
806  ntohl (mp->route.table_id), &fib_index);
807  if (0 != rv)
808  goto out;
809 
810  vec_validate (rpaths, mp->route.n_paths - 1);
811 
812  for (ii = 0; ii < mp->route.n_paths; ii++)
813  {
814  rpath = &rpaths[ii];
815 
816  rv = mfib_api_path_decode (&mp->route.paths[ii], rpath);
817 
818  if (0 != rv)
819  goto out;
820  }
821 
822  mfib_entry_index = mroute_add_del_handler (mp->is_add,
823  mp->is_add,
824  fib_index, &pfx,
825  ntohl (mp->route.entry_flags),
826  ntohl (mp->route.rpf_id),
827  rpaths);
828 
829  if (~0 != mfib_entry_index)
830  *stats_index = mfib_entry_get_stats_index (mfib_entry_index);
831 
832 out:
833  return (rv);
834 }
835 
836 void
838 {
840  u32 stats_index = ~0;
841  int rv;
842 
843  rv = api_mroute_add_del_t_handler (mp, &stats_index);
844 
845  /* *INDENT-OFF* */
846  REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY,
847  ({
848  rmp->stats_index = htonl (stats_index);
849  }));
850  /* *INDENT-ON* */
851 }
852 
853 static void
855  vl_api_registration_t * reg, u32 sw_if_index, u8 is_ipv6,
856  u32 context)
857 {
859 
860  mp = vl_msg_api_alloc (sizeof (*mp));
861  clib_memset (mp, 0, sizeof (*mp));
862  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
863 
864  mp->sw_if_index = ntohl (sw_if_index);
865  mp->is_ipv6 = is_ipv6;
866  mp->context = context;
867 
868  vl_api_send_msg (reg, (u8 *) mp);
869 }
870 
871 static void
873  vl_api_registration_t * reg,
874  const fib_prefix_t * pfx,
876 {
878 
879  mp = vl_msg_api_alloc (sizeof (*mp));
880  clib_memset (mp, 0, sizeof (*mp));
881  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
882 
883  ip_prefix_encode (pfx, &mp->prefix);
884  mp->context = context;
885  mp->sw_if_index = htonl (sw_if_index);
886 
887  vl_api_send_msg (reg, (u8 *) mp);
888 }
889 
890 static void
892 {
895  ip6_main_t *im6 = &ip6_main;
896  ip4_main_t *im4 = &ip4_main;
897  ip_lookup_main_t *lm6 = &im6->lookup_main;
898  ip_lookup_main_t *lm4 = &im4->lookup_main;
899  ip_interface_address_t *ia = 0;
900  u32 sw_if_index = ~0;
901  int rv __attribute__ ((unused)) = 0;
902 
904 
905  sw_if_index = ntohl (mp->sw_if_index);
906 
908  if (!reg)
909  return;
910 
911  if (mp->is_ipv6)
912  {
913  /* *INDENT-OFF* */
914  /* Do not send subnet details of the IP-interface for
915  * unnumbered interfaces. otherwise listening clients
916  * will be confused that the subnet is applied on more
917  * than one interface */
918  foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
919  ({
920  fib_prefix_t pfx = {
922  .fp_len = ia->address_length,
923  .fp_proto = FIB_PROTOCOL_IP6,
924  };
925  send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
926  }));
927  /* *INDENT-ON* */
928  }
929  else
930  {
931  /* *INDENT-OFF* */
932  foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
933  ({
934  fib_prefix_t pfx = {
936  .fp_len = ia->address_length,
937  .fp_proto = FIB_PROTOCOL_IP4,
938  };
939 
940  send_ip_address_details(am, reg, &pfx, sw_if_index, mp->context);
941  }));
942  /* *INDENT-ON* */
943  }
944 
946 }
947 
948 static void
950  vl_api_registration_t * reg,
951  u32 sw_if_index, u32 ip_sw_if_index, u32 context)
952 {
954 
955  mp = vl_msg_api_alloc (sizeof (*mp));
956  clib_memset (mp, 0, sizeof (*mp));
957  mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS);
958 
959  mp->context = context;
960  mp->sw_if_index = htonl (sw_if_index);
961  mp->ip_sw_if_index = htonl (ip_sw_if_index);
962 
963  vl_api_send_msg (reg, (u8 *) mp);
964 }
965 
966 static void
968 {
969  vnet_main_t *vnm = vnet_get_main ();
971  int rv __attribute__ ((unused)) = 0;
976 
977  sw_if_index = ntohl (mp->sw_if_index);
978 
980  if (!reg)
981  return;
982 
983  if (~0 != sw_if_index)
984  {
986 
987  si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
988 
990  {
992  sw_if_index,
994  mp->context);
995  }
996  }
997  else
998  {
999  /* *INDENT-OFF* */
1000  pool_foreach (si, im->sw_interfaces,
1001  ({
1002  if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
1003  {
1004  send_ip_unnumbered_details(am, reg,
1005  si->sw_if_index,
1006  si->unnumbered_sw_if_index,
1007  mp->context);
1008  }
1009  }));
1010  /* *INDENT-ON* */
1011  }
1012 
1014 }
1015 
1016 static void
1018 {
1020  vnet_main_t *vnm = vnet_get_main ();
1023  vl_api_registration_t *reg;
1024  vnet_sw_interface_t *si, *sorted_sis;
1025  u32 sw_if_index = ~0;
1026 
1028  if (!reg)
1029  return;
1030 
1031  /* Gather interfaces. */
1032  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
1033  _vec_len (sorted_sis) = 0;
1034  /* *INDENT-OFF* */
1035  pool_foreach (si, im->sw_interfaces,
1036  ({
1037  vec_add1 (sorted_sis, si[0]);
1038  }));
1039  /* *INDENT-ON* */
1040 
1041  vec_foreach (si, sorted_sis)
1042  {
1044  {
1045  if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
1046  {
1047  continue;
1048  }
1049  sw_if_index = si->sw_if_index;
1050  send_ip_details (am, reg, sw_if_index, mp->is_ipv6, mp->context);
1051  }
1052  }
1053 
1054  vec_free (sorted_sis);
1055 }
1056 
1057 static void
1059 {
1060  vl_api_set_ip_flow_hash_reply_t *rmp;
1061  int rv;
1062  u32 table_id;
1063  flow_hash_config_t flow_hash_config = 0;
1064 
1065  table_id = ntohl (mp->vrf_id);
1066 
1067 #define _(a,b) if (mp->a) flow_hash_config |= b;
1069 #undef _
1070 
1071  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1072 
1073  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1074 }
1075 
1076 static void
1078 {
1079  vl_api_set_ip_flow_hash_reply_t *rmp;
1080  int rv;
1081  u32 table_id;
1082  flow_hash_config_t flow_hash_config = 0;
1083 
1084  table_id = ntohl (mp->vrf_id);
1085 
1086 #define _(a,b) if (mp->a) flow_hash_config |= b;
1088 #undef _
1089 
1090  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1091 
1092  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1093 }
1094 
1095 
1096 static void
1098 {
1099  if (mp->is_ipv6 == 0)
1100  set_ip4_flow_hash (mp);
1101  else
1102  set_ip6_flow_hash (mp);
1103 }
1104 
1105 static void
1108 {
1109  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1111  int rv = 0;
1112  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1113  default_router;
1114 
1115  is_no = mp->is_no == 1;
1116  suppress = mp->suppress == 1;
1117  managed = mp->managed == 1;
1118  other = mp->other == 1;
1119  ll_option = mp->ll_option == 1;
1120  send_unicast = mp->send_unicast == 1;
1121  cease = mp->cease == 1;
1122  default_router = mp->default_router == 1;
1123 
1124  VALIDATE_SW_IF_INDEX (mp);
1125 
1126  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1127  suppress, managed, other,
1128  ll_option, send_unicast, cease,
1129  default_router, ntohl (mp->lifetime),
1130  ntohl (mp->initial_count),
1131  ntohl (mp->initial_interval),
1132  ntohl (mp->max_interval),
1133  ntohl (mp->min_interval), is_no);
1134 
1136 
1137  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1138 }
1139 
1140 static void
1143 {
1145  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1146  fib_prefix_t pfx;
1147  int rv = 0;
1148  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1149 
1150  VALIDATE_SW_IF_INDEX (mp);
1151 
1152  ip_prefix_decode (&mp->prefix, &pfx);
1153  is_no = mp->is_no == 1;
1154  use_default = mp->use_default == 1;
1155  no_advertise = mp->no_advertise == 1;
1156  off_link = mp->off_link == 1;
1157  no_autoconfig = mp->no_autoconfig == 1;
1158  no_onlink = mp->no_onlink == 1;
1159 
1160  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1161  &pfx.fp_addr.ip6,
1162  pfx.fp_len, use_default,
1163  ntohl (mp->val_lifetime),
1164  ntohl (mp->pref_lifetime), no_advertise,
1165  off_link, no_autoconfig, no_onlink, is_no);
1166 
1168  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1169 }
1170 
1171 static void
1173  u32 context,
1174  const ip46_address_t * addr, u32 sw_if_index)
1175 {
1177 
1178  mp = vl_msg_api_alloc (sizeof (*mp));
1179  clib_memset (mp, 0, sizeof (*mp));
1180  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1181  mp->context = context;
1182  mp->sw_if_index = htonl (sw_if_index);
1183 
1184  ip6_address_encode (&addr->ip6, mp->ip);
1185 
1186  vl_api_send_msg (reg, (u8 *) mp);
1187 }
1188 
1190 {
1193 
1194 static fib_table_walk_rc_t
1196 {
1198 
1200  {
1201  vec_add1 (ctx->indices, fei);
1202  }
1203 
1204  return (FIB_TABLE_WALK_CONTINUE);
1205 }
1206 
1207 static void
1209 {
1210  ip6_main_t *im6 = &ip6_main;
1211  fib_table_t *fib_table;
1213  .indices = NULL,
1214  };
1215  fib_node_index_t *feip;
1216  const fib_prefix_t *pfx;
1217  vl_api_registration_t *reg;
1218 
1220  if (!reg)
1221  return;
1222 
1223  /* *INDENT-OFF* */
1224  pool_foreach (fib_table, im6->fibs,
1225  ({
1226  fib_table_walk(fib_table->ft_index,
1227  FIB_PROTOCOL_IP6,
1228  api_ip6nd_proxy_fib_table_walk,
1229  &ctx);
1230  }));
1231  /* *INDENT-ON* */
1232 
1234 
1235  vec_foreach (feip, ctx.indices)
1236  {
1237  pfx = fib_entry_get_prefix (*feip);
1238 
1240  mp->context,
1241  &pfx->fp_addr,
1243  }
1244 
1245  vec_free (ctx.indices);
1246 }
1247 
1248 static void
1250 {
1251  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1252  ip6_address_t ip6;
1253  int rv = 0;
1254 
1255  VALIDATE_SW_IF_INDEX (mp);
1256 
1257  ip6_address_decode (mp->ip, &ip6);
1258  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index), &ip6, mp->is_del);
1259 
1261  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1262 }
1263 
1264 static void
1267 {
1268  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
1271  int rv = 0;
1272 
1273  VALIDATE_SW_IF_INDEX (mp);
1274 
1276  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);
1277 
1278  if (rv != 0)
1279  return;
1280 
1281  params.irt = ntohl (mp->irt);
1282  params.mrt = ntohl (mp->mrt);
1283  params.mrc = ntohl (mp->mrc);
1284  params.mrd = ntohl (mp->mrd);
1285 
1286  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
1287  &params);
1288 }
1289 
1290 static void
1293 {
1295  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1296  vnet_main_t *vnm = vnet_get_main ();
1297  int rv = 0;
1298  clib_error_t *error;
1299 
1300  vnm->api_errno = 0;
1301 
1302  VALIDATE_SW_IF_INDEX (mp);
1303 
1304  error =
1305  (mp->enable == 1) ? enable_ip6_interface (vm,
1306  ntohl (mp->sw_if_index)) :
1307  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1308 
1309  if (error)
1310  {
1311  clib_error_report (error);
1312  rv = VNET_API_ERROR_UNSPECIFIED;
1313  }
1314  else
1315  {
1316  rv = vnm->api_errno;
1317  }
1318 
1320 
1321  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1322 }
1323 
1324 void
1326  u32 context, const mfib_signal_t * mfs)
1327 {
1329  const mfib_prefix_t *prefix;
1330  mfib_table_t *mfib;
1331  mfib_itf_t *mfi;
1332 
1333  mp = vl_msg_api_alloc (sizeof (*mp));
1334 
1335  clib_memset (mp, 0, sizeof (*mp));
1336  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1337  mp->context = context;
1338 
1339  mfi = mfib_itf_get (mfs->mfs_itf);
1340  prefix = mfib_entry_get_prefix (mfs->mfs_entry);
1342  prefix->fp_proto);
1343  mp->table_id = ntohl (mfib->mft_table_id);
1344  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1345 
1346  ip_mprefix_encode (prefix, &mp->prefix);
1347 
1348  if (0 != mfs->mfs_buffer_len)
1349  {
1350  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1351 
1352  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1353  }
1354  else
1355  {
1356  mp->ip_packet_len = 0;
1357  }
1358 
1359  vl_api_send_msg (reg, (u8 *) mp);
1360 }
1361 
1362 static void
1364 {
1365  vl_api_registration_t *reg;
1366 
1368  if (!reg)
1369  return;
1370 
1371  while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
1372  ;
1373 }
1374 
1375 static void
1378 {
1379  vl_api_ip_container_proxy_add_del_reply_t *rmp;
1381  int rv = 0;
1382  clib_error_t *error;
1383 
1384  clib_memset (&args, 0, sizeof (args));
1385 
1386  ip_prefix_decode (&mp->pfx, &args.prefix);
1387 
1388  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
1389  args.is_add = mp->is_add;
1390  if ((error = vnet_ip_container_proxy_add_del (&args)))
1391  {
1392  rv = clib_error_get_code (error);
1393  clib_error_report (error);
1394  }
1395 
1396  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
1397 }
1398 
1400 {
1404 
1405 static int
1407  void *args)
1408 {
1411 
1412  mp = vl_msg_api_alloc (sizeof (*mp));
1413  if (!mp)
1414  return 1;
1415 
1416  clib_memset (mp, 0, sizeof (*mp));
1417  mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS);
1418  mp->context = ctx->context;
1419 
1420  mp->sw_if_index = ntohl (sw_if_index);
1421  ip_prefix_encode (pfx, &mp->prefix);
1422 
1423  vl_api_send_msg (ctx->reg, (u8 *) mp);
1424 
1425  return 1;
1426 }
1427 
1428 static void
1430  mp)
1431 {
1432  vl_api_registration_t *reg;
1433 
1435  if (!reg)
1436  return;
1437 
1439  .context = mp->context,
1440  .reg = reg,
1441  };
1442 
1444 }
1445 
1446 static void
1448 {
1449  int rv = 0;
1450  vl_api_ioam_enable_reply_t *rmp;
1451  clib_error_t *error;
1452 
1453  /* Ignoring the profile id as currently a single profile
1454  * is supported */
1455  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
1456  mp->seqno, mp->analyse);
1457  if (error)
1458  {
1459  clib_error_report (error);
1460  rv = clib_error_get_code (error);
1461  }
1462 
1463  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
1464 }
1465 
1466 static void
1468 {
1469  int rv = 0;
1470  vl_api_ioam_disable_reply_t *rmp;
1471  clib_error_t *error;
1472 
1473  error = clear_ioam_rewrite_fn ();
1474  if (error)
1475  {
1476  clib_error_report (error);
1477  rv = clib_error_get_code (error);
1478  }
1479 
1480  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
1481 }
1482 
1483 static void
1486 {
1487  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
1488  int rv = 0;
1489 
1490  u8 is_add = mp->is_add;
1491  fib_prefix_t pfx;
1492  u16 *low_ports = 0;
1493  u16 *high_ports = 0;
1494  u32 vrf_id;
1495  u16 tmp_low, tmp_high;
1496  u8 num_ranges;
1497  int i;
1498 
1499  ip_prefix_decode (&mp->prefix, &pfx);
1500 
1501  // Validate port range
1502  num_ranges = mp->number_of_ranges;
1503  if (num_ranges > 32)
1504  { // This is size of array in VPE.API
1505  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1506  goto reply;
1507  }
1508 
1509  vec_reset_length (low_ports);
1510  vec_reset_length (high_ports);
1511 
1512  for (i = 0; i < num_ranges; i++)
1513  {
1514  tmp_low = mp->low_ports[i];
1515  tmp_high = mp->high_ports[i];
1516  // If tmp_low <= tmp_high then only need to check tmp_low = 0
1517  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
1518  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
1519  {
1520  rv = VNET_API_ERROR_INVALID_VALUE;
1521  goto reply;
1522  }
1523  vec_add1 (low_ports, tmp_low);
1524  vec_add1 (high_ports, tmp_high + 1);
1525  }
1526 
1527  vrf_id = ntohl (mp->vrf_id);
1528 
1529  if (vrf_id < 1)
1530  {
1531  rv = VNET_API_ERROR_INVALID_VALUE;
1532  goto reply;
1533  }
1534 
1535 
1536  if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
1537  {
1539  pfx.fp_len,
1540  vrf_id,
1541  low_ports,
1542  high_ports, is_add);
1543  }
1544  else
1545  {
1547  pfx.fp_len,
1548  vrf_id,
1549  low_ports,
1550  high_ports, is_add);
1551  }
1552 
1553 reply:
1554  vec_free (low_ports);
1555  vec_free (high_ports);
1556  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
1557 }
1558 
1559 static void
1562 {
1564  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
1565  ip4_main_t *im = &ip4_main;
1566  int rv;
1567  u32 sw_if_index;
1570  uword *p = 0;
1571  int i;
1572 
1574  ntohl (mp->tcp_out_vrf_id);
1576  ntohl (mp->udp_out_vrf_id);
1578  ntohl (mp->tcp_in_vrf_id);
1580  ntohl (mp->udp_in_vrf_id);
1581 
1582 
1583  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
1584  {
1585  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
1586  {
1587  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
1588 
1589  if (p == 0)
1590  {
1591  rv = VNET_API_ERROR_INVALID_VALUE;
1592  goto reply;
1593  }
1594 
1595  fib_index[i] = p[0];
1596  }
1597  else
1598  fib_index[i] = ~0;
1599  }
1600  sw_if_index = ntohl (mp->sw_if_index);
1601 
1602  VALIDATE_SW_IF_INDEX (mp);
1603 
1604  rv =
1605  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
1606  mp->is_add);
1607 
1609 reply:
1610 
1611  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
1612 }
1613 
1614 typedef union
1615 {
1616  u32 fib_index;
1618 
1619 static void
1622 {
1623  vl_api_ip_source_check_interface_add_del_reply_t *rmp;
1624  int rv;
1625  u32 sw_if_index = ntohl (mp->sw_if_index);
1626  u8 is_add = mp->is_add;
1627  char *feature_name =
1628  mp->loose ? "ip4-source-check-via-any" : "ip4-source-check-via-rx";
1629 
1631 
1632  VALIDATE_SW_IF_INDEX (mp);
1633 
1634  config.fib_index =
1636  rv =
1637  vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index,
1638  is_add, &config, sizeof (config));
1640 
1641  REPLY_MACRO (VL_API_IP_SOURCE_CHECK_INTERFACE_ADD_DEL_REPLY);
1642 }
1643 
1644 #define IP4_ARP_EVENT 3
1645 #define IP6_ND_EVENT 4
1646 
1648 
1649 static int
1651  const mac_address_t * mac,
1653 {
1655 
1656  if (pool_is_free_index (am->arp_events, pool_index))
1657  return 1;
1658 
1659  pool_put_index (am->arp_events, pool_index);
1660  return 0;
1661 }
1662 
1663 static void
1665 {
1666  vpe_api_main_t *vam = &vpe_api_main;
1667  vnet_main_t *vnm = vam->vnet_main;
1668  vlib_main_t *vm = vam->vlib_main;
1669  vl_api_ip4_arp_event_t *event;
1671  vl_api_registration_t *reg;
1672 
1673  /* Client can cancel, die, etc. */
1674  if (pool_is_free_index (vam->arp_events, pool_index))
1675  return;
1676 
1677  event = pool_elt_at_index (vam->arp_events, pool_index);
1678 
1680  if (!reg)
1681  {
1684  event->pid, event->ip,
1685  ip_resolver_process_node.index, IP4_ARP_EVENT,
1686  ~0 /* pool index, notused */ , 0 /* is_add */ );
1687  return;
1688  }
1689 
1690  if (vl_api_can_send_msg (reg))
1691  {
1692  mp = vl_msg_api_alloc (sizeof (*mp));
1693  clib_memcpy (mp, event, sizeof (*mp));
1694  vl_api_send_msg (reg, (u8 *) mp);
1695  }
1696  else
1697  {
1698  static f64 last_time;
1699  /*
1700  * Throttle syslog msgs.
1701  * It's pretty tempting to just revoke the registration...
1702  */
1703  if (vlib_time_now (vm) > last_time + 10.0)
1704  {
1705  clib_warning ("arp event for %U to pid %d: queue stuffed!",
1706  format_ip4_address, event->ip, event->pid);
1707  last_time = vlib_time_now (vm);
1708  }
1709  }
1710 }
1711 
1712 static int
1714  const mac_address_t * mac,
1715  u32 sw_if_index, const ip6_address_t * addr)
1716 {
1718 
1719  if (pool_is_free_index (am->nd_events, pool_index))
1720  return 1;
1721 
1722  pool_put_index (am->nd_events, pool_index);
1723  return 0;
1724 }
1725 
1726 static void
1728 {
1729  vpe_api_main_t *vam = &vpe_api_main;
1730  vnet_main_t *vnm = vam->vnet_main;
1731  vlib_main_t *vm = vam->vlib_main;
1732  vl_api_ip6_nd_event_t *event;
1734  vl_api_registration_t *reg;
1735 
1736  /* Client can cancel, die, etc. */
1737  if (pool_is_free_index (vam->nd_events, pool_index))
1738  return;
1739 
1740  event = pool_elt_at_index (vam->nd_events, pool_index);
1741 
1743  if (!reg)
1744  {
1747  event->pid, event->ip,
1748  ip_resolver_process_node.index, IP6_ND_EVENT,
1749  ~0 /* pool index, notused */ , 0 /* is_add */ );
1750  return;
1751  }
1752 
1753  if (vl_api_can_send_msg (reg))
1754  {
1755  mp = vl_msg_api_alloc (sizeof (*mp));
1756  clib_memcpy (mp, event, sizeof (*mp));
1757  vl_api_send_msg (reg, (u8 *) mp);
1758  }
1759  else
1760  {
1761  static f64 last_time;
1762  /*
1763  * Throttle syslog msgs.
1764  * It's pretty tempting to just revoke the registration...
1765  */
1766  if (vlib_time_now (vm) > last_time + 10.0)
1767  {
1768  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
1769  format_ip6_address, event->ip, event->pid);
1770  last_time = vlib_time_now (vm);
1771  }
1772  }
1773 }
1774 
1775 static uword
1778 {
1779  volatile f64 timeout = 100.0;
1780  volatile uword *event_data = 0;
1781 
1782  while (1)
1783  {
1785 
1786  uword event_type =
1787  vlib_process_get_events (vm, (uword **) & event_data);
1788 
1789  int i;
1790  switch (event_type)
1791  {
1792  case IP4_ARP_EVENT:
1793  for (i = 0; i < vec_len (event_data); i++)
1794  handle_ip4_arp_event (event_data[i]);
1795  break;
1796 
1797  case IP6_ND_EVENT:
1798  for (i = 0; i < vec_len (event_data); i++)
1799  handle_ip6_nd_event (event_data[i]);
1800  break;
1801 
1802  case ~0: /* timeout */
1803  break;
1804  }
1805 
1806  vec_reset_length (event_data);
1807  }
1808  return 0; /* or not */
1809 }
1810 
1811 /* *INDENT-OFF* */
1812 VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
1813  .function = resolver_process,
1814  .type = VLIB_NODE_TYPE_PROCESS,
1815  .name = "ip-route-resolver-process",
1816 };
1817 /* *INDENT-ON* */
1818 
1819 static int
1820 nd_change_data_callback (u32 pool_index, const mac_address_t * new_mac,
1822 {
1824  vl_api_ip6_nd_event_t *event;
1825 
1826  if (pool_is_free_index (am->nd_events, pool_index))
1827  return 1;
1828 
1829  event = pool_elt_at_index (am->nd_events, pool_index);
1830  if (ethernet_mac_address_equal (event->mac, new_mac->bytes) &&
1831  sw_if_index == ntohl (event->sw_if_index))
1832  {
1833  return 1;
1834  }
1835 
1836  mac_address_encode (new_mac, event->mac);
1837  event->sw_if_index = htonl (sw_if_index);
1838  return 0;
1839 }
1840 
1842 
1843 enum
1845 
1846 static uword
1848 {
1849  /* These cross the longjmp boundary (vlib_process_wait_for_event)
1850  * and need to be volatile - to prevent them from being optimized into
1851  * a register - which could change during suspension */
1852 
1853  volatile wc_arp_report_t arp_prev = { 0 };
1854  volatile wc_nd_report_t nd_prev = { 0 };
1855  volatile f64 last_arp = vlib_time_now (vm);
1856  volatile f64 last_nd = vlib_time_now (vm);
1857 
1858  while (1)
1859  {
1861  uword event_type = WC_ARP_REPORT;
1862  void *event_data = vlib_process_get_event_data (vm, &event_type);
1863 
1864  f64 now = vlib_time_now (vm);
1865  int i;
1866  if (event_type == WC_ARP_REPORT)
1867  {
1868  wc_arp_report_t *arp_events = event_data;
1869  for (i = 0; i < vec_len (arp_events); i++)
1870  {
1871  /* discard dup event - cast away volatile */
1872  if (arp_prev.ip.as_u32 == arp_events[i].ip.as_u32 &&
1873  mac_address_equal ((const mac_address_t *) &arp_prev.mac,
1874  &arp_events[i].mac) &&
1875  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
1876  (now - last_arp) < 10.0)
1877  {
1878  continue;
1879  }
1880  arp_prev = arp_events[i];
1881  last_arp = now;
1883  /* *INDENT-OFF* */
1884  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
1885  ({
1886  vl_api_registration_t *vl_reg;
1887  vl_reg = vl_api_client_index_to_registration (reg->client_index);
1888  ASSERT (vl_reg != NULL);
1889  if (reg && vl_api_can_send_msg (vl_reg))
1890  {
1891  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
1892  clib_memset (event, 0, sizeof *event);
1893  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
1894  event->client_index = reg->client_index;
1895  event->pid = reg->client_pid;
1896  event->mac_ip = 1;
1897  ip4_address_encode(&arp_events[i].ip, event->ip);
1898  event->sw_if_index = htonl(arp_events[i].sw_if_index);
1899  mac_address_encode(&arp_events[i].mac, event->mac);
1900  vl_api_send_msg (vl_reg, (u8 *) event);
1901  }
1902  }));
1903  /* *INDENT-ON* */
1904  }
1905  }
1906  else if (event_type == WC_ND_REPORT)
1907  {
1908  wc_nd_report_t *nd_events = event_data;
1909  for (i = 0; i < vec_len (nd_events); i++)
1910  {
1911  /* discard dup event - cast away volatile */
1912  if (ip6_address_is_equal ((const ip6_address_t *) &nd_prev.ip6,
1913  &nd_events[i].ip6)
1914  && mac_address_equal ((const mac_address_t *) &nd_prev.mac,
1915  &nd_events[i].mac)
1916  && nd_prev.sw_if_index == nd_events[i].sw_if_index
1917  && (now - last_nd) < 10.0)
1918  {
1919  continue;
1920  }
1921  nd_prev = nd_events[i];
1922  last_nd = now;
1924  /* *INDENT-OFF* */
1925  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
1926  ({
1927  vl_api_registration_t *vl_reg;
1928  vl_reg = vl_api_client_index_to_registration (reg->client_index);
1929  if (vl_reg && vl_api_can_send_msg (vl_reg))
1930  {
1931  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
1932  clib_memset (event, 0, sizeof *event);
1933  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
1934  event->client_index = reg->client_index;
1935  event->pid = reg->client_pid;
1936  event->mac_ip = 1;
1937  ip6_address_encode(&nd_events[i].ip6, event->ip);
1938  event->sw_if_index = htonl(nd_events[i].sw_if_index);
1939  mac_address_encode(&nd_events[i].mac, event->mac);
1940  vl_api_send_msg (vl_reg, (u8 *) event);
1941  }
1942  }));
1943  /* *INDENT-ON* */
1944  }
1945  }
1946  else if (event_type == RA_REPORT)
1947  {
1948  ra_report_t *ra_events = event_data;
1949  for (i = 0; i < vec_len (ra_events); i++)
1950  {
1952  call_ip6_neighbor_callbacks (&ra_events[i],
1953  npm->ra_report_functions);
1954 
1956  /* *INDENT-OFF* */
1957  pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
1958  ({
1959  vl_api_registration_t *vl_reg;
1960  vl_reg =
1961  vl_api_client_index_to_registration (reg->client_index);
1962  if (vl_reg && vl_api_can_send_msg (vl_reg))
1963  {
1964  u32 event_size =
1965  sizeof (vl_api_ip6_ra_event_t) +
1966  vec_len (ra_events[i].prefixes) *
1967  sizeof (vl_api_ip6_ra_prefix_info_t);
1968  vl_api_ip6_ra_event_t *event =
1969  vl_msg_api_alloc (event_size);
1970  clib_memset (event, 0, event_size);
1971  event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT);
1972  event->client_index = reg->client_index;
1973  event->pid = reg->client_pid;
1974 
1975  event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);
1976 
1977  ip6_address_encode (&ra_events[i].router_address,
1978  event->router_addr);
1979 
1980  event->current_hop_limit = ra_events[i].current_hop_limit;
1981  event->flags = ra_events[i].flags;
1982  event->router_lifetime_in_sec =
1983  clib_host_to_net_u16 (ra_events
1984  [i].router_lifetime_in_sec);
1985  event->neighbor_reachable_time_in_msec =
1986  clib_host_to_net_u32 (ra_events
1987  [i].neighbor_reachable_time_in_msec);
1988  event->time_in_msec_between_retransmitted_neighbor_solicitations
1989  =
1990  clib_host_to_net_u32 (ra_events
1991  [i].time_in_msec_between_retransmitted_neighbor_solicitations);
1992 
1993  event->n_prefixes =
1994  clib_host_to_net_u32 (vec_len (ra_events[i].prefixes));
1995  vl_api_ip6_ra_prefix_info_t *prefix =
1996  (typeof (prefix)) event->prefixes;
1997  u32 j;
1998  for (j = 0; j < vec_len (ra_events[i].prefixes); j++)
1999  {
2000  ra_report_prefix_info_t *info =
2001  &ra_events[i].prefixes[j];
2002  ip_prefix_encode(&info->prefix, &prefix->prefix);
2003  prefix->flags = info->flags;
2004  prefix->valid_time =
2005  clib_host_to_net_u32 (info->valid_time);
2006  prefix->preferred_time =
2007  clib_host_to_net_u32 (info->preferred_time);
2008  prefix++;
2009  }
2010 
2011  vl_api_send_msg (vl_reg, (u8 *) event);
2012  }
2013  }));
2014  /* *INDENT-ON* */
2015  vec_free (ra_events[i].prefixes);
2016  }
2017  }
2018  vlib_process_put_event_data (vm, event_data);
2019  }
2020 
2021  return 0;
2022 }
2023 
2024 /* *INDENT-OFF* */
2026  .function = wc_arp_process,
2027  .type = VLIB_NODE_TYPE_PROCESS,
2028  .name = "wildcard-ip4-arp-publisher-process",
2029 };
2030 /* *INDENT-ON* */
2031 
2032 static int
2034  const mac_address_t * mac,
2036 {
2038  vl_api_ip4_arp_event_t *event;
2039 
2040  if (pool_is_free_index (am->arp_events, pool_index))
2041  return 1;
2042 
2043  event = pool_elt_at_index (am->arp_events, pool_index);
2044  if (ethernet_mac_address_equal (event->mac, mac->bytes) &&
2045  sw_if_index == ntohl (event->sw_if_index))
2046  {
2047  return 1;
2048  }
2049 
2050  mac_address_encode (mac, event->mac);
2051  event->sw_if_index = htonl (sw_if_index);
2052  return 0;
2053 }
2054 
2055 static void
2057 {
2059  vnet_main_t *vnm = vnet_get_main ();
2060  vl_api_want_ip4_arp_events_reply_t *rmp;
2061  ip4_address_t ip;
2062  int rv = 0;
2063 
2064  ip4_address_decode (mp->ip, &ip);
2065 
2066  if (ip.as_u32 == 0)
2067  {
2068  uword *p =
2069  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
2071  if (p)
2072  {
2073  if (mp->enable_disable)
2074  {
2075  clib_warning ("pid %d: already enabled...", mp->pid);
2076  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2077  goto reply;
2078  }
2079  else
2080  {
2081  rp =
2082  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2083  pool_put (am->wc_ip4_arp_events_registrations, rp);
2084  hash_unset (am->wc_ip4_arp_events_registration_hash,
2085  mp->client_index);
2086  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2088  goto reply;
2089  }
2090  }
2091  if (mp->enable_disable == 0)
2092  {
2093  clib_warning ("pid %d: already disabled...", mp->pid);
2094  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2095  goto reply;
2096  }
2097  pool_get (am->wc_ip4_arp_events_registrations, rp);
2098  rp->client_index = mp->client_index;
2099  rp->client_pid = mp->pid;
2100  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
2101  rp - am->wc_ip4_arp_events_registrations);
2103  goto reply;
2104  }
2105 
2106  if (mp->enable_disable)
2107  {
2108  vl_api_ip4_arp_event_t *event;
2109  pool_get (am->arp_events, event);
2112  mp->pid, mp->ip /* addr, in net byte order */ ,
2114  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2115 
2116  if (rv)
2117  {
2118  pool_put (am->arp_events, event);
2119  goto reply;
2120  }
2121  clib_memset (event, 0, sizeof (*event));
2122 
2123  /* Python API expects events to have no context */
2124  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2125  event->client_index = mp->client_index;
2126  memcpy (event->ip, mp->ip, 4);
2127  event->pid = mp->pid;
2128  if (ip.as_u32 == 0)
2129  event->mac_ip = 1;
2130  }
2131  else
2132  {
2135  mp->pid, mp->ip /* addr, in net byte order */ ,
2137  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2138  }
2139 reply:
2140  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2141 }
2142 
2143 static clib_error_t *
2145 {
2147  vl_api_ip4_arp_event_t *event;
2148  u32 *to_delete, *event_id;
2149  vpe_api_main_t *am;
2150  vnet_main_t *vnm;
2151  uword *p;
2152 
2153  am = &vpe_api_main;
2154  vnm = vnet_get_main ();
2155  to_delete = NULL;
2156 
2157  /* clear out all of its pending resolutions */
2158  /* *INDENT-OFF* */
2159  pool_foreach(event, am->arp_events,
2160  ({
2161  if (event->client_index == client_index)
2162  {
2163  vec_add1(to_delete, event - am->arp_events);
2164  }
2165  }));
2166  /* *INDENT-ON* */
2167 
2168  vec_foreach (event_id, to_delete)
2169  {
2170  event = pool_elt_at_index (am->arp_events, *event_id);
2173  event->pid, event->ip,
2175  ~0 /* pool index, notused */ , 0 /* is_add */ );
2176  }
2177  vec_free (to_delete);
2178 
2179  /* remove from the registration hash */
2180  p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index);
2181 
2182  if (p)
2183  {
2184  rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2185  pool_put (am->wc_ip4_arp_events_registrations, rp);
2186  hash_unset (am->wc_ip4_arp_events_registration_hash, client_index);
2187  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2189  }
2190  return (NULL);
2191 }
2192 
2194 
2195 static void
2197 {
2199  vnet_main_t *vnm = vnet_get_main ();
2200  vl_api_want_ip6_nd_events_reply_t *rmp;
2201  ip6_address_t ip6;
2202  int rv = 0;
2203 
2204  ip6_address_decode (mp->ip, &ip6);
2205 
2206  if (ip6_address_is_zero (&ip6))
2207  {
2208  uword *p =
2209  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
2211  if (p)
2212  {
2213  if (mp->enable_disable)
2214  {
2215  clib_warning ("pid %d: already enabled...", mp->pid);
2216  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2217  goto reply;
2218  }
2219  else
2220  {
2221  rp =
2222  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2223  pool_put (am->wc_ip6_nd_events_registrations, rp);
2224  hash_unset (am->wc_ip6_nd_events_registration_hash,
2225  mp->client_index);
2226  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2228  goto reply;
2229  }
2230  }
2231  if (mp->enable_disable == 0)
2232  {
2233  clib_warning ("pid %d: already disabled...", mp->pid);
2234  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2235  goto reply;
2236  }
2237  pool_get (am->wc_ip6_nd_events_registrations, rp);
2238  rp->client_index = mp->client_index;
2239  rp->client_pid = mp->pid;
2240  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
2241  rp - am->wc_ip6_nd_events_registrations);
2243  goto reply;
2244  }
2245 
2246  if (mp->enable_disable)
2247  {
2248  vl_api_ip6_nd_event_t *event;
2249  pool_get (am->nd_events, event);
2250 
2253  mp->pid, &ip6,
2255  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
2256 
2257  if (rv)
2258  {
2259  pool_put (am->nd_events, event);
2260  goto reply;
2261  }
2262  clib_memset (event, 0, sizeof (*event));
2263 
2264  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2265  event->client_index = mp->client_index;
2266  ip6_address_encode (&ip6, event->ip);
2267  event->pid = mp->pid;
2268  }
2269  else
2270  {
2273  mp->pid, &ip6 /* addr, in net byte order */ ,
2275  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2276  }
2277 reply:
2278  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
2279 }
2280 
2281 static clib_error_t *
2283 {
2284 
2286  vl_api_ip6_nd_event_t *event;
2287  u32 *to_delete, *event_id;
2288  vpe_api_main_t *am;
2289  vnet_main_t *vnm;
2290  uword *p;
2291 
2292  am = &vpe_api_main;
2293  vnm = vnet_get_main ();
2294  to_delete = NULL;
2295 
2296  /* clear out all of its pending resolutions */
2297  /* *INDENT-OFF* */
2298  pool_foreach(event, am->nd_events,
2299  ({
2300  if (event->client_index == client_index)
2301  {
2302  vec_add1(to_delete, event - am->nd_events);
2303  }
2304  }));
2305  /* *INDENT-ON* */
2306 
2307  vec_foreach (event_id, to_delete)
2308  {
2309  event = pool_elt_at_index (am->nd_events, *event_id);
2312  event->pid, event->ip,
2314  ~0 /* pool index, notused */ , 0 /* is_add */ );
2315  }
2316  vec_free (to_delete);
2317 
2318  /* remove from the registration hash */
2319  p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index);
2320 
2321  if (p)
2322  {
2323  rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2324  pool_put (am->wc_ip6_nd_events_registrations, rp);
2325  hash_unset (am->wc_ip6_nd_events_registration_hash, client_index);
2326  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2328  }
2329  return (NULL);
2330 }
2331 
2333 
2334 static void
2336 {
2338  vl_api_want_ip6_ra_events_reply_t *rmp;
2339  int rv = 0;
2340 
2341  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
2343  if (p)
2344  {
2345  if (mp->enable_disable)
2346  {
2347  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
2348  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2349  goto reply;
2350  }
2351  else
2352  {
2353  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2354  pool_put (am->ip6_ra_events_registrations, rp);
2355  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
2356  goto reply;
2357  }
2358  }
2359  if (mp->enable_disable == 0)
2360  {
2361  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
2362  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2363  goto reply;
2364  }
2365  pool_get (am->ip6_ra_events_registrations, rp);
2366  rp->client_index = mp->client_index;
2367  rp->client_pid = ntohl (mp->pid);
2368  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
2369  rp - am->ip6_ra_events_registrations);
2370 
2371 reply:
2372  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
2373 }
2374 
2375 static clib_error_t *
2377 {
2380  uword *p;
2381 
2382  p = hash_get (am->ip6_ra_events_registration_hash, client_index);
2383 
2384  if (p)
2385  {
2386  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2387  pool_put (am->ip6_ra_events_registrations, rp);
2388  hash_unset (am->ip6_ra_events_registration_hash, client_index);
2389  }
2390  return (NULL);
2391 }
2392 
2394 
2395 static void
2397 {
2398  vl_api_proxy_arp_add_del_reply_t *rmp;
2399  ip4_address_t lo, hi;
2400  u32 fib_index;
2401  int rv;
2402 
2403  fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->proxy.table_id));
2404 
2405  if (~0 == fib_index)
2406  {
2407  rv = VNET_API_ERROR_NO_SUCH_FIB;
2408  goto out;
2409  }
2410 
2411  ip4_address_decode (mp->proxy.low, &lo);
2412  ip4_address_decode (mp->proxy.hi, &hi);
2413 
2414  rv = vnet_proxy_arp_add_del (&lo, &hi, fib_index, mp->is_add == 0);
2415 
2416 out:
2417  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2418 }
2419 
2421 {
2425 
2426 static walk_rc_t
2428  const ip4_address_t * hi_addr,
2429  u32 fib_index, void *data)
2430 {
2433 
2434  ctx = data;
2435 
2436  mp = vl_msg_api_alloc (sizeof (*mp));
2437  clib_memset (mp, 0, sizeof (*mp));
2438  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
2439  mp->context = ctx->context;
2440  mp->proxy.table_id = htonl (fib_index);
2441 
2442  ip4_address_encode (lo_addr, mp->proxy.low);
2443  ip4_address_encode (hi_addr, mp->proxy.hi);
2444 
2445  vl_api_send_msg (ctx->reg, (u8 *) mp);
2446 
2447  return (WALK_CONTINUE);
2448 }
2449 
2450 static void
2452 {
2453  vl_api_registration_t *reg;
2454 
2456  if (!reg)
2457  return;
2458 
2459  proxy_arp_walk_ctx_t wctx = {
2460  .reg = reg,
2461  .context = mp->context,
2462  };
2463 
2465 }
2466 
2467 static walk_rc_t
2469 {
2472 
2473  ctx = data;
2474 
2475  mp = vl_msg_api_alloc (sizeof (*mp));
2476  clib_memset (mp, 0, sizeof (*mp));
2477  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS);
2478  mp->context = ctx->context;
2479  mp->sw_if_index = htonl (sw_if_index);
2480 
2481  vl_api_send_msg (ctx->reg, (u8 *) mp);
2482 
2483  return (WALK_CONTINUE);
2484 }
2485 
2486 static void
2488 {
2489  vl_api_registration_t *reg;
2490 
2492  if (!reg)
2493  return;
2494 
2495  proxy_arp_walk_ctx_t wctx = {
2496  .reg = reg,
2497  .context = mp->context,
2498  };
2499 
2501 }
2502 
2503 static void
2506 {
2507  int rv = 0;
2508  vnet_main_t *vnm = vnet_get_main ();
2509  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2510 
2511  VALIDATE_SW_IF_INDEX (mp);
2512 
2514  ntohl (mp->sw_if_index),
2515  mp->enable_disable);
2516 
2518 
2519  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2520 }
2521 
2522 static void
2524 {
2525  int rv = 0;
2527  vl_api_ip_probe_neighbor_reply_t *rmp;
2528  clib_error_t *error;
2529  ip46_address_t dst;
2530  ip46_type_t itype;
2531 
2532  VALIDATE_SW_IF_INDEX (mp);
2533 
2534  u32 sw_if_index = ntohl (mp->sw_if_index);
2535  itype = ip_address_decode (&mp->dst, &dst);
2536 
2537  if (IP46_TYPE_IP6 == itype)
2538  error = ip6_probe_neighbor (vm, &dst.ip6, sw_if_index, 0);
2539  else
2540  error = ip4_probe_neighbor (vm, &dst.ip4, sw_if_index, 0);
2541 
2542  if (error)
2543  {
2544  clib_error_report (error);
2545  rv = clib_error_get_code (error);
2546  }
2547 
2549 
2550  REPLY_MACRO (VL_API_IP_PROBE_NEIGHBOR_REPLY);
2551 }
2552 
2553 static void
2556 {
2557  int rv = 0;
2558  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
2560 
2561  arg.mode = mp->mode;
2562  arg.scan_interval = mp->scan_interval;
2563  arg.max_proc_time = mp->max_proc_time;
2564  arg.max_update = mp->max_update;
2565  arg.scan_int_delay = mp->scan_int_delay;
2566  arg.stale_threshold = mp->stale_threshold;
2568 
2569  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
2570 }
2571 
2572 static int
2574 {
2575  vnet_main_t *vnm = vnet_get_main ();
2577  ip4_main_t *im4 = &ip4_main;
2578  static u32 *sw_if_indices_to_shut;
2579  fib_table_t *fib_table;
2580  ip4_fib_t *fib;
2581  u32 sw_if_index;
2582  int i;
2583  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2584  u32 target_fib_id = ntohl (mp->vrf_id);
2585 
2586  /* *INDENT-OFF* */
2587  pool_foreach (fib_table, im4->fibs,
2588  ({
2589  vnet_sw_interface_t * si;
2590 
2591  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
2592 
2593  if (fib->table_id != target_fib_id)
2594  continue;
2595 
2596  /* remove any mpls encap/decap labels */
2597  mpls_fib_reset_labels (fib->table_id);
2598 
2599  /* remove any proxy arps in this fib */
2600  vnet_proxy_arp_fib_reset (fib->table_id);
2601 
2602  /* Set the flow hash for this fib to the default */
2603  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2604 
2605  vec_reset_length (sw_if_indices_to_shut);
2606 
2607  /* Shut down interfaces in this FIB / clean out intfc routes */
2608  pool_foreach (si, im->sw_interfaces,
2609  ({
2610  u32 sw_if_index = si->sw_if_index;
2611 
2612  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2613  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2614  fib->index))
2615  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2616  }));
2617 
2618  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2619  sw_if_index = sw_if_indices_to_shut[i];
2620 
2621  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2622  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2623  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2624  }
2625 
2627 
2628  rv = 0;
2629  break;
2630  })); /* pool_foreach (fib) */
2631  /* *INDENT-ON* */
2632 
2633  return rv;
2634 }
2635 
2636 static int
2638 {
2639  vnet_main_t *vnm = vnet_get_main ();
2641  ip6_main_t *im6 = &ip6_main;
2642  static u32 *sw_if_indices_to_shut;
2643  fib_table_t *fib_table;
2644  ip6_fib_t *fib;
2645  u32 sw_if_index;
2646  int i;
2647  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2648  u32 target_fib_id = ntohl (mp->vrf_id);
2649 
2650  /* *INDENT-OFF* */
2651  pool_foreach (fib_table, im6->fibs,
2652  ({
2653  vnet_sw_interface_t * si;
2654 
2655  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
2656 
2657  if (fib->table_id != target_fib_id)
2658  continue;
2659 
2660  vec_reset_length (sw_if_indices_to_shut);
2661 
2662  /* Set the flow hash for this fib to the default */
2663  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2664 
2665  /* Shut down interfaces in this FIB / clean out intfc routes */
2666  pool_foreach (si, im->sw_interfaces,
2667  ({
2668  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
2669  fib->index)
2670  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2671  }));
2672 
2673  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2674  sw_if_index = sw_if_indices_to_shut[i];
2675 
2676  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2677  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2678  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2679  }
2680 
2682 
2683  rv = 0;
2684  break;
2685  })); /* pool_foreach (fib) */
2686  /* *INDENT-ON* */
2687 
2688  return rv;
2689 }
2690 
2691 static void
2693 {
2694  int rv;
2695  vl_api_reset_fib_reply_t *rmp;
2696 
2697  if (mp->is_ipv6)
2698  rv = ip6_reset_fib_t_handler (mp);
2699  else
2700  rv = ip4_reset_fib_t_handler (mp);
2701 
2702  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
2703 }
2704 
2705 static void
2707 {
2708  int rv;
2709  vl_api_set_arp_neighbor_limit_reply_t *rmp;
2710  vnet_main_t *vnm = vnet_get_main ();
2711  clib_error_t *error;
2712 
2713  vnm->api_errno = 0;
2714 
2715  if (mp->is_ipv6)
2716  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
2717  else
2718  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
2719 
2720  if (error)
2721  {
2722  clib_error_report (error);
2723  rv = VNET_API_ERROR_UNSPECIFIED;
2724  }
2725  else
2726  {
2727  rv = vnm->api_errno;
2728  }
2729 
2730  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
2731 }
2732 
2733 void
2735 {
2736  vl_api_ip_reassembly_set_reply_t *rmp;
2737  int rv = 0;
2738  if (mp->is_ip6)
2739  {
2740  rv = ip6_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
2741  clib_net_to_host_u32 (mp->max_reassemblies),
2742  clib_net_to_host_u32
2743  (mp->max_reassembly_length),
2744  clib_net_to_host_u32
2745  (mp->expire_walk_interval_ms));
2746  }
2747  else
2748  {
2749  rv = ip4_full_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
2750  clib_net_to_host_u32 (mp->max_reassemblies),
2751  clib_net_to_host_u32
2752  (mp->max_reassembly_length),
2753  clib_net_to_host_u32
2754  (mp->expire_walk_interval_ms));
2755  }
2756 
2757  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
2758 }
2759 
2760 void
2762 {
2764 
2766  if (rp == 0)
2767  return;
2768 
2769  vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
2770  clib_memset (rmp, 0, sizeof (*rmp));
2771  rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
2772  rmp->context = mp->context;
2773  rmp->retval = 0;
2774  if (mp->is_ip6)
2775  {
2776  rmp->is_ip6 = 1;
2778  &rmp->max_reassembly_length,
2779  &rmp->expire_walk_interval_ms);
2780  }
2781  else
2782  {
2783  rmp->is_ip6 = 0;
2785  &rmp->max_reassembly_length,
2786  &rmp->expire_walk_interval_ms);
2787  }
2788  rmp->timeout_ms = clib_host_to_net_u32 (rmp->timeout_ms);
2789  rmp->max_reassemblies = clib_host_to_net_u32 (rmp->max_reassemblies);
2791  clib_host_to_net_u32 (rmp->expire_walk_interval_ms);
2792  vl_api_send_msg (rp, (u8 *) rmp);
2793 }
2794 
2795 void
2798 {
2799  vl_api_ip_reassembly_enable_disable_reply_t *rmp;
2800  int rv = 0;
2801  rv = ip4_full_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
2802  mp->enable_ip4);
2803  if (0 == rv)
2804  {
2805  rv =
2806  ip6_full_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
2807  mp->enable_ip6);
2808  }
2809 
2810  REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
2811 }
2812 
2814 {
2818 
2819 static walk_rc_t
2821  const ip_punt_redirect_rx_t * ipr, void *arg)
2822 {
2825  fib_path_encode_ctx_t path_ctx = {
2826  .rpaths = NULL,
2827  };
2828 
2829  mp = vl_msg_api_alloc (sizeof (*mp));
2830  if (!mp)
2831  return (WALK_STOP);;
2832 
2833  clib_memset (mp, 0, sizeof (*mp));
2834  mp->_vl_msg_id = ntohs (VL_API_IP_PUNT_REDIRECT_DETAILS);
2835  mp->context = ctx->context;
2836 
2837  fib_path_list_walk_w_ext (ipr->pl, NULL, fib_path_encode, &path_ctx);
2838 
2839  mp->punt.rx_sw_if_index = htonl (rx_sw_if_index);
2840  mp->punt.tx_sw_if_index = htonl (path_ctx.rpaths[0].frp_sw_if_index);
2841 
2842  ip_address_encode (&path_ctx.rpaths[0].frp_addr,
2843  fib_proto_to_ip46 (ipr->fproto), &mp->punt.nh);
2844 
2845  vl_api_send_msg (ctx->reg, (u8 *) mp);
2846 
2847  vec_free (path_ctx.rpaths);
2848 
2849  return (WALK_CONTINUE);
2850 }
2851 
2852 static void
2854 {
2855  vl_api_registration_t *reg;
2856  fib_protocol_t fproto;
2857 
2859  if (!reg)
2860  return;
2861 
2862  fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
2863 
2865  .reg = reg,
2866  .context = mp->context,
2867  };
2868 
2869  if (~0 != mp->sw_if_index)
2870  {
2871  u32 rx_sw_if_index;
2872  index_t pri;
2873 
2874  rx_sw_if_index = ntohl (mp->sw_if_index);
2875  pri = ip_punt_redirect_find (fproto, rx_sw_if_index);
2876 
2877  if (INDEX_INVALID == pri)
2878  return;
2879 
2880  send_ip_punt_redirect_details (rx_sw_if_index,
2881  ip_punt_redirect_get (pri), &ctx);
2882  }
2883  else
2885 }
2886 
2887 #define vl_msg_name_crc_list
2888 #include <vnet/ip/ip.api.h>
2889 #undef vl_msg_name_crc_list
2890 
2891 static void
2893 {
2894 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
2895  foreach_vl_msg_name_crc_ip;
2896 #undef _
2897 }
2898 
2899 static clib_error_t *
2901 {
2902  api_main_t *am = &api_main;
2903 
2904 #define _(N,n) \
2905  vl_msg_api_set_handlers(VL_API_##N, #n, \
2906  vl_api_##n##_t_handler, \
2907  vl_noop_handler, \
2908  vl_api_##n##_t_endian, \
2909  vl_api_##n##_t_print, \
2910  sizeof(vl_api_##n##_t), 1);
2912 #undef _
2913 
2914  /*
2915  * Mark the route add/del API as MP safe
2916  */
2917  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1;
2918  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1;
2919 
2920  /*
2921  * Set up the (msg_name, crc, message-id) table
2922  */
2924 
2926 
2927  return 0;
2928 }
2929 
2931 
2932 /*
2933  * fd.io coding-style-patch-verification: ON
2934  *
2935  * Local Variables:
2936  * eval: (c-set-style "gnu")
2937  * End:
2938  */
u8 name[64]
Definition: ip.api:42
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:439
ip_neighbor_flags_t flags
Definition: arp.h:31
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:213
vnet_api_error_t ip6_full_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *max_reassembly_length, u32 *expire_walk_interval_ms)
get ip6 reassembly configuration
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
vmrglw vmrglh hi
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1701
vl_api_ip_table_t table
Definition: ip.api:126
static void vl_api_proxy_arp_intfc_enable_disable_t_handler(vl_api_proxy_arp_intfc_enable_disable_t *mp)
Definition: ip_api.c:2505
Proxy ARP add / del request.
Definition: ip.api:903
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:501
static void send_ip_address_details(vpe_api_main_t *am, vl_api_registration_t *reg, const fib_prefix_t *pfx, u32 sw_if_index, u32 context)
Definition: ip_api.c:872
Dump IP unnumbered configurations.
Definition: ip.api:524
void ip4_punt_redirect_add(u32 rx_sw_if_index, u32 tx_sw_if_index, ip46_address_t *nh)
vl_api_proxy_arp_t proxy
Definition: ip.api:908
Continue on to the next entry.
Definition: fib_table.h:868
typedef address
Definition: ip_types.api:83
VL_MSG_API_REAPER_FUNCTION(want_ip4_arp_events_reaper)
static int nd_change_delete_callback(u32 pool_index, const mac_address_t *mac, u32 sw_if_index, const ip6_address_t *addr)
Definition: ip_api.c:1713
#define hash_set(h, key, value)
Definition: hash.h:255
vl_api_proxy_arp_t proxy
Definition: ip.api:925
Register for IP6 ND resolution event on recieving NA reply MAC/IP info from ICMP6 Neighbor Solicitati...
Definition: ip.api:791
u32 flags
Definition: vhost_user.h:141
static void vl_api_ip6nd_proxy_add_del_t_handler(vl_api_ip6nd_proxy_add_del_t *mp)
Definition: ip_api.c:1249
#define clib_min(x, y)
Definition: clib.h:295
vnet_main_t * vnet_main
static void vl_api_ip_route_dump_t_handler(vl_api_ip_route_dump_t *mp)
Definition: ip_api.c:321
Reset fib table request.
Definition: ip.api:966
fib_protocol_t ft_proto
Which protocol this table serves.
Definition: fib_table.h:74
vnet_api_error_t ip4_full_reass_enable_disable(u32 sw_if_index, u8 enable_disable)
static void vl_api_ip_container_proxy_add_del_t_handler(vl_api_ip_container_proxy_add_del_t *mp)
Definition: ip_api.c:1377
int vnet_set_ip4_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip4_forward.c:2917
Register for ip6 router advertisement events.
Definition: ip.api:830
static uword resolver_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:1776
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:673
Dump IP neighboors.
Definition: ip.api:191
IP punt redirect.
Definition: ip.api:598
vl_api_mac_address_t mac
Definition: l2.api:490
#define hash_unset(h, key)
Definition: hash.h:261
static walk_rc_t send_ip_punt_redirect_details(u32 rx_sw_if_index, const ip_punt_redirect_rx_t *ipr, void *arg)
Definition: ip_api.c:2820
void ip_prefix_decode(const vl_api_prefix_t *in, fib_prefix_t *out)
Definition: ip_types_api.c:200
int ip6_neighbor_ra_prefix(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *prefix_addr, u8 prefix_len, u8 use_default, u32 val_lifetime, u32 pref_lifetime, u8 no_advertise, u8 off_link, u8 no_autoconfig, u8 no_onlink, u8 is_no)
static uword * vlib_process_wait_for_event(vlib_main_t *vm)
Definition: node_funcs.h:593
A representation of a path as described by a route producer.
Definition: fib_types.h:485
static void vl_api_ip_neighbor_add_del_t_handler(vl_api_ip_neighbor_add_del_t *mp, vlib_main_t *vm)
Definition: ip_api.c:557
int fib_api_route_add_del(u8 is_add, u8 is_multipath, u32 fib_index, const fib_prefix_t *prefix, fib_entry_flag_t entry_flags, fib_route_path_t *rpaths)
Adding routes from the API.
Definition: fib_api.c:455
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
fib_protocol_t fproto
Definition: ip_punt_drop.h:201
void mac_address_encode(const mac_address_t *in, u8 *out)
static walk_rc_t send_proxy_arp_intfc_details(u32 sw_if_index, void *data)
Definition: ip_api.c:2468
static walk_rc_t send_proxy_arp_details(const ip4_address_t *lo_addr, const ip4_address_t *hi_addr, u32 fib_index, void *data)
Definition: ip_api.c:2427
vl_api_ip_neighbor_t neighbor
Definition: ip.api:176
vnet_interface_main_t interface_main
Definition: vnet.h:56
vl_api_fib_path_nh_t nh
Definition: fib_types.api:126
ip46_type_t fib_proto_to_ip46(fib_protocol_t fproto)
Convert from fib_protocol to ip46_type.
Definition: fib_types.c:295
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, icmp6_send_router_solicitation_params_t *params)
void ip4_punt_redirect_del(u32 rx_sw_if_index)
vl_api_ip_table_t table
Definition: ip.api:483
u64 as_u64[2]
Definition: ip6_packet.h:51
A pair of indicies, for the entry and interface resp.
Definition: mfib_signal.h:29
u32 fib_table_find_or_create_and_lock_w_name(fib_protocol_t proto, u32 table_id, fib_source_t src, const u8 *name)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1148
u32 sw_if_index
Definition: arp.h:94
static void vl_api_ip_mtable_dump_t_handler(vl_api_ip_mtable_dump_t *mp)
Definition: ip_api.c:373
int ip_neighbor_add(const ip46_address_t *ip, ip46_type_t type, const mac_address_t *mac, u32 sw_if_index, ip_neighbor_flags_t flags, u32 *stats_index)
Definition: ip_neighbor.c:68
void fib_api_path_encode(const fib_route_path_t *rpath, vl_api_fib_path_t *out)
Definition: fib_api.c:358
Proxy ARP interface dump request.
Definition: ip.api:945
clib_error_t * call_ip6_neighbor_callbacks(void *data, _vnet_ip6_neighbor_function_list_elt_t *elt)
vl_api_ip6_address_t ip
Definition: ip.api:797
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:58
iOAM disable
Definition: ip.api:1012
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
Set max allowed ARP or ip6 neighbor entries request.
Definition: ip.api:980
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:279
Dump IP multicast fib table.
Definition: ip.api:479
vl_api_mac_address_t mac
Definition: ip.api:773
u32 fib_table_get_index_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the index of the FIB bound to the interface.
Definition: fib_table.c:972
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:35
#define IP6_ND_EVENT
Definition: ip_api.c:1645
clib_error_t * ip4_set_arp_limit(u32 arp_limit)
Definition: arp.c:1933
ip6_neighbor_t * ip6_neighbors_entries(u32 sw_if_index)
Definition: ip6_neighbor.c:985
mac_address_t mac
Definition: ip6_neighbor.h:36
void ip6_address_decode(const vl_api_ip6_address_t in, ip6_address_t *out)
Definition: ip_types_api.c:117
From the CLI.
Definition: fib_entry.h:83
u32 index_t
A Data-Path Object is an object that represents actions that are applied to packets are they are swit...
Definition: dpo.h:41
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
IPv4 Reassembly.
static int nd_change_data_callback(u32 pool_index, const mac_address_t *new_mac, u32 sw_if_index, const ip6_address_t *address)
Definition: ip_api.c:1820
vl_api_punt_redirect_t punt
Definition: ip.api:602
int i
int ip6_neighbor_proxy_add_del(u32 sw_if_index, ip6_address_t *addr, u8 is_del)
void ip_table_delete(fib_protocol_t fproto, u32 table_id, u8 is_api)
Definition: ip_api.c:597
ip_lookup_main_t lookup_main
Definition: ip4.h:107
void vl_api_ip_reassembly_set_t_handler(vl_api_ip_reassembly_set_t *mp)
Definition: ip_api.c:2734
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
Add / del route request.
Definition: ip.api:103
vlib_main_t * vlib_main
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1691
static vl_api_ip_neighbor_flags_t ip_neighbor_flags_encode(ip_neighbor_flags_t f)
Definition: ip_api.c:121
fib_node_index_t mfib_table_entry_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, fib_rpf_id_t rpf_id, mfib_entry_flags_t entry_flags)
Add a new (with no replication) or lock an existing entry.
Definition: mfib_table.c:235
void mfib_api_path_encode(const fib_route_path_t *in, vl_api_mfib_path_t *out)
Definition: mfib_api.c:69
IPv6 router advertisement config request.
Definition: ip.api:253
u8 data[128]
Definition: ipsec.api:251
vl_api_registration_t * reg
Definition: ip_api.c:1401
vl_api_mprefix_t prefix
Definition: ip.api:456
static void vl_api_proxy_arp_intfc_dump_t_handler(vl_api_proxy_arp_intfc_dump_t *mp)
Definition: ip_api.c:2487
struct api_ip6nd_proxy_fib_table_walk_ctx_t_ api_ip6nd_proxy_fib_table_walk_ctx_t
static clib_error_t * want_ip6_nd_events_reaper(u32 client_index)
Definition: ip_api.c:2282
void vl_api_ip_reassembly_enable_disable_t_handler(vl_api_ip_reassembly_enable_disable_t *mp)
Definition: ip_api.c:2797
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:236
static void vl_api_ip6nd_proxy_dump_t_handler(vl_api_ip6nd_proxy_dump_t *mp)
Definition: ip_api.c:1208
void * vl_msg_api_alloc(int nbytes)
static fib_table_walk_rc_t api_ip6nd_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:1195
vhost_vring_addr_t addr
Definition: vhost_user.h:147
#define IP4_ARP_EVENT
Definition: ip_api.c:1644
unsigned char u8
Definition: types.h:56
void vl_api_ip_reassembly_get_t_handler(vl_api_ip_reassembly_get_t *mp)
Definition: ip_api.c:2761
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
index_t ip_punt_redirect_find(fib_protocol_t fproto, u32 rx_sw_if_index)
Definition: ip_punt_drop.c:61
struct vl_api_ip_mfib_dump_ctx_t_ vl_api_ip_mfib_dump_ctx_t
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
int ip_neighbor_del(const ip46_address_t *ip, ip46_type_t type, u32 sw_if_index)
Definition: ip_neighbor.c:111
#define clib_memcpy(d, s, n)
Definition: string.h:180
enum walk_rc_t_ walk_rc_t
Walk return code.
static int vl_api_can_send_msg(vl_api_registration_t *rp)
Definition: api.h:48
IP FIB table response.
Definition: ip.api:72
static void handle_ip4_arp_event(u32 pool_index)
Definition: ip_api.c:1664
format_function_t format_ip4_address
Definition: format.h:75
fib_node_index_t mfib_table_entry_paths_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpaths)
Definition: mfib_table.c:341
Proxy ARP add / del interface request.
Definition: ip.api:934
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:493
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:525
Add / del table request A table can be added multiple times, but need be deleted only once...
Definition: ip.api:50
vl_api_interface_index_t sw_if_index
Definition: gre.api:50
Start / stop sending router solicitation.
Definition: ip.api:368
void ip_neighbor_scan_enable_disable(ip_neighbor_scan_arg_t *arg)
Definition: ip_neighbor.c:134
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:516
vl_api_ip_mroute_t route
Definition: ip.api:467
clib_error_t * vnet_ip_container_proxy_add_del(vnet_ip_container_proxy_args_t *args)
Definition: lookup.c:1254
enum ip_neighbor_flags_t_ ip_neighbor_flags_t
struct _vnet_ip_container_proxy_args vnet_ip_container_proxy_args_t
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
Definition: vec.h:311
void proxy_arp_walk(proxy_arp_walk_t cb, void *data)
Definition: arp.c:2399
Set interface source and L4 port-range request.
Definition: ip.api:673
u32 index
Definition: ip4_fib.h:57
struct _vl_api_ip4_arp_event * arp_events
u32 mfib_table_find_or_create_and_lock_w_name(fib_protocol_t proto, u32 table_id, mfib_source_t src, const u8 *name)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:620
fib_node_index_t pl
Definition: ip_punt_drop.h:203
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:1345
void vl_api_ip_route_add_del_t_handler(vl_api_ip_route_add_del_t *mp)
Definition: ip_api.c:702
Aggregate type for a prefix.
Definition: fib_types.h:203
int ip6_interface_enabled(vlib_main_t *vm, u32 sw_if_index)
static void vl_api_ip_dump_t_handler(vl_api_ip_dump_t *mp)
Definition: ip_api.c:1017
IPv6 interface enable / disable request.
Definition: ip.api:386
vl_api_ip_table_t table
Definition: ip.api:55
u32 mfib_entry_get_stats_index(fib_node_index_t fib_entry_index)
Definition: mfib_entry.c:1225
struct proxy_arp_walk_ctx_t_ proxy_arp_walk_ctx_t
unsigned int u32
Definition: types.h:88
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip4.h:116
u32 fib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1080
u16 fp_len
The mask length.
Definition: fib_types.h:207
static void vl_api_set_arp_neighbor_limit_t_handler(vl_api_set_arp_neighbor_limit_t *mp)
Definition: ip_api.c:2706
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1363
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index, u8 refresh)
Definition: ip6_forward.c:1530
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1623
ip46_type_t ip_address_decode(const vl_api_address_t *in, ip46_address_t *out)
Definition: ip_types_api.c:161
vl_api_address_with_prefix_t prefix
Definition: ip.api:499
vl_api_fib_path_t paths[n_paths]
Definition: ip.api:91
static void vl_api_ip_scan_neighbor_enable_disable_t_handler(vl_api_ip_scan_neighbor_enable_disable_t *mp)
Definition: ip_api.c:2555
u32 mfib_entry_get_fib_index(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1379
vl_api_address_t dst
Definition: ip.api:737
Definition: fib_entry.h:281
Configure IP source and L4 port-range check.
Definition: ip.api:654
int mfib_api_path_decode(vl_api_mfib_path_t *in, fib_route_path_t *out)
Definition: mfib_api.c:96
static int api_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp, u32 *stats_index)
Definition: ip_api.c:793
vl_api_fib_path_type_t type
Definition: fib_types.api:123
Set interface source check request.
Definition: ip.api:692
vnet_api_error_t api_errno
Definition: vnet.h:78
u32 rpf_id
Definition: fib_types.api:119
u32 stats_index
Definition: ip.api:88
Definition: fib_entry.h:286
#define hash_get(h, key)
Definition: hash.h:249
static void vl_api_want_ip6_nd_events_t_handler(vl_api_want_ip6_nd_events_t *mp)
Definition: ip_api.c:2196
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:514
IP probe neighbor address on an interface by sending an ARP request (for IP4) or ICMP6 Neighbor Solic...
Definition: ip.api:732
static fib_table_walk_rc_t vl_api_ip_fib_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:264
vl_api_ip_route_t route
Definition: ip.api:109
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
Definition: ip4.h:131
static mfib_itf_t * mfib_itf_get(index_t mi)
Get the MFIB interface representation.
Definition: mfib_itf.h:78
int vnet_proxy_arp_enable_disable(vnet_main_t *vnm, u32 sw_if_index, u8 enable)
Definition: arp.c:2412
static int mfib_route_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:400
void mfib_table_unlock(u32 fib_index, fib_protocol_t proto, mfib_source_t source)
Take a reference counting lock on the table.
Definition: mfib_table.c:702
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
lo
ip4_address_t ip4_address
Definition: arp.h:27
long ctx[MAX_CONNS]
Definition: main.c:144
mac_address_t mac
Definition: arp.h:29
static void vl_api_ip_mroute_dump_t_handler(vl_api_ip_mroute_dump_t *mp)
Definition: ip_api.c:449
u32 sw_if_index
Definition: arp.h:26
unsigned short u16
Definition: types.h:57
void vl_api_ip_table_add_del_t_handler(vl_api_ip_table_add_del_t *mp)
Definition: ip_api.c:632
static u32 mroute_add_del_handler(u8 is_add, u8 is_multipath, u32 fib_index, const mfib_prefix_t *prefix, u32 entry_flags, u32 rpf_id, fib_route_path_t *rpaths)
Definition: ip_api.c:759
static void vl_api_proxy_arp_add_del_t_handler(vl_api_proxy_arp_add_del_t *mp)
Definition: ip_api.c:2396
static void vl_api_sw_interface_ip6nd_ra_prefix_t_handler(vl_api_sw_interface_ip6nd_ra_prefix_t *mp)
Definition: ip_api.c:1142
IP Multicast Route Details.
Definition: ip.api:489
fib_node_index_t * entries
Definition: ip_api.c:396
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:286
int mfib_entry_cmp_for_sort(void *i1, void *i2)
Definition: mfib_entry.c:1193
vl_api_ip4_address_t ip
Definition: ip.api:770
#define REPLY_MACRO(t)
vnet_sw_interface_flags_t flags
Definition: interface.h:703
Proxy ARP dump details reply.
Definition: ip.api:922
u32 index
Definition: ip6.h:78
IP FIB table entry response.
Definition: ip.api:132
fib_node_index_t * entries
Definition: ip_api.c:317
Tell client about an IP4 ARP resolution event or MAC/IP info from ARP requests in L2 BDs...
Definition: ip.api:767
vl_api_ip4_address_t low
Definition: ip.api:893
static_always_inline int mac_address_equal(const mac_address_t *a, const mac_address_t *b)
Definition: mac_address.h:140
vl_api_address_t dst
Definition: gre.api:52
static void send_ip6nd_proxy_details(vl_api_registration_t *reg, u32 context, const ip46_address_t *addr, u32 sw_if_index)
Definition: ip_api.c:1172
vl_api_ip6_address_t ip
Definition: ip.api:341
VLIB_API_INIT_FUNCTION(ip_api_hookup)
void fib_table_unlock(u32 fib_index, fib_protocol_t proto, fib_source_t source)
Take a reference counting lock on the table.
Definition: fib_table.c:1253
u8 name[64]
Definition: memclnt.api:152
static void vl_api_sw_interface_ip6_enable_disable_t_handler(vl_api_sw_interface_ip6_enable_disable_t *mp)
Definition: ip_api.c:1292
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1097
void ra_set_publisher_node(uword node_index, uword event_type)
Definition: ip6_neighbor.c:331
IOAM enable : Enable in-band OAM.
Definition: ip.api:995
struct _vl_api_ip6_nd_event * nd_events
clib_error_t * ip4_probe_neighbor(vlib_main_t *vm, ip4_address_t *dst, u32 sw_if_index, u8 refresh)
Definition: ip4_forward.c:2167
static void vl_api_ip_unnumbered_dump_t_handler(vl_api_ip_unnumbered_dump_t *mp)
Definition: ip_api.c:967
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:203
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1458
static clib_error_t * want_ip6_ra_events_reaper(u32 client_index)
Definition: ip_api.c:2376
An API client registration, only in vpp/vlib.
Definition: api_common.h:46
void wc_nd_set_publisher_node(uword node_index, uword event_type)
Definition: ip6_neighbor.c:300
vl_api_registration_t * reg
Definition: ip_api.c:2422
The IPv4 FIB.
Definition: ip4_fib.h:39
#define BAD_SW_IF_INDEX_LABEL
Proxy ARP interface dump details reply.
Definition: ip.api:954
static int arp_change_data_callback(u32 pool_index, const mac_address_t *mac, u32 sw_if_index, const ip4_address_t *address)
Definition: ip_api.c:2033
static uword vnet_sw_if_index_is_api_valid(u32 sw_if_index)
void mfib_table_walk(u32 fib_index, fib_protocol_t proto, mfib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: mfib_table.c:754
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:169
Set the ip flow hash config for a fib request.
Definition: ip.api:221
vl_api_mprefix_t prefix
Definition: ip.api:556
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:89
format_function_t format_ip6_address
Definition: format.h:93
vlib_main_t * vm
Definition: buffer.c:323
static void vl_api_ip_punt_redirect_t_handler(vl_api_ip_punt_redirect_t *mp, vlib_main_t *vm)
Definition: ip_api.c:499
static_always_inline ip_punt_redirect_rx_t * ip_punt_redirect_get(index_t rrxi)
Definition: ip_punt_drop.h:271
static void vl_api_ip_container_proxy_dump_t_handler(vl_api_ip_container_proxy_dump_t *mp)
Definition: ip_api.c:1429
static uword ip6_address_is_zero(const ip6_address_t *a)
Definition: ip6_packet.h:299
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:341
struct vl_api_ip_fib_dump_walk_ctx_t_ vl_api_ip_fib_dump_walk_ctx_t
IP4 punt redirect per-rx interface configuration redirect punted traffic to another location...
Definition: ip_punt_drop.h:194
Definition: ip6.h:69
static int ethernet_mac_address_equal(const u8 *a, const u8 *b)
Definition: mac_address.h:85
u8 * ft_desc
Table description.
Definition: fib_table.h:114
void ip_mprefix_encode(const mfib_prefix_t *in, vl_api_mprefix_t *out)
Definition: ip_types_api.c:225
static void send_ip_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 sw_if_index, u8 is_ipv6, u32 context)
Definition: ip_api.c:854
#define clib_warning(format, args...)
Definition: error.h:59
vnet_api_error_t ip4_full_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *max_reassembly_length, u32 *expire_walk_interval_ms)
get ip4 reassembly configuration
static vlib_node_registration_t wc_arp_process_node
(constructor) VLIB_REGISTER_NODE (wc_arp_process_node)
Definition: ip_api.c:1841
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: ip_api.c:1485
ip6_address_t ip6
Definition: ip6_neighbor.h:94
clib_error_t * ip6_ioam_enable(int has_trace_option, int has_pot_option, int has_seqno_option, int has_analyse_option)
void wc_arp_set_publisher_node(uword node_index, uword event_type)
Definition: arp.c:2003
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
static void set_ip6_flow_hash(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1058
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:283
void ip4_punt_policer_add_del(u8 is_add, u32 policer_index)
void ip_container_proxy_walk(ip_container_proxy_cb_t cb, void *ctx)
Definition: lookup.c:1340
int vnet_add_del_ip4_arp_change_event(vnet_main_t *vnm, arp_change_event_cb_t data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
Definition: arp.c:888
static void vl_api_proxy_arp_dump_t_handler(vl_api_proxy_arp_dump_t *mp)
Definition: ip_api.c:2451
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:57
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
IP unnumbered configurations.
Definition: ip.api:514
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:2444
Aggregate type for a prefix.
Definition: mfib_types.h:24
enum fib_entry_flag_t_ fib_entry_flag_t
void ip6_punt_redirect_add(u32 rx_sw_if_index, u32 tx_sw_if_index, ip46_address_t *nh)
void ip6_punt_redirect_del(u32 rx_sw_if_index)
static void vl_api_ioam_disable_t_handler(vl_api_ioam_disable_t *mp)
Definition: ip_api.c:1467
#define foreach_flow_hash_bit
Definition: lookup.h:72
int vnet_add_del_ip6_nd_change_event(vnet_main_t *vnm, ip6_nd_change_event_cb_t data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
static void vl_api_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:2692
void ip6_punt_policer_add_del(u8 is_add, u32 policer_index)
static int ip4_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:2573
void vl_api_ip_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:837
IP neighbor add / del request.
Definition: ip.api:170
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:311
vl_api_ip_mroute_t route
Definition: ip.api:492
vl_api_ip4_address_t hi
Definition: ip.api:894
Dump IP multicast fib table.
Definition: ip.api:411
static void vl_api_ip_table_dump_t_handler(vl_api_ip_table_dump_t *mp)
Definition: ip_api.c:233
mac_address_t mac
Definition: ip6_neighbor.h:95
ip6_address_t ip6_address
Definition: ip6_neighbor.h:28
int mfib_signal_send_one(struct vl_api_registration_ *reg, u32 context)
Definition: mfib_signal.c:94
ip6_main_t ip6_main
Definition: ip6_forward.c:2732
ip_lookup_main_t lookup_main
Definition: ip6.h:179
index_t mfs_itf
Definition: mfib_signal.h:32
static int arp_change_delete_callback(u32 pool_index, const mac_address_t *mac, u32 sw_if_index, const ip4_address_t *address)
Definition: ip_api.c:1650
static int ip_container_proxy_send_details(const fib_prefix_t *pfx, u32 sw_if_index, void *args)
Definition: ip_api.c:1406
void fib_table_walk(u32 fib_index, fib_protocol_t proto, fib_table_walk_fn_t fn, void *ctx)
Walk all entries in a FIB table N.B: This is NOT safe to deletes.
Definition: fib_table.c:1213
static ip_neighbor_flags_t ip_neighbor_flags_decode(vl_api_ip_neighbor_flags_t v)
Definition: ip_api.c:542
ip46_type_t
Definition: ip6_packet.h:70
u32 fib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: fib_table.c:1069
IPv6 router advertisement prefix config request.
Definition: ip.api:301
IPv6 ND proxy details returned after request.
Definition: ip.api:337
IPv4 main type.
Definition: ip4.h:105
vnet_api_error_t ip4_full_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 max_reassembly_length, u32 expire_walk_interval_ms)
set ip4 reassembly configuration
void proxy_arp_intfc_walk(proxy_arp_intf_walk_t cb, void *data)
Definition: arp.c:2481
static void set_ip4_flow_hash(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1077
int fib_api_path_decode(vl_api_fib_path_t *in, fib_route_path_t *out)
Definition: fib_api.c:150
An interface associated with a particular MFIB entry.
Definition: mfib_itf.h:25
IPv6 ND proxy dump request.
Definition: ip.api:350
static uword wc_arp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:1847
Path encode context to use when walking a path-list to encode paths.
Definition: fib_path.h:213
static void vl_api_ip_source_check_interface_add_del_t_handler(vl_api_ip_source_check_interface_add_del_t *mp)
Definition: ip_api.c:1621
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: ip_api.c:1447
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:188
static void vl_api_ip_probe_neighbor_t_handler(vl_api_ip_probe_neighbor_t *mp)
Definition: ip_api.c:2523
vl_api_prefix_t prefix
Definition: ip.api:89
fib_protocol_t mft_proto
Which protocol this table serves.
Definition: mfib_table.h:56
#define clib_error_report(e)
Definition: error.h:113
void ip6_address_encode(const ip6_address_t *in, vl_api_ip6_address_t out)
Definition: ip_types_api.c:111
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:66
From the control plane API.
Definition: fib_entry.h:79
u32 mfib_table_get_table_id(u32 fib_index, fib_protocol_t proto)
Get the Table-ID of the FIB from protocol and index.
Definition: mfib_table.c:542
static uword ip6_address_is_equal(const ip6_address_t *a, const ip6_address_t *b)
Definition: ip6_packet.h:240
static clib_error_t * ip_api_hookup(vlib_main_t *vm)
Definition: ip_api.c:2900
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
u32 fib_table_entry_get_stats_index(u32 fib_index, const fib_prefix_t *prefix)
Return the stats index for a FIB entry.
Definition: fib_table.c:905
vl_api_ip_table_t table
Definition: ip.api:420
static vlib_node_registration_t ip_resolver_process_node
(constructor) VLIB_REGISTER_NODE (ip_resolver_process_node)
Definition: ip_api.c:1647
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:2870
IP neighboors dump response.
Definition: ip.api:203
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
vl_api_punt_redirect_t punt
Definition: ip.api:617
static void send_ip_mtable_details(vl_api_registration_t *reg, u32 context, const mfib_table_t *mfib_table)
Definition: ip_api.c:354
vl_api_address_t nh
Definition: ip.api:589
fib_route_path_t * rpaths
Definition: fib_path.h:215
void ip_prefix_encode(const fib_prefix_t *in, vl_api_prefix_t *out)
Definition: ip_types_api.c:217
struct _vlib_node_registration vlib_node_registration_t
u32 table_id
Definition: ip.api:87
int mfib_api_table_id_decode(fib_protocol_t fproto, u32 table_id, u32 *fib_index)
Definition: mfib_api.c:105
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
static void setup_message_id_table(api_main_t *am)
Definition: ip_api.c:2892
vl_api_ip_neighbor_t neighbor
Definition: ip.api:205
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:463
vl_api_address_t ip
Definition: l2.api:489
int fib_api_table_id_decode(fib_protocol_t fproto, u32 table_id, u32 *fib_index)
Definition: fib_api.c:44
vl_api_ip6_address_t ip
Definition: ip.api:814
mfib_table_t * mfib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: mfib_table.c:28
static void vl_api_ip_punt_police_t_handler(vl_api_ip_punt_police_t *mp, vlib_main_t *vm)
Definition: ip_api.c:484
ip6_neighbor_key_t key
Definition: ip6_neighbor.h:35
Enable/disable periodic IP neighbor scan.
Definition: ip.api:713
A for-us/local path.
Definition: fib_types.h:338
fib_route_path_t * fib_entry_encode(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1661
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
static void vl_api_want_ip4_arp_events_t_handler(vl_api_want_ip4_arp_events_t *mp)
Definition: ip_api.c:2056
const mfib_prefix_t * mfib_entry_get_prefix(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1369
#define INDEX_INVALID
Invalid index - used when no index is known blazoned capitals INVALID speak volumes where ~0 does not...
Definition: dpo.h:47
static fib_protocol_t fib_ip_proto(bool is_ip6)
Convert from boolean is_ip6 to FIB protocol.
Definition: fib_types.h:80
Definition: fib_entry.h:282
u32 mfib_table_find(fib_protocol_t proto, u32 table_id)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:553
u64 uword
Definition: types.h:112
ip6_neighbor_public_main_t ip6_neighbor_public_main
Definition: ip6_neighbor.c:235
IPv6 ND proxy config.
Definition: ip.api:324
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:980
void ip4_address_decode(const vl_api_ip4_address_t in, ip4_address_t *out)
Definition: ip_types_api.c:129
int ip6_neighbor_ra_config(vlib_main_t *vm, u32 sw_if_index, u8 suppress, u8 managed, u8 other, u8 ll_option, u8 send_unicast, u8 cease, u8 use_lifetime, u32 lifetime, u32 initial_count, u32 initial_interval, u32 max_interval, u32 min_interval, u8 is_no)
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:837
#define clib_error_get_code(err)
Definition: error.h:77
vnet_api_error_t ip6_full_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 max_reassembly_length, u32 expire_walk_interval_ms)
set ip6 reassembly configuration
u8 mfs_buffer[MFIB_SIGNAL_BUFFER_SIZE]
A buffer copied from the DP plane that triggered the signal.
Definition: mfib_signal.h:37
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)
vl_api_ip_table_t table
Definition: ip.api:75
Proxy ARP dump request.
Definition: ip.api:913
vl_api_ip6_address_t ip
Definition: ip.api:330
static clib_error_t * want_ip4_arp_events_reaper(u32 client_index)
Definition: ip_api.c:2144
vl_api_ip_route_t route
Definition: ip.api:135
void ip_address_encode(const ip46_address_t *in, ip46_type_t type, vl_api_address_t *out)
Definition: ip_types_api.c:178
static void vl_api_sw_interface_ip6nd_ra_config_t_handler(vl_api_sw_interface_ip6nd_ra_config_t *mp)
Definition: ip_api.c:1107
Tell client about an IP6 ND resolution or MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs...
Definition: ip.api:809
vl_api_mac_address_t mac
Definition: ip.api:815
u32 client_index
Definition: ip.api:540
mac_address_t mac
Definition: arp.h:96
Dump IP routes from a table.
Definition: ip.api:122
ip4_address_t ip
Definition: arp.h:95
static vnet_sw_interface_flags_t vnet_sw_interface_get_flags(vnet_main_t *vnm, u32 sw_if_index)
u32 mfi_sw_if_index
The SW IF index that this MFIB interface represents.
Definition: mfib_itf.h:40
u8 * is_mp_safe
Message is mp safe vector.
Definition: api_common.h:226
u32 entry_flags
Definition: ip.api:454
A protocol Independent IP multicast FIB table.
Definition: mfib_table.h:35
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1076
static void vlib_process_put_event_data(vlib_main_t *vm, void *event_data)
Definition: node_funcs.h:500
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
ip_neighbor_flags_t flags
Definition: ip6_neighbor.h:37
u32 table_id
Definition: ip.api:40
Register for IP4 ARP resolution event on receing ARP reply or MAC/IP info from ARP requests in L2 BDs...
Definition: ip.api:749
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:110
Enable/disable reassembly feature.
Definition: ip.api:1055
void ip4_address_encode(const ip4_address_t *in, vl_api_ip4_address_t out)
Definition: ip_types_api.c:123
IP punt policer.
Definition: ip.api:568
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t * clear_ioam_rewrite_fn(void)
static void vl_api_ip_punt_redirect_dump_t_handler(vl_api_ip_punt_redirect_dump_t *mp)
Definition: ip_api.c:2853
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:719
vnet_api_error_t ip6_full_reass_enable_disable(u32 sw_if_index, u8 enable_disable)
void fib_path_list_walk_w_ext(fib_node_index_t path_list_index, const fib_path_ext_list_t *ext_list, fib_path_list_walk_w_ext_fn_t func, void *ctx)
struct ip_punt_redirect_walk_ctx_t_ ip_punt_redirect_walk_ctx_t
static void send_ip_neighbor_details(u32 sw_if_index, const ip46_address_t *ip_address, const mac_address_t *mac, ip_neighbor_flags_t flags, vl_api_registration_t *reg, u32 context)
Definition: ip_api.c:134
fib_route_path_t * mfib_entry_encode(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1333
static void vl_api_ip_address_dump_t_handler(vl_api_ip_address_dump_t *mp)
Definition: ip_api.c:891
ethernet_arp_ip4_entry_t * ip4_neighbor_entries(u32 sw_if_index)
Definition: arp.c:1786
static void send_ip_table_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 context, const fib_table_t *table)
Definition: ip_api.c:211
vl_api_ip4_address_t ip
Definition: ip.api:755
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:199
_vnet_ip6_neighbor_function_list_elt_t * ra_report_functions
Definition: ip6_neighbor.h:145
static int ip_route_add_del_t_handler(vl_api_ip_route_add_del_t *mp, u32 *stats_index)
Definition: ip_api.c:653
struct apt_ip6_fib_show_ctx_t_ api_ip6_fib_show_ctx_t
u32 table_id
Definition: fib_types.api:118
clib_error_t * disable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
fib_node_index_t mfs_entry
Definition: mfib_signal.h:31
void ip_mprefix_decode(const vl_api_mprefix_t *in, mfib_prefix_t *out)
Definition: ip_types_api.c:236
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)
vl_api_registration_t * reg
Definition: ip_api.c:2815
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
void ip_punt_redirect_walk(fib_protocol_t fproto, ip_punt_redirect_walk_cb_t cb, void *ctx)
Definition: ip_punt_drop.c:160
u32 context
Definition: gre.api:45
void mfib_table_entry_paths_remove(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpaths)
Definition: mfib_table.c:393
void vl_mfib_signal_send_one(vl_api_registration_t *reg, u32 context, const mfib_signal_t *mfs)
Definition: ip_api.c:1325
static void handle_ip6_nd_event(u32 pool_index)
Definition: ip_api.c:1727
api_main_t api_main
Definition: api_shared.c:35
struct fib_table_t_ * fibs
Definition: ip6.h:182
void mac_address_decode(const u8 *in, mac_address_t *out)
Conversion functions to/from (decode/encode) API types to VPP internal types.
static void vl_api_ip6nd_send_router_solicitation_t_handler(vl_api_ip6nd_send_router_solicitation_t *mp)
Definition: ip_api.c:1266
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: ip_api.c:1561
#define foreach_ip_api_msg
Definition: ip_api.c:70
static void send_ip_mroute_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 context, fib_node_index_t mfib_entry_index)
Definition: ip_api.c:410
static void send_ip_route_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 context, fib_node_index_t fib_entry_index)
Definition: ip_api.c:274
Dump IP all fib tables.
Definition: ip.api:62
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:275
#define VALIDATE_SW_IF_INDEX(mp)
fib_path_list_walk_rc_t fib_path_encode(fib_node_index_t path_list_index, fib_node_index_t path_index, const fib_path_ext_t *path_ext, void *args)
Definition: fib_path.c:2707
A protocol Independent FIB table.
Definition: fib_table.h:69
Definition: arp.h:24
fib_node_index_t * feis
Definition: ip_api.c:260
IPv6 Proxy ND.
Definition: fib_entry.h:103
static int ip6_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:2637
clib_error_t * ip6_set_neighbor_limit(u32 neighbor_limit)
static void vl_api_ip_neighbor_dump_t_handler(vl_api_ip_neighbor_dump_t *mp)
Definition: ip_api.c:156
static void vl_api_want_ip6_ra_events_t_handler(vl_api_want_ip6_ra_events_t *mp)
Definition: ip_api.c:2335
IPv6 Reassembly.
static void send_ip_unnumbered_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 sw_if_index, u32 ip_sw_if_index, u32 context)
Definition: ip_api.c:949
struct ip_container_proxy_walk_ctx_t_ ip_container_proxy_walk_ctx_t
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