FD.io VPP  v19.08-27-gf4dcae4
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>
46 #include <vnet/ip/ip4_reassembly.h>
47 #include <vnet/ip/ip6_reassembly.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 
1055 static void
1057 {
1058  vl_api_set_ip_flow_hash_reply_t *rmp;
1059  int rv;
1060  u32 table_id;
1061  flow_hash_config_t flow_hash_config = 0;
1062 
1063  table_id = ntohl (mp->vrf_id);
1064 
1065 #define _(a,b) if (mp->a) flow_hash_config |= b;
1067 #undef _
1068 
1069  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1070 
1071  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1072 }
1073 
1074 static void
1076 {
1077  vl_api_set_ip_flow_hash_reply_t *rmp;
1078  int rv;
1079  u32 table_id;
1080  flow_hash_config_t flow_hash_config = 0;
1081 
1082  table_id = ntohl (mp->vrf_id);
1083 
1084 #define _(a,b) if (mp->a) flow_hash_config |= b;
1086 #undef _
1087 
1088  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1089 
1090  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1091 }
1092 
1093 
1094 static void
1096 {
1097  if (mp->is_ipv6 == 0)
1098  set_ip4_flow_hash (mp);
1099  else
1100  set_ip6_flow_hash (mp);
1101 }
1102 
1103 static void
1106 {
1107  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1109  int rv = 0;
1110  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1111  default_router;
1112 
1113  is_no = mp->is_no == 1;
1114  suppress = mp->suppress == 1;
1115  managed = mp->managed == 1;
1116  other = mp->other == 1;
1117  ll_option = mp->ll_option == 1;
1118  send_unicast = mp->send_unicast == 1;
1119  cease = mp->cease == 1;
1120  default_router = mp->default_router == 1;
1121 
1122  VALIDATE_SW_IF_INDEX (mp);
1123 
1124  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1125  suppress, managed, other,
1126  ll_option, send_unicast, cease,
1127  default_router, ntohl (mp->lifetime),
1128  ntohl (mp->initial_count),
1129  ntohl (mp->initial_interval),
1130  ntohl (mp->max_interval),
1131  ntohl (mp->min_interval), is_no);
1132 
1134 
1135  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1136 }
1137 
1138 static void
1141 {
1143  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1144  fib_prefix_t pfx;
1145  int rv = 0;
1146  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1147 
1148  VALIDATE_SW_IF_INDEX (mp);
1149 
1150  ip_prefix_decode (&mp->prefix, &pfx);
1151  is_no = mp->is_no == 1;
1152  use_default = mp->use_default == 1;
1153  no_advertise = mp->no_advertise == 1;
1154  off_link = mp->off_link == 1;
1155  no_autoconfig = mp->no_autoconfig == 1;
1156  no_onlink = mp->no_onlink == 1;
1157 
1158  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1159  &pfx.fp_addr.ip6,
1160  pfx.fp_len, use_default,
1161  ntohl (mp->val_lifetime),
1162  ntohl (mp->pref_lifetime), no_advertise,
1163  off_link, no_autoconfig, no_onlink, is_no);
1164 
1166  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1167 }
1168 
1169 static void
1171  u32 context,
1172  const ip46_address_t * addr, u32 sw_if_index)
1173 {
1175 
1176  mp = vl_msg_api_alloc (sizeof (*mp));
1177  clib_memset (mp, 0, sizeof (*mp));
1178  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1179  mp->context = context;
1180  mp->sw_if_index = htonl (sw_if_index);
1181 
1182  ip6_address_encode (&addr->ip6, mp->ip);
1183 
1184  vl_api_send_msg (reg, (u8 *) mp);
1185 }
1186 
1188 {
1191 
1192 static fib_table_walk_rc_t
1194 {
1196 
1198  {
1199  vec_add1 (ctx->indices, fei);
1200  }
1201 
1202  return (FIB_TABLE_WALK_CONTINUE);
1203 }
1204 
1205 static void
1207 {
1208  ip6_main_t *im6 = &ip6_main;
1209  fib_table_t *fib_table;
1211  .indices = NULL,
1212  };
1213  fib_node_index_t *feip;
1214  const fib_prefix_t *pfx;
1215  vl_api_registration_t *reg;
1216 
1218  if (!reg)
1219  return;
1220 
1221  /* *INDENT-OFF* */
1222  pool_foreach (fib_table, im6->fibs,
1223  ({
1224  fib_table_walk(fib_table->ft_index,
1225  FIB_PROTOCOL_IP6,
1226  api_ip6nd_proxy_fib_table_walk,
1227  &ctx);
1228  }));
1229  /* *INDENT-ON* */
1230 
1232 
1233  vec_foreach (feip, ctx.indices)
1234  {
1235  pfx = fib_entry_get_prefix (*feip);
1236 
1238  mp->context,
1239  &pfx->fp_addr,
1241  }
1242 
1243  vec_free (ctx.indices);
1244 }
1245 
1246 static void
1248 {
1249  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1250  ip6_address_t ip6;
1251  int rv = 0;
1252 
1253  VALIDATE_SW_IF_INDEX (mp);
1254 
1255  ip6_address_decode (mp->ip, &ip6);
1256  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index), &ip6, mp->is_del);
1257 
1259  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1260 }
1261 
1262 static void
1265 {
1266  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
1269  int rv = 0;
1270 
1271  VALIDATE_SW_IF_INDEX (mp);
1272 
1274  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);
1275 
1276  if (rv != 0)
1277  return;
1278 
1279  params.irt = ntohl (mp->irt);
1280  params.mrt = ntohl (mp->mrt);
1281  params.mrc = ntohl (mp->mrc);
1282  params.mrd = ntohl (mp->mrd);
1283 
1284  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
1285  &params);
1286 }
1287 
1288 static void
1291 {
1293  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1294  vnet_main_t *vnm = vnet_get_main ();
1295  int rv = 0;
1296  clib_error_t *error;
1297 
1298  vnm->api_errno = 0;
1299 
1300  VALIDATE_SW_IF_INDEX (mp);
1301 
1302  error =
1303  (mp->enable == 1) ? enable_ip6_interface (vm,
1304  ntohl (mp->sw_if_index)) :
1305  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1306 
1307  if (error)
1308  {
1309  clib_error_report (error);
1310  rv = VNET_API_ERROR_UNSPECIFIED;
1311  }
1312  else
1313  {
1314  rv = vnm->api_errno;
1315  }
1316 
1318 
1319  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1320 }
1321 
1322 void
1324  u32 context, const mfib_signal_t * mfs)
1325 {
1327  const mfib_prefix_t *prefix;
1328  mfib_table_t *mfib;
1329  mfib_itf_t *mfi;
1330 
1331  mp = vl_msg_api_alloc (sizeof (*mp));
1332 
1333  clib_memset (mp, 0, sizeof (*mp));
1334  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1335  mp->context = context;
1336 
1337  mfi = mfib_itf_get (mfs->mfs_itf);
1338  prefix = mfib_entry_get_prefix (mfs->mfs_entry);
1340  prefix->fp_proto);
1341  mp->table_id = ntohl (mfib->mft_table_id);
1342  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1343 
1344  ip_mprefix_encode (prefix, &mp->prefix);
1345 
1346  if (0 != mfs->mfs_buffer_len)
1347  {
1348  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1349 
1350  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1351  }
1352  else
1353  {
1354  mp->ip_packet_len = 0;
1355  }
1356 
1357  vl_api_send_msg (reg, (u8 *) mp);
1358 }
1359 
1360 static void
1362 {
1363  vl_api_registration_t *reg;
1364 
1366  if (!reg)
1367  return;
1368 
1369  while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
1370  ;
1371 }
1372 
1373 static void
1376 {
1377  vl_api_ip_container_proxy_add_del_reply_t *rmp;
1379  int rv = 0;
1380  clib_error_t *error;
1381 
1382  clib_memset (&args, 0, sizeof (args));
1383 
1384  ip_prefix_decode (&mp->pfx, &args.prefix);
1385 
1386  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
1387  args.is_add = mp->is_add;
1388  if ((error = vnet_ip_container_proxy_add_del (&args)))
1389  {
1390  rv = clib_error_get_code (error);
1391  clib_error_report (error);
1392  }
1393 
1394  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
1395 }
1396 
1398 {
1402 
1403 static int
1405  void *args)
1406 {
1409 
1410  mp = vl_msg_api_alloc (sizeof (*mp));
1411  if (!mp)
1412  return 1;
1413 
1414  clib_memset (mp, 0, sizeof (*mp));
1415  mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS);
1416  mp->context = ctx->context;
1417 
1418  mp->sw_if_index = ntohl (sw_if_index);
1419  ip_prefix_encode (pfx, &mp->prefix);
1420 
1421  vl_api_send_msg (ctx->reg, (u8 *) mp);
1422 
1423  return 1;
1424 }
1425 
1426 static void
1428  mp)
1429 {
1430  vl_api_registration_t *reg;
1431 
1433  if (!reg)
1434  return;
1435 
1437  .context = mp->context,
1438  .reg = reg,
1439  };
1440 
1442 }
1443 
1444 static void
1446 {
1447  int rv = 0;
1448  vl_api_ioam_enable_reply_t *rmp;
1449  clib_error_t *error;
1450 
1451  /* Ignoring the profile id as currently a single profile
1452  * is supported */
1453  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
1454  mp->seqno, mp->analyse);
1455  if (error)
1456  {
1457  clib_error_report (error);
1458  rv = clib_error_get_code (error);
1459  }
1460 
1461  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
1462 }
1463 
1464 static void
1466 {
1467  int rv = 0;
1468  vl_api_ioam_disable_reply_t *rmp;
1469  clib_error_t *error;
1470 
1471  error = clear_ioam_rewrite_fn ();
1472  if (error)
1473  {
1474  clib_error_report (error);
1475  rv = clib_error_get_code (error);
1476  }
1477 
1478  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
1479 }
1480 
1481 static void
1484 {
1485  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
1486  int rv = 0;
1487 
1488  u8 is_add = mp->is_add;
1489  fib_prefix_t pfx;
1490  u16 *low_ports = 0;
1491  u16 *high_ports = 0;
1492  u32 vrf_id;
1493  u16 tmp_low, tmp_high;
1494  u8 num_ranges;
1495  int i;
1496 
1497  ip_prefix_decode (&mp->prefix, &pfx);
1498 
1499  // Validate port range
1500  num_ranges = mp->number_of_ranges;
1501  if (num_ranges > 32)
1502  { // This is size of array in VPE.API
1503  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1504  goto reply;
1505  }
1506 
1507  vec_reset_length (low_ports);
1508  vec_reset_length (high_ports);
1509 
1510  for (i = 0; i < num_ranges; i++)
1511  {
1512  tmp_low = mp->low_ports[i];
1513  tmp_high = mp->high_ports[i];
1514  // If tmp_low <= tmp_high then only need to check tmp_low = 0
1515  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
1516  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
1517  {
1518  rv = VNET_API_ERROR_INVALID_VALUE;
1519  goto reply;
1520  }
1521  vec_add1 (low_ports, tmp_low);
1522  vec_add1 (high_ports, tmp_high + 1);
1523  }
1524 
1525  vrf_id = ntohl (mp->vrf_id);
1526 
1527  if (vrf_id < 1)
1528  {
1529  rv = VNET_API_ERROR_INVALID_VALUE;
1530  goto reply;
1531  }
1532 
1533 
1534  if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
1535  {
1537  pfx.fp_len,
1538  vrf_id,
1539  low_ports,
1540  high_ports, is_add);
1541  }
1542  else
1543  {
1545  pfx.fp_len,
1546  vrf_id,
1547  low_ports,
1548  high_ports, is_add);
1549  }
1550 
1551 reply:
1552  vec_free (low_ports);
1553  vec_free (high_ports);
1554  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
1555 }
1556 
1557 static void
1560 {
1562  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
1563  ip4_main_t *im = &ip4_main;
1564  int rv;
1565  u32 sw_if_index;
1568  uword *p = 0;
1569  int i;
1570 
1572  ntohl (mp->tcp_out_vrf_id);
1574  ntohl (mp->udp_out_vrf_id);
1576  ntohl (mp->tcp_in_vrf_id);
1578  ntohl (mp->udp_in_vrf_id);
1579 
1580 
1581  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
1582  {
1583  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
1584  {
1585  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
1586 
1587  if (p == 0)
1588  {
1589  rv = VNET_API_ERROR_INVALID_VALUE;
1590  goto reply;
1591  }
1592 
1593  fib_index[i] = p[0];
1594  }
1595  else
1596  fib_index[i] = ~0;
1597  }
1598  sw_if_index = ntohl (mp->sw_if_index);
1599 
1600  VALIDATE_SW_IF_INDEX (mp);
1601 
1602  rv =
1603  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
1604  mp->is_add);
1605 
1607 reply:
1608 
1609  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
1610 }
1611 
1612 typedef union
1613 {
1614  u32 fib_index;
1616 
1617 static void
1620 {
1621  vl_api_ip_source_check_interface_add_del_reply_t *rmp;
1622  int rv;
1623  u32 sw_if_index = ntohl (mp->sw_if_index);
1624  u8 is_add = mp->is_add;
1625  char *feature_name =
1626  mp->loose ? "ip4-source-check-via-any" : "ip4-source-check-via-rx";
1627 
1629 
1630  VALIDATE_SW_IF_INDEX (mp);
1631 
1632  config.fib_index =
1634  rv =
1635  vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index,
1636  is_add, &config, sizeof (config));
1638 
1639  REPLY_MACRO (VL_API_IP_SOURCE_CHECK_INTERFACE_ADD_DEL_REPLY);
1640 }
1641 
1642 #define IP4_ARP_EVENT 3
1643 #define IP6_ND_EVENT 4
1644 
1646 
1647 static int
1649  const mac_address_t * mac,
1651 {
1653 
1654  if (pool_is_free_index (am->arp_events, pool_index))
1655  return 1;
1656 
1657  pool_put_index (am->arp_events, pool_index);
1658  return 0;
1659 }
1660 
1661 static void
1663 {
1664  vpe_api_main_t *vam = &vpe_api_main;
1665  vnet_main_t *vnm = vam->vnet_main;
1666  vlib_main_t *vm = vam->vlib_main;
1667  vl_api_ip4_arp_event_t *event;
1669  vl_api_registration_t *reg;
1670 
1671  /* Client can cancel, die, etc. */
1672  if (pool_is_free_index (vam->arp_events, pool_index))
1673  return;
1674 
1675  event = pool_elt_at_index (vam->arp_events, pool_index);
1676 
1678  if (!reg)
1679  {
1682  event->pid, event->ip,
1683  ip_resolver_process_node.index, IP4_ARP_EVENT,
1684  ~0 /* pool index, notused */ , 0 /* is_add */ );
1685  return;
1686  }
1687 
1688  if (vl_api_can_send_msg (reg))
1689  {
1690  mp = vl_msg_api_alloc (sizeof (*mp));
1691  clib_memcpy (mp, event, sizeof (*mp));
1692  vl_api_send_msg (reg, (u8 *) mp);
1693  }
1694  else
1695  {
1696  static f64 last_time;
1697  /*
1698  * Throttle syslog msgs.
1699  * It's pretty tempting to just revoke the registration...
1700  */
1701  if (vlib_time_now (vm) > last_time + 10.0)
1702  {
1703  clib_warning ("arp event for %U to pid %d: queue stuffed!",
1704  format_ip4_address, event->ip, event->pid);
1705  last_time = vlib_time_now (vm);
1706  }
1707  }
1708 }
1709 
1710 static int
1712  const mac_address_t * mac,
1713  u32 sw_if_index, const ip6_address_t * addr)
1714 {
1716 
1717  if (pool_is_free_index (am->nd_events, pool_index))
1718  return 1;
1719 
1720  pool_put_index (am->nd_events, pool_index);
1721  return 0;
1722 }
1723 
1724 static void
1726 {
1727  vpe_api_main_t *vam = &vpe_api_main;
1728  vnet_main_t *vnm = vam->vnet_main;
1729  vlib_main_t *vm = vam->vlib_main;
1730  vl_api_ip6_nd_event_t *event;
1732  vl_api_registration_t *reg;
1733 
1734  /* Client can cancel, die, etc. */
1735  if (pool_is_free_index (vam->nd_events, pool_index))
1736  return;
1737 
1738  event = pool_elt_at_index (vam->nd_events, pool_index);
1739 
1741  if (!reg)
1742  {
1745  event->pid, event->ip,
1746  ip_resolver_process_node.index, IP6_ND_EVENT,
1747  ~0 /* pool index, notused */ , 0 /* is_add */ );
1748  return;
1749  }
1750 
1751  if (vl_api_can_send_msg (reg))
1752  {
1753  mp = vl_msg_api_alloc (sizeof (*mp));
1754  clib_memcpy (mp, event, sizeof (*mp));
1755  vl_api_send_msg (reg, (u8 *) mp);
1756  }
1757  else
1758  {
1759  static f64 last_time;
1760  /*
1761  * Throttle syslog msgs.
1762  * It's pretty tempting to just revoke the registration...
1763  */
1764  if (vlib_time_now (vm) > last_time + 10.0)
1765  {
1766  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
1767  format_ip6_address, event->ip, event->pid);
1768  last_time = vlib_time_now (vm);
1769  }
1770  }
1771 }
1772 
1773 static uword
1776 {
1777  volatile f64 timeout = 100.0;
1778  volatile uword *event_data = 0;
1779 
1780  while (1)
1781  {
1783 
1784  uword event_type =
1785  vlib_process_get_events (vm, (uword **) & event_data);
1786 
1787  int i;
1788  switch (event_type)
1789  {
1790  case IP4_ARP_EVENT:
1791  for (i = 0; i < vec_len (event_data); i++)
1792  handle_ip4_arp_event (event_data[i]);
1793  break;
1794 
1795  case IP6_ND_EVENT:
1796  for (i = 0; i < vec_len (event_data); i++)
1797  handle_ip6_nd_event (event_data[i]);
1798  break;
1799 
1800  case ~0: /* timeout */
1801  break;
1802  }
1803 
1804  vec_reset_length (event_data);
1805  }
1806  return 0; /* or not */
1807 }
1808 
1809 /* *INDENT-OFF* */
1810 VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
1811  .function = resolver_process,
1812  .type = VLIB_NODE_TYPE_PROCESS,
1813  .name = "ip-route-resolver-process",
1814 };
1815 /* *INDENT-ON* */
1816 
1817 static int
1818 nd_change_data_callback (u32 pool_index, const mac_address_t * new_mac,
1820 {
1822  vl_api_ip6_nd_event_t *event;
1823 
1824  if (pool_is_free_index (am->nd_events, pool_index))
1825  return 1;
1826 
1827  event = pool_elt_at_index (am->nd_events, pool_index);
1828  if (ethernet_mac_address_equal (event->mac, new_mac->bytes) &&
1829  sw_if_index == ntohl (event->sw_if_index))
1830  {
1831  return 1;
1832  }
1833 
1834  mac_address_encode (new_mac, event->mac);
1835  event->sw_if_index = htonl (sw_if_index);
1836  return 0;
1837 }
1838 
1840 
1841 enum
1843 
1844 static uword
1846 {
1847  /* These cross the longjmp boundary (vlib_process_wait_for_event)
1848  * and need to be volatile - to prevent them from being optimized into
1849  * a register - which could change during suspension */
1850 
1851  volatile wc_arp_report_t arp_prev = { 0 };
1852  volatile wc_nd_report_t nd_prev = { 0 };
1853  volatile f64 last_arp = vlib_time_now (vm);
1854  volatile f64 last_nd = vlib_time_now (vm);
1855 
1856  while (1)
1857  {
1859  uword event_type = WC_ARP_REPORT;
1860  void *event_data = vlib_process_get_event_data (vm, &event_type);
1861 
1862  f64 now = vlib_time_now (vm);
1863  int i;
1864  if (event_type == WC_ARP_REPORT)
1865  {
1866  wc_arp_report_t *arp_events = event_data;
1867  for (i = 0; i < vec_len (arp_events); i++)
1868  {
1869  /* discard dup event - cast away volatile */
1870  if (arp_prev.ip.as_u32 == arp_events[i].ip.as_u32 &&
1871  mac_address_equal ((const mac_address_t *) &arp_prev.mac,
1872  &arp_events[i].mac) &&
1873  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
1874  (now - last_arp) < 10.0)
1875  {
1876  continue;
1877  }
1878  arp_prev = arp_events[i];
1879  last_arp = now;
1881  /* *INDENT-OFF* */
1882  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
1883  ({
1884  vl_api_registration_t *vl_reg;
1885  vl_reg = vl_api_client_index_to_registration (reg->client_index);
1886  ASSERT (vl_reg != NULL);
1887  if (reg && vl_api_can_send_msg (vl_reg))
1888  {
1889  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
1890  clib_memset (event, 0, sizeof *event);
1891  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
1892  event->client_index = reg->client_index;
1893  event->pid = reg->client_pid;
1894  event->mac_ip = 1;
1895  ip4_address_encode(&arp_events[i].ip, event->ip);
1896  event->sw_if_index = htonl(arp_events[i].sw_if_index);
1897  mac_address_encode(&arp_events[i].mac, event->mac);
1898  vl_api_send_msg (vl_reg, (u8 *) event);
1899  }
1900  }));
1901  /* *INDENT-ON* */
1902  }
1903  }
1904  else if (event_type == WC_ND_REPORT)
1905  {
1906  wc_nd_report_t *nd_events = event_data;
1907  for (i = 0; i < vec_len (nd_events); i++)
1908  {
1909  /* discard dup event - cast away volatile */
1910  if (ip6_address_is_equal ((const ip6_address_t *) &nd_prev.ip6,
1911  &nd_events[i].ip6)
1912  && mac_address_equal ((const mac_address_t *) &nd_prev.mac,
1913  &nd_events[i].mac)
1914  && nd_prev.sw_if_index == nd_events[i].sw_if_index
1915  && (now - last_nd) < 10.0)
1916  {
1917  continue;
1918  }
1919  nd_prev = nd_events[i];
1920  last_nd = now;
1922  /* *INDENT-OFF* */
1923  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
1924  ({
1925  vl_api_registration_t *vl_reg;
1926  vl_reg = vl_api_client_index_to_registration (reg->client_index);
1927  if (vl_reg && vl_api_can_send_msg (vl_reg))
1928  {
1929  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
1930  clib_memset (event, 0, sizeof *event);
1931  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
1932  event->client_index = reg->client_index;
1933  event->pid = reg->client_pid;
1934  event->mac_ip = 1;
1935  ip6_address_encode(&nd_events[i].ip6, event->ip);
1936  event->sw_if_index = htonl(nd_events[i].sw_if_index);
1937  mac_address_encode(&nd_events[i].mac, event->mac);
1938  vl_api_send_msg (vl_reg, (u8 *) event);
1939  }
1940  }));
1941  /* *INDENT-ON* */
1942  }
1943  }
1944  else if (event_type == RA_REPORT)
1945  {
1946  ra_report_t *ra_events = event_data;
1947  for (i = 0; i < vec_len (ra_events); i++)
1948  {
1950  call_ip6_neighbor_callbacks (&ra_events[i],
1951  npm->ra_report_functions);
1952 
1954  /* *INDENT-OFF* */
1955  pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
1956  ({
1957  vl_api_registration_t *vl_reg;
1958  vl_reg =
1959  vl_api_client_index_to_registration (reg->client_index);
1960  if (vl_reg && vl_api_can_send_msg (vl_reg))
1961  {
1962  u32 event_size =
1963  sizeof (vl_api_ip6_ra_event_t) +
1964  vec_len (ra_events[i].prefixes) *
1965  sizeof (vl_api_ip6_ra_prefix_info_t);
1966  vl_api_ip6_ra_event_t *event =
1967  vl_msg_api_alloc (event_size);
1968  clib_memset (event, 0, event_size);
1969  event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT);
1970  event->client_index = reg->client_index;
1971  event->pid = reg->client_pid;
1972 
1973  event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);
1974 
1975  ip6_address_encode (&ra_events[i].router_address,
1976  event->router_addr);
1977 
1978  event->current_hop_limit = ra_events[i].current_hop_limit;
1979  event->flags = ra_events[i].flags;
1980  event->router_lifetime_in_sec =
1981  clib_host_to_net_u16 (ra_events
1982  [i].router_lifetime_in_sec);
1983  event->neighbor_reachable_time_in_msec =
1984  clib_host_to_net_u32 (ra_events
1985  [i].neighbor_reachable_time_in_msec);
1986  event->time_in_msec_between_retransmitted_neighbor_solicitations
1987  =
1988  clib_host_to_net_u32 (ra_events
1989  [i].time_in_msec_between_retransmitted_neighbor_solicitations);
1990 
1991  event->n_prefixes =
1992  clib_host_to_net_u32 (vec_len (ra_events[i].prefixes));
1993  vl_api_ip6_ra_prefix_info_t *prefix =
1994  (typeof (prefix)) event->prefixes;
1995  u32 j;
1996  for (j = 0; j < vec_len (ra_events[i].prefixes); j++)
1997  {
1998  ra_report_prefix_info_t *info =
1999  &ra_events[i].prefixes[j];
2000  ip_prefix_encode(&info->prefix, &prefix->prefix);
2001  prefix->flags = info->flags;
2002  prefix->valid_time =
2003  clib_host_to_net_u32 (info->valid_time);
2004  prefix->preferred_time =
2005  clib_host_to_net_u32 (info->preferred_time);
2006  prefix++;
2007  }
2008 
2009  vl_api_send_msg (vl_reg, (u8 *) event);
2010  }
2011  }));
2012  /* *INDENT-ON* */
2013  vec_free (ra_events[i].prefixes);
2014  }
2015  }
2016  vlib_process_put_event_data (vm, event_data);
2017  }
2018 
2019  return 0;
2020 }
2021 
2022 /* *INDENT-OFF* */
2024  .function = wc_arp_process,
2025  .type = VLIB_NODE_TYPE_PROCESS,
2026  .name = "wildcard-ip4-arp-publisher-process",
2027 };
2028 /* *INDENT-ON* */
2029 
2030 static int
2032  const mac_address_t * mac,
2034 {
2036  vl_api_ip4_arp_event_t *event;
2037 
2038  if (pool_is_free_index (am->arp_events, pool_index))
2039  return 1;
2040 
2041  event = pool_elt_at_index (am->arp_events, pool_index);
2042  if (ethernet_mac_address_equal (event->mac, mac->bytes) &&
2043  sw_if_index == ntohl (event->sw_if_index))
2044  {
2045  return 1;
2046  }
2047 
2048  mac_address_encode (mac, event->mac);
2049  event->sw_if_index = htonl (sw_if_index);
2050  return 0;
2051 }
2052 
2053 static void
2055 {
2057  vnet_main_t *vnm = vnet_get_main ();
2058  vl_api_want_ip4_arp_events_reply_t *rmp;
2059  ip4_address_t ip;
2060  int rv = 0;
2061 
2062  ip4_address_decode (mp->ip, &ip);
2063 
2064  if (ip.as_u32 == 0)
2065  {
2066  uword *p =
2067  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
2069  if (p)
2070  {
2071  if (mp->enable_disable)
2072  {
2073  clib_warning ("pid %d: already enabled...", mp->pid);
2074  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2075  goto reply;
2076  }
2077  else
2078  {
2079  rp =
2080  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2081  pool_put (am->wc_ip4_arp_events_registrations, rp);
2082  hash_unset (am->wc_ip4_arp_events_registration_hash,
2083  mp->client_index);
2084  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2086  goto reply;
2087  }
2088  }
2089  if (mp->enable_disable == 0)
2090  {
2091  clib_warning ("pid %d: already disabled...", mp->pid);
2092  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2093  goto reply;
2094  }
2095  pool_get (am->wc_ip4_arp_events_registrations, rp);
2096  rp->client_index = mp->client_index;
2097  rp->client_pid = mp->pid;
2098  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
2099  rp - am->wc_ip4_arp_events_registrations);
2101  goto reply;
2102  }
2103 
2104  if (mp->enable_disable)
2105  {
2106  vl_api_ip4_arp_event_t *event;
2107  pool_get (am->arp_events, event);
2110  mp->pid, mp->ip /* addr, in net byte order */ ,
2112  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2113 
2114  if (rv)
2115  {
2116  pool_put (am->arp_events, event);
2117  goto reply;
2118  }
2119  clib_memset (event, 0, sizeof (*event));
2120 
2121  /* Python API expects events to have no context */
2122  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2123  event->client_index = mp->client_index;
2124  memcpy (event->ip, mp->ip, 4);
2125  event->pid = mp->pid;
2126  if (ip.as_u32 == 0)
2127  event->mac_ip = 1;
2128  }
2129  else
2130  {
2133  mp->pid, mp->ip /* addr, in net byte order */ ,
2135  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2136  }
2137 reply:
2138  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2139 }
2140 
2141 static clib_error_t *
2143 {
2145  vl_api_ip4_arp_event_t *event;
2146  u32 *to_delete, *event_id;
2147  vpe_api_main_t *am;
2148  vnet_main_t *vnm;
2149  uword *p;
2150 
2151  am = &vpe_api_main;
2152  vnm = vnet_get_main ();
2153  to_delete = NULL;
2154 
2155  /* clear out all of its pending resolutions */
2156  /* *INDENT-OFF* */
2157  pool_foreach(event, am->arp_events,
2158  ({
2159  if (event->client_index == client_index)
2160  {
2161  vec_add1(to_delete, event - am->arp_events);
2162  }
2163  }));
2164  /* *INDENT-ON* */
2165 
2166  vec_foreach (event_id, to_delete)
2167  {
2168  event = pool_elt_at_index (am->arp_events, *event_id);
2171  event->pid, event->ip,
2173  ~0 /* pool index, notused */ , 0 /* is_add */ );
2174  }
2175  vec_free (to_delete);
2176 
2177  /* remove from the registration hash */
2178  p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index);
2179 
2180  if (p)
2181  {
2182  rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2183  pool_put (am->wc_ip4_arp_events_registrations, rp);
2184  hash_unset (am->wc_ip4_arp_events_registration_hash, client_index);
2185  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2187  }
2188  return (NULL);
2189 }
2190 
2192 
2193 static void
2195 {
2197  vnet_main_t *vnm = vnet_get_main ();
2198  vl_api_want_ip6_nd_events_reply_t *rmp;
2199  ip6_address_t ip6;
2200  int rv = 0;
2201 
2202  ip6_address_decode (mp->ip, &ip6);
2203 
2204  if (ip6_address_is_zero (&ip6))
2205  {
2206  uword *p =
2207  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
2209  if (p)
2210  {
2211  if (mp->enable_disable)
2212  {
2213  clib_warning ("pid %d: already enabled...", mp->pid);
2214  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2215  goto reply;
2216  }
2217  else
2218  {
2219  rp =
2220  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2221  pool_put (am->wc_ip6_nd_events_registrations, rp);
2222  hash_unset (am->wc_ip6_nd_events_registration_hash,
2223  mp->client_index);
2224  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2226  goto reply;
2227  }
2228  }
2229  if (mp->enable_disable == 0)
2230  {
2231  clib_warning ("pid %d: already disabled...", mp->pid);
2232  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2233  goto reply;
2234  }
2235  pool_get (am->wc_ip6_nd_events_registrations, rp);
2236  rp->client_index = mp->client_index;
2237  rp->client_pid = mp->pid;
2238  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
2239  rp - am->wc_ip6_nd_events_registrations);
2241  goto reply;
2242  }
2243 
2244  if (mp->enable_disable)
2245  {
2246  vl_api_ip6_nd_event_t *event;
2247  pool_get (am->nd_events, event);
2248 
2251  mp->pid, &ip6,
2253  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
2254 
2255  if (rv)
2256  {
2257  pool_put (am->nd_events, event);
2258  goto reply;
2259  }
2260  clib_memset (event, 0, sizeof (*event));
2261 
2262  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2263  event->client_index = mp->client_index;
2264  ip6_address_encode (&ip6, event->ip);
2265  event->pid = mp->pid;
2266  }
2267  else
2268  {
2271  mp->pid, &ip6 /* addr, in net byte order */ ,
2273  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2274  }
2275 reply:
2276  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
2277 }
2278 
2279 static clib_error_t *
2281 {
2282 
2284  vl_api_ip6_nd_event_t *event;
2285  u32 *to_delete, *event_id;
2286  vpe_api_main_t *am;
2287  vnet_main_t *vnm;
2288  uword *p;
2289 
2290  am = &vpe_api_main;
2291  vnm = vnet_get_main ();
2292  to_delete = NULL;
2293 
2294  /* clear out all of its pending resolutions */
2295  /* *INDENT-OFF* */
2296  pool_foreach(event, am->nd_events,
2297  ({
2298  if (event->client_index == client_index)
2299  {
2300  vec_add1(to_delete, event - am->nd_events);
2301  }
2302  }));
2303  /* *INDENT-ON* */
2304 
2305  vec_foreach (event_id, to_delete)
2306  {
2307  event = pool_elt_at_index (am->nd_events, *event_id);
2310  event->pid, event->ip,
2312  ~0 /* pool index, notused */ , 0 /* is_add */ );
2313  }
2314  vec_free (to_delete);
2315 
2316  /* remove from the registration hash */
2317  p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index);
2318 
2319  if (p)
2320  {
2321  rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2322  pool_put (am->wc_ip6_nd_events_registrations, rp);
2323  hash_unset (am->wc_ip6_nd_events_registration_hash, client_index);
2324  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2326  }
2327  return (NULL);
2328 }
2329 
2331 
2332 static void
2334 {
2336  vl_api_want_ip6_ra_events_reply_t *rmp;
2337  int rv = 0;
2338 
2339  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
2341  if (p)
2342  {
2343  if (mp->enable_disable)
2344  {
2345  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
2346  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2347  goto reply;
2348  }
2349  else
2350  {
2351  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2352  pool_put (am->ip6_ra_events_registrations, rp);
2353  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
2354  goto reply;
2355  }
2356  }
2357  if (mp->enable_disable == 0)
2358  {
2359  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
2360  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2361  goto reply;
2362  }
2363  pool_get (am->ip6_ra_events_registrations, rp);
2364  rp->client_index = mp->client_index;
2365  rp->client_pid = ntohl (mp->pid);
2366  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
2367  rp - am->ip6_ra_events_registrations);
2368 
2369 reply:
2370  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
2371 }
2372 
2373 static clib_error_t *
2375 {
2378  uword *p;
2379 
2380  p = hash_get (am->ip6_ra_events_registration_hash, client_index);
2381 
2382  if (p)
2383  {
2384  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2385  pool_put (am->ip6_ra_events_registrations, rp);
2386  hash_unset (am->ip6_ra_events_registration_hash, client_index);
2387  }
2388  return (NULL);
2389 }
2390 
2392 
2393 static void
2395 {
2396  vl_api_proxy_arp_add_del_reply_t *rmp;
2397  ip4_address_t lo, hi;
2398  u32 fib_index;
2399  int rv;
2400 
2401  fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->proxy.table_id));
2402 
2403  if (~0 == fib_index)
2404  {
2405  rv = VNET_API_ERROR_NO_SUCH_FIB;
2406  goto out;
2407  }
2408 
2409  ip4_address_decode (mp->proxy.low, &lo);
2410  ip4_address_decode (mp->proxy.hi, &hi);
2411 
2412  rv = vnet_proxy_arp_add_del (&lo, &hi, fib_index, mp->is_add == 0);
2413 
2414 out:
2415  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2416 }
2417 
2419 {
2423 
2424 static walk_rc_t
2426  const ip4_address_t * hi_addr,
2427  u32 fib_index, void *data)
2428 {
2431 
2432  ctx = data;
2433 
2434  mp = vl_msg_api_alloc (sizeof (*mp));
2435  clib_memset (mp, 0, sizeof (*mp));
2436  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
2437  mp->context = ctx->context;
2438  mp->proxy.table_id = htonl (fib_index);
2439 
2440  ip4_address_encode (lo_addr, mp->proxy.low);
2441  ip4_address_encode (hi_addr, mp->proxy.hi);
2442 
2443  vl_api_send_msg (ctx->reg, (u8 *) mp);
2444 
2445  return (WALK_CONTINUE);
2446 }
2447 
2448 static void
2450 {
2451  vl_api_registration_t *reg;
2452 
2454  if (!reg)
2455  return;
2456 
2457  proxy_arp_walk_ctx_t wctx = {
2458  .reg = reg,
2459  .context = mp->context,
2460  };
2461 
2463 }
2464 
2465 static walk_rc_t
2467 {
2470 
2471  ctx = data;
2472 
2473  mp = vl_msg_api_alloc (sizeof (*mp));
2474  clib_memset (mp, 0, sizeof (*mp));
2475  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS);
2476  mp->context = ctx->context;
2477  mp->sw_if_index = htonl (sw_if_index);
2478 
2479  vl_api_send_msg (ctx->reg, (u8 *) mp);
2480 
2481  return (WALK_CONTINUE);
2482 }
2483 
2484 static void
2486 {
2487  vl_api_registration_t *reg;
2488 
2490  if (!reg)
2491  return;
2492 
2493  proxy_arp_walk_ctx_t wctx = {
2494  .reg = reg,
2495  .context = mp->context,
2496  };
2497 
2499 }
2500 
2501 static void
2504 {
2505  int rv = 0;
2506  vnet_main_t *vnm = vnet_get_main ();
2507  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2508 
2509  VALIDATE_SW_IF_INDEX (mp);
2510 
2512  ntohl (mp->sw_if_index),
2513  mp->enable_disable);
2514 
2516 
2517  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2518 }
2519 
2520 static void
2522 {
2523  int rv = 0;
2525  vl_api_ip_probe_neighbor_reply_t *rmp;
2526  clib_error_t *error;
2527  ip46_address_t dst;
2528  ip46_type_t itype;
2529 
2530  VALIDATE_SW_IF_INDEX (mp);
2531 
2532  u32 sw_if_index = ntohl (mp->sw_if_index);
2533  itype = ip_address_decode (&mp->dst, &dst);
2534 
2535  if (IP46_TYPE_IP6 == itype)
2536  error = ip6_probe_neighbor (vm, &dst.ip6, sw_if_index, 0);
2537  else
2538  error = ip4_probe_neighbor (vm, &dst.ip4, sw_if_index, 0);
2539 
2540  if (error)
2541  {
2542  clib_error_report (error);
2543  rv = clib_error_get_code (error);
2544  }
2545 
2547 
2548  REPLY_MACRO (VL_API_IP_PROBE_NEIGHBOR_REPLY);
2549 }
2550 
2551 static void
2554 {
2555  int rv = 0;
2556  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
2558 
2559  arg.mode = mp->mode;
2560  arg.scan_interval = mp->scan_interval;
2561  arg.max_proc_time = mp->max_proc_time;
2562  arg.max_update = mp->max_update;
2563  arg.scan_int_delay = mp->scan_int_delay;
2564  arg.stale_threshold = mp->stale_threshold;
2566 
2567  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
2568 }
2569 
2570 static int
2572 {
2573  vnet_main_t *vnm = vnet_get_main ();
2575  ip4_main_t *im4 = &ip4_main;
2576  static u32 *sw_if_indices_to_shut;
2577  fib_table_t *fib_table;
2578  ip4_fib_t *fib;
2579  u32 sw_if_index;
2580  int i;
2581  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2582  u32 target_fib_id = ntohl (mp->vrf_id);
2583 
2584  /* *INDENT-OFF* */
2585  pool_foreach (fib_table, im4->fibs,
2586  ({
2587  vnet_sw_interface_t * si;
2588 
2589  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
2590 
2591  if (fib->table_id != target_fib_id)
2592  continue;
2593 
2594  /* remove any mpls encap/decap labels */
2595  mpls_fib_reset_labels (fib->table_id);
2596 
2597  /* remove any proxy arps in this fib */
2598  vnet_proxy_arp_fib_reset (fib->table_id);
2599 
2600  /* Set the flow hash for this fib to the default */
2601  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2602 
2603  vec_reset_length (sw_if_indices_to_shut);
2604 
2605  /* Shut down interfaces in this FIB / clean out intfc routes */
2606  pool_foreach (si, im->sw_interfaces,
2607  ({
2608  u32 sw_if_index = si->sw_if_index;
2609 
2610  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2611  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2612  fib->index))
2613  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2614  }));
2615 
2616  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2617  sw_if_index = sw_if_indices_to_shut[i];
2618 
2619  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2620  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2621  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2622  }
2623 
2625 
2626  rv = 0;
2627  break;
2628  })); /* pool_foreach (fib) */
2629  /* *INDENT-ON* */
2630 
2631  return rv;
2632 }
2633 
2634 static int
2636 {
2637  vnet_main_t *vnm = vnet_get_main ();
2639  ip6_main_t *im6 = &ip6_main;
2640  static u32 *sw_if_indices_to_shut;
2641  fib_table_t *fib_table;
2642  ip6_fib_t *fib;
2643  u32 sw_if_index;
2644  int i;
2645  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2646  u32 target_fib_id = ntohl (mp->vrf_id);
2647 
2648  /* *INDENT-OFF* */
2649  pool_foreach (fib_table, im6->fibs,
2650  ({
2651  vnet_sw_interface_t * si;
2652 
2653  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
2654 
2655  if (fib->table_id != target_fib_id)
2656  continue;
2657 
2658  vec_reset_length (sw_if_indices_to_shut);
2659 
2660  /* Set the flow hash for this fib to the default */
2661  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2662 
2663  /* Shut down interfaces in this FIB / clean out intfc routes */
2664  pool_foreach (si, im->sw_interfaces,
2665  ({
2666  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
2667  fib->index)
2668  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2669  }));
2670 
2671  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2672  sw_if_index = sw_if_indices_to_shut[i];
2673 
2674  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2675  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2676  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2677  }
2678 
2680 
2681  rv = 0;
2682  break;
2683  })); /* pool_foreach (fib) */
2684  /* *INDENT-ON* */
2685 
2686  return rv;
2687 }
2688 
2689 static void
2691 {
2692  int rv;
2693  vl_api_reset_fib_reply_t *rmp;
2694 
2695  if (mp->is_ipv6)
2696  rv = ip6_reset_fib_t_handler (mp);
2697  else
2698  rv = ip4_reset_fib_t_handler (mp);
2699 
2700  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
2701 }
2702 
2703 static void
2705 {
2706  int rv;
2707  vl_api_set_arp_neighbor_limit_reply_t *rmp;
2708  vnet_main_t *vnm = vnet_get_main ();
2709  clib_error_t *error;
2710 
2711  vnm->api_errno = 0;
2712 
2713  if (mp->is_ipv6)
2714  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
2715  else
2716  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
2717 
2718  if (error)
2719  {
2720  clib_error_report (error);
2721  rv = VNET_API_ERROR_UNSPECIFIED;
2722  }
2723  else
2724  {
2725  rv = vnm->api_errno;
2726  }
2727 
2728  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
2729 }
2730 
2731 void
2733 {
2734  vl_api_ip_reassembly_set_reply_t *rmp;
2735  int rv = 0;
2736  if (mp->is_ip6)
2737  {
2738  rv = ip6_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
2739  clib_net_to_host_u32 (mp->max_reassemblies),
2740  clib_net_to_host_u32 (mp->max_reassembly_length),
2741  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
2742  }
2743  else
2744  {
2745  rv = ip4_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
2746  clib_net_to_host_u32 (mp->max_reassemblies),
2747  clib_net_to_host_u32 (mp->max_reassembly_length),
2748  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
2749  }
2750 
2751  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
2752 }
2753 
2754 void
2756 {
2758 
2760  if (rp == 0)
2761  return;
2762 
2763  vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
2764  clib_memset (rmp, 0, sizeof (*rmp));
2765  rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
2766  rmp->context = mp->context;
2767  rmp->retval = 0;
2768  if (mp->is_ip6)
2769  {
2770  rmp->is_ip6 = 1;
2772  &rmp->expire_walk_interval_ms);
2773  }
2774  else
2775  {
2776  rmp->is_ip6 = 0;
2778  &rmp->max_reassembly_length,
2779  &rmp->expire_walk_interval_ms);
2780  }
2781  rmp->timeout_ms = clib_host_to_net_u32 (rmp->timeout_ms);
2782  rmp->max_reassemblies = clib_host_to_net_u32 (rmp->max_reassemblies);
2784  clib_host_to_net_u32 (rmp->expire_walk_interval_ms);
2785  vl_api_send_msg (rp, (u8 *) rmp);
2786 }
2787 
2788 void
2791 {
2792  vl_api_ip_reassembly_enable_disable_reply_t *rmp;
2793  int rv = 0;
2794  rv = ip4_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
2795  mp->enable_ip4);
2796  if (0 == rv)
2797  {
2798  rv = ip6_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
2799  mp->enable_ip6);
2800  }
2801 
2802  REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
2803 }
2804 
2806 {
2810 
2811 static walk_rc_t
2813  const ip_punt_redirect_rx_t * ipr, void *arg)
2814 {
2817  fib_path_encode_ctx_t path_ctx = {
2818  .rpaths = NULL,
2819  };
2820 
2821  mp = vl_msg_api_alloc (sizeof (*mp));
2822  if (!mp)
2823  return (WALK_STOP);;
2824 
2825  clib_memset (mp, 0, sizeof (*mp));
2826  mp->_vl_msg_id = ntohs (VL_API_IP_PUNT_REDIRECT_DETAILS);
2827  mp->context = ctx->context;
2828 
2829  fib_path_list_walk_w_ext (ipr->pl, NULL, fib_path_encode, &path_ctx);
2830 
2831  mp->punt.rx_sw_if_index = htonl (rx_sw_if_index);
2832  mp->punt.tx_sw_if_index = htonl (path_ctx.rpaths[0].frp_sw_if_index);
2833 
2834  ip_address_encode (&path_ctx.rpaths[0].frp_addr,
2835  fib_proto_to_ip46 (ipr->fproto), &mp->punt.nh);
2836 
2837  vl_api_send_msg (ctx->reg, (u8 *) mp);
2838 
2839  vec_free (path_ctx.rpaths);
2840 
2841  return (WALK_CONTINUE);
2842 }
2843 
2844 static void
2846 {
2847  vl_api_registration_t *reg;
2848  fib_protocol_t fproto;
2849 
2851  if (!reg)
2852  return;
2853 
2854  fproto = mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4;
2855 
2857  .reg = reg,
2858  .context = mp->context,
2859  };
2860 
2861  if (~0 != mp->sw_if_index)
2862  {
2863  u32 rx_sw_if_index;
2864  index_t pri;
2865 
2866  rx_sw_if_index = ntohl (mp->sw_if_index);
2867  pri = ip_punt_redirect_find (fproto, rx_sw_if_index);
2868 
2869  if (INDEX_INVALID == pri)
2870  return;
2871 
2872  send_ip_punt_redirect_details (rx_sw_if_index,
2873  ip_punt_redirect_get (pri), &ctx);
2874  }
2875  else
2877 }
2878 
2879 #define vl_msg_name_crc_list
2880 #include <vnet/ip/ip.api.h>
2881 #undef vl_msg_name_crc_list
2882 
2883 static void
2885 {
2886 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
2887  foreach_vl_msg_name_crc_ip;
2888 #undef _
2889 }
2890 
2891 static clib_error_t *
2893 {
2894  api_main_t *am = &api_main;
2895 
2896 #define _(N,n) \
2897  vl_msg_api_set_handlers(VL_API_##N, #n, \
2898  vl_api_##n##_t_handler, \
2899  vl_noop_handler, \
2900  vl_api_##n##_t_endian, \
2901  vl_api_##n##_t_print, \
2902  sizeof(vl_api_##n##_t), 1);
2904 #undef _
2905 
2906  /*
2907  * Mark the route add/del API as MP safe
2908  */
2909  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL] = 1;
2910  am->is_mp_safe[VL_API_IP_ROUTE_ADD_DEL_REPLY] = 1;
2911 
2912  /*
2913  * Set up the (msg_name, crc, message-id) table
2914  */
2916 
2918 
2919  return 0;
2920 }
2921 
2923 
2924 /*
2925  * fd.io coding-style-patch-verification: ON
2926  *
2927  * Local Variables:
2928  * eval: (c-set-style "gnu")
2929  * End:
2930  */
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:182
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:1691
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:2503
Proxy ARP add / del request.
Definition: ip.api:903
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:495
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:1711
#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:1247
#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
static void vl_api_ip_container_proxy_add_del_t_handler(vl_api_ip_container_proxy_add_del_t *mp)
Definition: ip_api.c:1375
int vnet_set_ip4_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip4_forward.c:2805
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:1774
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:2812
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:479
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
vnet_api_error_t ip4_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 max_reassembly_length, u32 expire_walk_interval_ms)
set ip4 reassembly configuration
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:2466
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:2425
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
IPv6 Reassembly.
ip46_type_t fib_proto_to_ip46(fib_protocol_t fproto)
Convert from fib_protocol to ip46_type.
Definition: fib_types.c:287
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:1143
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
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:258
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:967
static void vl_api_send_msg(vl_api_registration_t *rp, u8 *elem)
Definition: api.h:34
#define IP6_ND_EVENT
Definition: ip_api.c:1643
clib_error_t * ip4_set_arp_limit(u32 arp_limit)
Definition: arp.c:1919
ip6_neighbor_t * ip6_neighbors_entries(u32 sw_if_index)
Definition: ip6_neighbor.c:985
IPv4 Reassembly.
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
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:1818
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
clib_memset(h->entries, 0, sizeof(h->entries[0])*entries)
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:2732
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:1681
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:249
vl_api_registration_t * reg
Definition: ip_api.c:1399
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:2485
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:2280
void vl_api_ip_reassembly_enable_disable_t_handler(vl_api_ip_reassembly_enable_disable_t *mp)
Definition: ip_api.c:2790
#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:1206
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:1193
vhost_vring_addr_t addr
Definition: vhost_user.h:147
#define IP4_ARP_EVENT
Definition: ip_api.c:1642
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:2755
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:47
IP FIB table response.
Definition: ip.api:72
static void handle_ip4_arp_event(u32 pool_index)
Definition: ip_api.c:1662
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:519
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:1248
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:2385
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:1340
void vl_api_ip_route_add_del_t_handler(vl_api_ip_route_add_del_t *mp)
Definition: ip_api.c:702
Aggregrate 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:1075
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:2704
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1361
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index, u8 refresh)
Definition: ip6_forward.c:1469
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1613
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:2553
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:2194
#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:2398
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:2394
static void vl_api_sw_interface_ip6nd_ra_prefix_t_handler(vl_api_sw_interface_ip6nd_ra_prefix_t *mp)
Definition: ip_api.c:1140
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:699
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:1170
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:1248
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:1290
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1095
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:2052
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:1448
static clib_error_t * want_ip6_ra_events_reaper(u32 client_index)
Definition: ip_api.c:2374
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:2420
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:2031
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:312
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:1427
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
static vlib_node_registration_t wc_arp_process_node
(constructor) VLIB_REGISTER_NODE (wc_arp_process_node)
Definition: ip_api.c:1839
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:1483
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:1989
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:1056
#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:1334
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:874
static void vl_api_proxy_arp_dump_t_handler(vl_api_proxy_arp_dump_t *mp)
Definition: ip_api.c:2449
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
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:2430
Aggregrate 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)
vnet_api_error_t ip4_reass_enable_disable(u32 sw_if_index, u8 enable_disable)
static void vl_api_ioam_disable_t_handler(vl_api_ioam_disable_t *mp)
Definition: ip_api.c:1465
#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)
vnet_api_error_t ip4_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *max_reassembly_length, u32 *expire_walk_interval_ms)
get ip4 reassembly configuration
static void vl_api_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:2690
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:2571
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:2671
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:1648
static int ip_container_proxy_send_details(const fib_prefix_t *pfx, u32 sw_if_index, void *args)
Definition: ip_api.c:1404
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:1208
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:1064
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
void proxy_arp_intfc_walk(proxy_arp_intf_walk_t cb, void *data)
Definition: arp.c:2467
static void set_ip4_flow_hash(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1075
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:1845
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:1619
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: ip_api.c:1445
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:2521
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:2892
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:900
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:1645
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:2809
vnet_api_error_t ip6_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 max_reassembly_length, u32 expire_walk_interval_ms)
set ip6 reassembly configuration
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:2884
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:332
fib_route_path_t * fib_entry_encode(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1651
#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:2054
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:833
#define clib_error_get_code(err)
Definition: error.h:77
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:2142
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:1105
Tell client about an IP6 ND resolution or MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs...
Definition: ip.api:809
vnet_api_error_t ip6_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *expire_walk_interval_ms)
get ip6 reassembly configuration
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
vl_api_address_t ip_address
Definition: ip.api:161
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:921
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:510
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.
vnet_api_error_t ip6_reass_enable_disable(u32 sw_if_index, u8 enable_disable)
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:2845
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:719
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:1772
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:175
_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:2807
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:1323
static void handle_ip6_nd_event(u32 pool_index)
Definition: ip_api.c:1725
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:1264
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:1559
#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:274
#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:2692
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:2635
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:2333
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