FD.io VPP  v18.07.1-19-g511ce25
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 <vpp/stats/stats.h>
24 #include <vnet/interface.h>
25 #include <vnet/api_errno.h>
26 #include <vnet/ethernet/ethernet.h>
27 #include <vnet/ip/ip.h>
28 #include <vnet/ip/ip_neighbor.h>
29 #include <vnet/ip/ip6_neighbor.h>
30 #include <vnet/fib/fib_table.h>
31 #include <vnet/fib/fib_api.h>
32 #include <vnet/dpo/drop_dpo.h>
33 #include <vnet/dpo/receive_dpo.h>
34 #include <vnet/dpo/lookup_dpo.h>
35 #include <vnet/dpo/classify_dpo.h>
36 #include <vnet/dpo/ip_null_dpo.h>
38 #include <vnet/mfib/ip6_mfib.h>
39 #include <vnet/mfib/ip4_mfib.h>
40 #include <vnet/mfib/mfib_signal.h>
41 #include <vnet/mfib/mfib_entry.h>
43 #include <vnet/fib/ip4_fib.h>
44 #include <vnet/fib/ip6_fib.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 
50 #include <vnet/vnet_msg_enum.h>
51 
52 #define vl_typedefs /* define message structures */
53 #include <vnet/vnet_all_api_h.h>
54 #undef vl_typedefs
55 
56 #define vl_endianfun /* define message structures */
57 #include <vnet/vnet_all_api_h.h>
58 #undef vl_endianfun
59 
60 /* instantiate all the print functions we know about */
61 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
62 #define vl_printfun
63 #include <vnet/vnet_all_api_h.h>
64 #undef vl_printfun
65 
67 
68 
69 #define foreach_ip_api_msg \
70 _(IP_FIB_DUMP, ip_fib_dump) \
71 _(IP6_FIB_DUMP, ip6_fib_dump) \
72 _(IP_MFIB_DUMP, ip_mfib_dump) \
73 _(IP6_MFIB_DUMP, ip6_mfib_dump) \
74 _(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
75 _(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
76 _(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
77 _(IP_ADDRESS_DUMP, ip_address_dump) \
78 _(IP_UNNUMBERED_DUMP, ip_unnumbered_dump) \
79 _(IP_DUMP, ip_dump) \
80 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
81 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
82 _(IP_PROBE_NEIGHBOR, ip_probe_neighbor) \
83 _(IP_SCAN_NEIGHBOR_ENABLE_DISABLE, ip_scan_neighbor_enable_disable) \
84 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
85 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
86 _(WANT_IP6_RA_EVENTS, want_ip6_ra_events) \
87 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
88 _(PROXY_ARP_DUMP, proxy_arp_dump) \
89 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
90  _(PROXY_ARP_INTFC_DUMP, proxy_arp_intfc_dump) \
91 _(RESET_FIB, reset_fib) \
92 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
93 _(IP_TABLE_ADD_DEL, ip_table_add_del) \
94 _(IP_PUNT_POLICE, ip_punt_police) \
95 _(IP_PUNT_REDIRECT, ip_punt_redirect) \
96 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
97 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
98 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
99 _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
100 _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
101 _(IP6ND_SEND_ROUTER_SOLICITATION, ip6nd_send_router_solicitation) \
102 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
103 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
104  sw_interface_ip6_set_link_local_address) \
105 _(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \
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_REASSEMBLY_SET, ip_reassembly_set) \
113 _(IP_REASSEMBLY_GET, ip_reassembly_get) \
114 _(IP_REASSEMBLY_ENABLE_DISABLE, ip_reassembly_enable_disable)
115 
116 extern void stats_dslock_with_hint (int hint, int tag);
117 extern void stats_dsunlock (void);
118 
119 static void
121  u8 is_ipv6,
122  u8 is_static,
123  u8 * mac_address,
124  u8 * ip_address, vl_api_registration_t * reg,
125  u32 context)
126 {
128 
129  mp = vl_msg_api_alloc (sizeof (*mp));
130  memset (mp, 0, sizeof (*mp));
131  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
132  mp->context = context;
133  mp->sw_if_index = htonl (sw_if_index);
134  mp->is_ipv6 = is_ipv6;
135  mp->is_static = is_static;
136  memcpy (mp->mac_address, mac_address, 6);
137  memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
138 
139  vl_api_send_msg (reg, (u8 *) mp);
140 }
141 
142 static void
144 {
146 
148  if (!reg)
149  return;
150 
151  u32 sw_if_index = ntohl (mp->sw_if_index);
152 
153  if (mp->is_ipv6)
154  {
155  ip6_neighbor_t *n, *ns;
156 
157  ns = ip6_neighbors_entries (sw_if_index);
158  /* *INDENT-OFF* */
159  vec_foreach (n, ns)
160  {
162  (n->key.sw_if_index, mp->is_ipv6,
163  ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0),
164  (u8 *) n->link_layer_address,
165  (u8 *) & (n->key.ip6_address.as_u8),
166  reg, mp->context);
167  }
168  /* *INDENT-ON* */
169  vec_free (ns);
170  }
171  else
172  {
173  ethernet_arp_ip4_entry_t *n, *ns;
174 
175  ns = ip4_neighbor_entries (sw_if_index);
176  /* *INDENT-OFF* */
177  vec_foreach (n, ns)
178  {
180  ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0),
181  (u8*) n->ethernet_address,
182  (u8*) & (n->ip4_address.as_u8),
183  reg, mp->context);
184  }
185  /* *INDENT-ON* */
186  vec_free (ns);
187  }
188 }
189 
190 static void
192  vl_api_registration_t * reg,
193  const fib_table_t * table,
194  const fib_prefix_t * pfx,
195  fib_route_path_encode_t * api_rpaths, u32 context)
196 {
198  fib_route_path_encode_t *api_rpath;
199  vl_api_fib_path_t *fp;
200  int path_count;
201 
202  path_count = vec_len (api_rpaths);
203  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
204  if (!mp)
205  return;
206  memset (mp, 0, sizeof (*mp));
207  mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
208  mp->context = context;
209 
210  mp->table_id = htonl (table->ft_table_id);
211  memcpy (mp->table_name, table->ft_desc,
212  clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
213  mp->address_length = pfx->fp_len;
214  memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
215 
216  mp->count = htonl (path_count);
217  fp = mp->path;
218  vec_foreach (api_rpath, api_rpaths)
219  {
220  fib_api_path_encode (api_rpath, fp);
221  fp++;
222  }
223 
224  vl_api_send_msg (reg, (u8 *) mp);
225 }
226 
228 {
231 
232 static fib_table_walk_rc_t
234 {
236 
237  vec_add1 (ctx->feis, fei);
238 
239  return (FIB_TABLE_WALK_CONTINUE);
240 }
241 
242 static void
244 {
247  ip4_main_t *im = &ip4_main;
248  fib_table_t *fib_table;
249  fib_node_index_t *lfeip;
250  fib_prefix_t pfx;
251  u32 fib_index;
252  fib_route_path_encode_t *api_rpaths;
254  .feis = NULL,
255  };
256 
258  if (!reg)
259  return;
260 
261  /* *INDENT-OFF* */
262  pool_foreach (fib_table, im->fibs,
263  ({
264  fib_table_walk(fib_table->ft_index,
265  FIB_PROTOCOL_IP4,
266  vl_api_ip_fib_dump_walk,
267  &ctx);
268  }));
269  /* *INDENT-ON* */
270 
272 
273  vec_foreach (lfeip, ctx.feis)
274  {
275  fib_entry_get_prefix (*lfeip, &pfx);
276  fib_index = fib_entry_get_fib_index (*lfeip);
277  fib_table = fib_table_get (fib_index, pfx.fp_proto);
278  api_rpaths = NULL;
279  fib_entry_encode (*lfeip, &api_rpaths);
280  send_ip_fib_details (am, reg, fib_table, &pfx, api_rpaths, mp->context);
281  vec_free (api_rpaths);
282  }
283 
284  vec_free (ctx.feis);
285 }
286 
287 static void
289  vl_api_registration_t * reg,
290  const fib_table_t * table,
291  const fib_prefix_t * pfx,
292  fib_route_path_encode_t * api_rpaths, u32 context)
293 {
295  fib_route_path_encode_t *api_rpath;
296  vl_api_fib_path_t *fp;
297  int path_count;
298 
299  path_count = vec_len (api_rpaths);
300  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
301  if (!mp)
302  return;
303  memset (mp, 0, sizeof (*mp));
304  mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
305  mp->context = context;
306 
307  mp->table_id = htonl (table->ft_table_id);
308  mp->address_length = pfx->fp_len;
309  memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
310  memcpy (mp->table_name, table->ft_desc,
311  clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
312 
313  mp->count = htonl (path_count);
314  fp = mp->path;
315  vec_foreach (api_rpath, api_rpaths)
316  {
317  fib_api_path_encode (api_rpath, fp);
318  fp++;
319  }
320 
321  vl_api_send_msg (reg, (u8 *) mp);
322 }
323 
325 {
329 
330 static void
332 {
334 
335  if ((kvp->key[2] >> 32) == ctx->fib_index)
336  {
337  vec_add1 (ctx->entries, kvp->value);
338  }
339 }
340 
341 static void
344  fib_table_t * fib_table)
345 {
347  ip6_main_t *im6 = &ip6_main;
348  fib_node_index_t *fib_entry_index;
350  .fib_index = fib_table->ft_index,
351  .entries = NULL,
352  };
353  fib_route_path_encode_t *api_rpaths;
354  fib_prefix_t pfx;
355 
357  ((BVT (clib_bihash) *) & im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].
358  ip6_hash, api_ip6_fib_table_put_entries, &ctx);
359 
361 
362  vec_foreach (fib_entry_index, ctx.entries)
363  {
364  fib_entry_get_prefix (*fib_entry_index, &pfx);
365  api_rpaths = NULL;
366  fib_entry_encode (*fib_entry_index, &api_rpaths);
367  send_ip6_fib_details (am, reg, fib_table, &pfx, api_rpaths, mp->context);
368  vec_free (api_rpaths);
369  }
370 
371  vec_free (ctx.entries);
372 }
373 
374 static void
376 {
378  ip6_main_t *im6 = &ip6_main;
379  fib_table_t *fib_table;
380 
382  if (!reg)
383  return;
384 
385  /* *INDENT-OFF* */
386  pool_foreach (fib_table, im6->fibs,
387  ({
388  /* don't send link locals */
389  if (fib_table->ft_flags & FIB_TABLE_FLAG_IP6_LL)
390  continue;
391 
392  api_ip6_fib_table_get_all(reg, mp, fib_table);
393  }));
394  /* *INDENT-ON* */
395 }
396 
397 static void
399  u32 context, u32 table_id, fib_node_index_t mfei)
400 {
401  fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
403  mfib_entry_t *mfib_entry;
404  vl_api_fib_path_t *fp;
405  mfib_prefix_t pfx;
406  int path_count;
407 
408  mfib_entry = mfib_entry_get (mfei);
409  mfib_entry_get_prefix (mfei, &pfx);
410  mfib_entry_encode (mfei, &api_rpaths);
411 
412  path_count = vec_len (api_rpaths);
413  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
414  if (!mp)
415  return;
416  memset (mp, 0, sizeof (*mp));
417  mp->_vl_msg_id = ntohs (VL_API_IP_MFIB_DETAILS);
418  mp->context = context;
419 
420  mp->rpf_id = mfib_entry->mfe_rpf_id;
421  mp->entry_flags = mfib_entry->mfe_flags;
422  mp->table_id = htonl (table_id);
423  mp->address_length = pfx.fp_len;
424  memcpy (mp->grp_address, &pfx.fp_grp_addr.ip4,
425  sizeof (pfx.fp_grp_addr.ip4));
426  memcpy (mp->src_address, &pfx.fp_src_addr.ip4,
427  sizeof (pfx.fp_src_addr.ip4));
428 
429  mp->count = htonl (path_count);
430  fp = mp->path;
431  vec_foreach (api_rpath, api_rpaths)
432  {
433  fib_api_path_encode (api_rpath, fp);
434  fp++;
435  }
436  vec_free (api_rpaths);
437 
438  vl_api_send_msg (reg, (u8 *) mp);
439 }
440 
442 {
445 
446 static int
448 {
450 
451  vec_add1 (ctx->entries, fei);
452 
453  return (0);
454 }
455 
456 static void
458 {
460  ip4_main_t *im = &ip4_main;
461  mfib_table_t *mfib_table;
462  fib_node_index_t *mfeip;
464  .entries = NULL,
465  };
466 
468  if (!reg)
469  return;
470 
471  /* *INDENT-OFF* */
472  pool_foreach (mfib_table, im->mfibs,
473  ({
474  ip4_mfib_table_walk(&mfib_table->v4,
475  vl_api_ip_mfib_table_dump_walk,
476  &ctx);
477 
478  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
479 
480  vec_foreach (mfeip, ctx.entries)
481  {
482  send_ip_mfib_details (reg, mp->context,
483  mfib_table->mft_table_id,
484  *mfeip);
485  }
487 
488  }));
489  /* *INDENT-ON* */
490 
491  vec_free (ctx.entries);
492 }
493 
494 static void
496  vl_api_registration_t * reg,
497  u32 table_id,
498  mfib_prefix_t * pfx,
499  fib_route_path_encode_t * api_rpaths, u32 context)
500 {
502  fib_route_path_encode_t *api_rpath;
503  vl_api_fib_path_t *fp;
504  int path_count;
505 
506  path_count = vec_len (api_rpaths);
507  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
508  if (!mp)
509  return;
510  memset (mp, 0, sizeof (*mp));
511  mp->_vl_msg_id = ntohs (VL_API_IP6_MFIB_DETAILS);
512  mp->context = context;
513 
514  mp->table_id = htonl (table_id);
515  mp->address_length = pfx->fp_len;
516  memcpy (mp->grp_address, &pfx->fp_grp_addr.ip6,
517  sizeof (pfx->fp_grp_addr.ip6));
518  memcpy (mp->src_address, &pfx->fp_src_addr.ip6,
519  sizeof (pfx->fp_src_addr.ip6));
520 
521  mp->count = htonl (path_count);
522  fp = mp->path;
523  vec_foreach (api_rpath, api_rpaths)
524  {
525  fib_api_path_encode (api_rpath, fp);
526  fp++;
527  }
528 
529  vl_api_send_msg (reg, (u8 *) mp);
530 }
531 
533 {
536 
537 static int
539 {
541 
542  vec_add1 (ctx->entries, fei);
543 
544  return (0);
545 }
546 
547 static void
549 {
552  ip6_main_t *im = &ip6_main;
553  mfib_table_t *mfib_table;
554  fib_node_index_t *mfeip;
555  mfib_prefix_t pfx;
556  fib_route_path_encode_t *api_rpaths = NULL;
558  .entries = NULL,
559  };
560 
562  if (!reg)
563  return;
564 
565 
566  /* *INDENT-OFF* */
567  pool_foreach (mfib_table, im->mfibs,
568  ({
569  ip6_mfib_table_walk(&mfib_table->v6,
570  vl_api_ip6_mfib_table_dump_walk,
571  &ctx);
572 
573  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
574 
575  vec_foreach(mfeip, ctx.entries)
576  {
577  mfib_entry_get_prefix (*mfeip, &pfx);
578  mfib_entry_encode (*mfeip, &api_rpaths);
579  send_ip6_mfib_details (am, reg,
580  mfib_table->mft_table_id,
581  &pfx, api_rpaths,
582  mp->context);
583  }
584  vec_reset_length (api_rpaths);
586 
587  }));
588  /* *INDENT-ON* */
589 
590  vec_free (ctx.entries);
591  vec_free (api_rpaths);
592 }
593 
594 static void
596  vlib_main_t * vm)
597 {
598  vl_api_ip_punt_police_reply_t *rmp;
599  int rv = 0;
600 
601  if (mp->is_ip6)
602  ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
603  else
604  ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
605 
606  REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
607 }
608 
609 static void
611  vlib_main_t * vm)
612 {
613  vl_api_ip_punt_redirect_reply_t *rmp;
614  int rv = 0;
615 
616  if (mp->is_add)
617  {
618  ip46_address_t nh;
619 
620  memset (&nh, 0, sizeof (nh));
621 
622  if (mp->is_ip6)
623  {
624  memcpy (&nh.ip6, mp->nh, sizeof (nh.ip6));
625 
627  ntohl (mp->tx_sw_if_index), &nh);
628  }
629  else
630  {
631  memcpy (&nh.ip4, mp->nh, sizeof (nh.ip4));
632 
634  ntohl (mp->tx_sw_if_index), &nh);
635  }
636  }
637  else
638  {
639  if (mp->is_ip6)
640  {
642  }
643  else
644  {
646  }
647  }
648 
649  REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
650 }
651 
652 static void
654  vlib_main_t * vm)
655 {
656  vl_api_ip_neighbor_add_del_reply_t *rmp;
657  vnet_main_t *vnm = vnet_get_main ();
658  int rv = 0;
659 
661 
662  stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ );
663 
664  /*
665  * there's no validation here of the ND/ARP entry being added.
666  * The expectation is that the FIB will ensure that nothing bad
667  * will come of adding bogus entries.
668  */
669  if (mp->is_ipv6)
670  {
671  if (mp->is_add)
673  (vm, ntohl (mp->sw_if_index),
674  (ip6_address_t *) (mp->dst_address),
675  mp->mac_address, sizeof (mp->mac_address), mp->is_static,
676  mp->is_no_adj_fib);
677  else
679  (vm, ntohl (mp->sw_if_index),
680  (ip6_address_t *) (mp->dst_address),
681  mp->mac_address, sizeof (mp->mac_address));
682  }
683  else
684  {
685  ethernet_arp_ip4_over_ethernet_address_t a;
686 
687  clib_memcpy (&a.ethernet, mp->mac_address, 6);
688  clib_memcpy (&a.ip4, mp->dst_address, 4);
689 
690  if (mp->is_add)
691  rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
692  &a, mp->is_static,
693  mp->is_no_adj_fib);
694  else
695  rv =
696  vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
697  }
698 
699  stats_dsunlock ();
700 
702  REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
703 }
704 
705 void
706 ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
707 {
708  u32 fib_index, mfib_index;
709 
710  /*
711  * ignore action on the default table - this is always present
712  * and cannot be added nor deleted from the API
713  */
714  if (0 != table_id)
715  {
716  /*
717  * The API holds only one lock on the table.
718  * i.e. it can be added many times via the API but needs to be
719  * deleted only once.
720  * The FIB index for unicast and multicast is not necessarily the
721  * same, since internal VPP systesm (like LISP and SR) create
722  * their own unicast tables.
723  */
724  fib_index = fib_table_find (fproto, table_id);
725  mfib_index = mfib_table_find (fproto, table_id);
726 
727  if (~0 != fib_index)
728  {
729  fib_table_unlock (fib_index, fproto,
730  (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
731  }
732  if (~0 != mfib_index)
733  {
734  mfib_table_unlock (mfib_index, fproto,
735  (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
736  }
737  }
738 }
739 
740 void
742 {
743  vl_api_ip_table_add_del_reply_t *rmp;
745  u32 table_id = ntohl (mp->table_id);
746  int rv = 0;
747 
748  if (mp->is_add)
749  {
750  ip_table_create (fproto, table_id, 1, mp->name);
751  }
752  else
753  {
754  ip_table_delete (fproto, table_id, 1);
755  }
756 
757  REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
758 }
759 
760 int
762  u8 is_add,
763  u8 is_drop,
764  u8 is_unreach,
765  u8 is_prohibit,
766  u8 is_local,
767  u8 is_multicast,
768  u8 is_classify,
769  u32 classify_table_index,
770  u8 is_resolve_host,
771  u8 is_resolve_attached,
772  u8 is_interface_rx,
773  u8 is_rpf_id,
774  u8 is_dvr,
775  u8 is_source_lookup,
776  u8 is_udp_encap,
777  u32 fib_index,
778  const fib_prefix_t * prefix,
779  dpo_proto_t next_hop_proto,
780  const ip46_address_t * next_hop,
781  u32 next_hop_id,
782  u32 next_hop_sw_if_index,
783  u8 next_hop_fib_index,
784  u16 next_hop_weight,
785  u16 next_hop_preference,
786  mpls_label_t next_hop_via_label,
787  fib_mpls_label_t * next_hop_out_label_stack)
788 {
791  fib_route_path_t path = {
792  .frp_proto = next_hop_proto,
793  .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
794  .frp_sw_if_index = next_hop_sw_if_index,
795  .frp_fib_index = next_hop_fib_index,
796  .frp_weight = next_hop_weight,
797  .frp_preference = next_hop_preference,
798  .frp_label_stack = next_hop_out_label_stack,
799  };
800  fib_route_path_t *paths = NULL;
802 
803  /*
804  * the special INVALID label meams we are not recursing via a
805  * label. Exp-null value is never a valid via-label so that
806  * also means it's not a via-label and means clients that set
807  * it to 0 by default get the expected behaviour
808  */
809  if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
810  {
811  path.frp_proto = DPO_PROTO_MPLS;
812  path.frp_local_label = next_hop_via_label;
813  path.frp_eos = MPLS_NON_EOS;
814  }
815  if (is_dvr)
816  path_flags |= FIB_ROUTE_PATH_DVR;
817  if (is_resolve_host)
818  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
819  if (is_resolve_attached)
821  if (is_interface_rx)
822  path_flags |= FIB_ROUTE_PATH_INTF_RX;
823  if (is_rpf_id)
824  path_flags |= FIB_ROUTE_PATH_RPF_ID;
825  if (is_source_lookup)
826  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
827  if (is_multicast)
828  entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
829  if (is_udp_encap)
830  {
831  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
832  path.frp_udp_encap_id = next_hop_id;
833  }
834  if (path.frp_sw_if_index == ~0 && ip46_address_is_zero (&path.frp_addr)
835  && path.frp_fib_index != ~0)
836  {
837  path_flags |= FIB_ROUTE_PATH_DEAG;
838  }
839 
840  path.frp_flags = path_flags;
841 
842  if (is_multipath)
843  {
844  stats_dslock_with_hint (1 /* release hint */ , 10 /* tag */ );
845 
846 
847  vec_add1 (paths, path);
848 
849  if (is_add)
850  fib_table_entry_path_add2 (fib_index,
851  prefix,
852  FIB_SOURCE_API, entry_flags, paths);
853  else
854  fib_table_entry_path_remove2 (fib_index,
855  prefix, FIB_SOURCE_API, paths);
856 
857  vec_free (paths);
858  stats_dsunlock ();
859  return 0;
860  }
861 
862  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
863 
864  if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
865  {
866  /*
867  * special route types that link directly to the adj
868  */
869  if (is_add)
870  {
871  dpo_id_t dpo = DPO_INVALID;
872  dpo_proto_t dproto;
873 
874  dproto = fib_proto_to_dpo (prefix->fp_proto);
875 
876  if (is_drop)
878  else if (is_local)
879  receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
880  else if (is_unreach)
881  ip_null_dpo_add_and_lock (dproto,
883  else if (is_prohibit)
884  ip_null_dpo_add_and_lock (dproto,
886  &dpo);
887  else if (is_classify)
888  {
889  if (pool_is_free_index (cm->tables,
890  ntohl (classify_table_index)))
891  {
892  stats_dsunlock ();
893  return VNET_API_ERROR_NO_SUCH_TABLE;
894  }
895 
896  dpo_set (&dpo, DPO_CLASSIFY, dproto,
897  classify_dpo_create (dproto,
898  ntohl (classify_table_index)));
899  }
900  else
901  {
902  stats_dsunlock ();
903  return VNET_API_ERROR_NO_SUCH_TABLE;
904  }
905 
907  prefix,
910  dpo_reset (&dpo);
911  }
912  else
913  {
914  fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
915  }
916  }
917  else
918  {
919  if (is_add)
920  {
921  vec_add1 (paths, path);
922  fib_table_entry_update (fib_index,
923  prefix, FIB_SOURCE_API, entry_flags, paths);
924  vec_free (paths);
925  }
926  else
927  {
928  fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
929  }
930  }
931 
932  stats_dsunlock ();
933  return (0);
934 }
935 
936 int
938  u32 table_id,
939  u32 next_hop_sw_if_index,
940  dpo_proto_t next_hop_table_proto,
941  u32 next_hop_table_id,
942  u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
943 {
944  vnet_main_t *vnm = vnet_get_main ();
945 
946  *fib_index = fib_table_find (table_proto, ntohl (table_id));
947  if (~0 == *fib_index)
948  {
949  /* No such VRF, and we weren't asked to create one */
950  return VNET_API_ERROR_NO_SUCH_FIB;
951  }
952 
953  if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
954  {
956  ntohl (next_hop_sw_if_index)))
957  {
958  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
959  }
960  }
961  else
962  {
963  fib_protocol_t fib_nh_proto;
964 
965  if (next_hop_table_proto > DPO_PROTO_MPLS)
966  return (0);
967 
968  fib_nh_proto = dpo_proto_to_fib (next_hop_table_proto);
969 
970  if (is_rpf_id)
971  *next_hop_fib_index = mfib_table_find (fib_nh_proto,
972  ntohl (next_hop_table_id));
973  else
974  *next_hop_fib_index = fib_table_find (fib_nh_proto,
975  ntohl (next_hop_table_id));
976 
977  if (~0 == *next_hop_fib_index)
978  {
979  /* No such VRF, and we weren't asked to create one */
980  return VNET_API_ERROR_NO_SUCH_FIB;
981  }
982  }
983 
984  return (0);
985 }
986 
987 static int
989 {
990  u32 fib_index, next_hop_fib_index;
991  fib_mpls_label_t *label_stack = NULL;
992  int rv, ii, n_labels;;
993 
995  mp->table_id,
998  mp->next_hop_table_id,
999  0, &fib_index, &next_hop_fib_index);
1000 
1001  if (0 != rv)
1002  return (rv);
1003 
1004  fib_prefix_t pfx = {
1005  .fp_len = mp->dst_address_length,
1006  .fp_proto = FIB_PROTOCOL_IP4,
1007  };
1008  clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
1009 
1010  ip46_address_t nh;
1011  memset (&nh, 0, sizeof (nh));
1012  memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
1013 
1014  n_labels = mp->next_hop_n_out_labels;
1015  if (n_labels == 0)
1016  ;
1017  else
1018  {
1019  vec_validate (label_stack, n_labels - 1);
1020  for (ii = 0; ii < n_labels; ii++)
1021  {
1022  label_stack[ii].fml_value =
1023  ntohl (mp->next_hop_out_label_stack[ii].label);
1024  label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
1025  label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
1026  label_stack[ii].fml_mode =
1029  }
1030  }
1031 
1033  mp->is_add,
1034  mp->is_drop,
1035  mp->is_unreach,
1036  mp->is_prohibit,
1037  mp->is_local, 0,
1038  mp->is_classify,
1040  mp->is_resolve_host,
1041  mp->is_resolve_attached, 0, 0,
1042  mp->is_dvr,
1043  mp->is_source_lookup,
1044  mp->is_udp_encap,
1045  fib_index, &pfx, DPO_PROTO_IP4,
1046  &nh,
1047  ntohl (mp->next_hop_id),
1048  ntohl (mp->next_hop_sw_if_index),
1049  next_hop_fib_index,
1050  mp->next_hop_weight,
1051  mp->next_hop_preference,
1052  ntohl (mp->next_hop_via_label),
1053  label_stack));
1054 }
1055 
1056 static int
1058 {
1059  fib_mpls_label_t *label_stack = NULL;
1060  u32 fib_index, next_hop_fib_index;
1061  int rv, ii, n_labels;;
1062 
1064  mp->table_id,
1066  DPO_PROTO_IP6,
1067  mp->next_hop_table_id,
1068  0, &fib_index, &next_hop_fib_index);
1069 
1070  if (0 != rv)
1071  return (rv);
1072 
1073  fib_prefix_t pfx = {
1074  .fp_len = mp->dst_address_length,
1075  .fp_proto = FIB_PROTOCOL_IP6,
1076  };
1077  clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
1078 
1079  ip46_address_t nh;
1080  memset (&nh, 0, sizeof (nh));
1081  memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
1082 
1083  n_labels = mp->next_hop_n_out_labels;
1084  if (n_labels == 0)
1085  ;
1086  else
1087  {
1088  vec_validate (label_stack, n_labels - 1);
1089  for (ii = 0; ii < n_labels; ii++)
1090  {
1091  label_stack[ii].fml_value =
1092  ntohl (mp->next_hop_out_label_stack[ii].label);
1093  label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
1094  label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
1095  label_stack[ii].fml_mode =
1098  }
1099  }
1100 
1102  mp->is_add,
1103  mp->is_drop,
1104  mp->is_unreach,
1105  mp->is_prohibit,
1106  mp->is_local, 0,
1107  mp->is_classify,
1109  mp->is_resolve_host,
1110  mp->is_resolve_attached, 0, 0,
1111  mp->is_dvr,
1112  mp->is_source_lookup,
1113  mp->is_udp_encap,
1114  fib_index, &pfx, DPO_PROTO_IP6,
1115  &nh, ntohl (mp->next_hop_id),
1116  ntohl (mp->next_hop_sw_if_index),
1117  next_hop_fib_index,
1118  mp->next_hop_weight,
1119  mp->next_hop_preference,
1120  ntohl (mp->next_hop_via_label),
1121  label_stack));
1122 }
1123 
1124 void
1126 {
1127  vl_api_ip_add_del_route_reply_t *rmp;
1128  int rv;
1129  vnet_main_t *vnm = vnet_get_main ();
1130 
1131  vnm->api_errno = 0;
1132 
1133  if (mp->is_ipv6)
1134  rv = ip6_add_del_route_t_handler (mp);
1135  else
1136  rv = ip4_add_del_route_t_handler (mp);
1137 
1138  rv = (rv == 0) ? vnm->api_errno : rv;
1139 
1140  REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
1141 }
1142 
1143 void
1145  u32 table_id, u8 is_api, const u8 * name)
1146 {
1147  u32 fib_index, mfib_index;
1148 
1149  /*
1150  * ignore action on the default table - this is always present
1151  * and cannot be added nor deleted from the API
1152  */
1153  if (0 != table_id)
1154  {
1155  /*
1156  * The API holds only one lock on the table.
1157  * i.e. it can be added many times via the API but needs to be
1158  * deleted only once.
1159  * The FIB index for unicast and multicast is not necessarily the
1160  * same, since internal VPP systesm (like LISP and SR) create
1161  * their own unicast tables.
1162  */
1163  fib_index = fib_table_find (fproto, table_id);
1164  mfib_index = mfib_table_find (fproto, table_id);
1165 
1166  if (~0 == fib_index)
1167  {
1168  fib_table_find_or_create_and_lock_w_name (fproto, table_id,
1169  (is_api ?
1170  FIB_SOURCE_API :
1171  FIB_SOURCE_CLI), name);
1172  }
1173  if (~0 == mfib_index)
1174  {
1176  (is_api ?
1177  MFIB_SOURCE_API :
1178  MFIB_SOURCE_CLI), name);
1179  }
1180  }
1181 }
1182 
1183 static int
1185  u32 table_id,
1186  u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
1187 {
1188  vnet_main_t *vnm = vnet_get_main ();
1189 
1190  *fib_index = mfib_table_find (table_proto, ntohl (table_id));
1191  if (~0 == *fib_index)
1192  {
1193  /* No such table */
1194  return VNET_API_ERROR_NO_SUCH_FIB;
1195  }
1196 
1197  if (~0 != ntohl (next_hop_sw_if_index))
1198  {
1200  ntohl (next_hop_sw_if_index)))
1201  {
1202  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1203  }
1204  }
1205 
1206  return (0);
1207 }
1208 
1209 static int
1211  u8 is_local,
1212  u32 fib_index,
1213  const mfib_prefix_t * prefix,
1214  dpo_proto_t nh_proto,
1215  u32 entry_flags,
1216  fib_rpf_id_t rpf_id,
1217  u32 next_hop_sw_if_index,
1218  ip46_address_t * nh, u32 itf_flags, u32 bier_imp)
1219 {
1220  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
1221 
1222  fib_route_path_t path = {
1223  .frp_sw_if_index = next_hop_sw_if_index,
1224  .frp_proto = nh_proto,
1225  .frp_addr = *nh,
1226  };
1227 
1228  if (is_local)
1230 
1231  if (DPO_PROTO_BIER == nh_proto)
1232  {
1233  path.frp_bier_imp = bier_imp;
1235  }
1236  else if (!is_local && ~0 == next_hop_sw_if_index)
1237  {
1238  mfib_table_entry_update (fib_index, prefix,
1239  MFIB_SOURCE_API, rpf_id, entry_flags);
1240  goto done;
1241  }
1242 
1243  if (is_add)
1244  {
1245  mfib_table_entry_path_update (fib_index, prefix,
1246  MFIB_SOURCE_API, &path, itf_flags);
1247  }
1248  else
1249  {
1250  mfib_table_entry_path_remove (fib_index, prefix,
1251  MFIB_SOURCE_API, &path);
1252  }
1253 
1254 done:
1255  stats_dsunlock ();
1256  return (0);
1257 }
1258 
1259 static int
1261 {
1262  fib_protocol_t fproto;
1263  dpo_proto_t nh_proto;
1264  ip46_address_t nh;
1265  u32 fib_index;
1266  int rv;
1267 
1268  nh_proto = mp->next_hop_afi;
1269  fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
1270  rv = add_del_mroute_check (fproto,
1271  mp->table_id,
1273  mp->is_local, &fib_index);
1274 
1275  if (0 != rv)
1276  return (rv);
1277 
1278  mfib_prefix_t pfx = {
1279  .fp_len = ntohs (mp->grp_address_length),
1280  .fp_proto = fproto,
1281  };
1282 
1283  if (FIB_PROTOCOL_IP4 == fproto)
1284  {
1285  clib_memcpy (&pfx.fp_grp_addr.ip4, mp->grp_address,
1286  sizeof (pfx.fp_grp_addr.ip4));
1287  clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
1288  sizeof (pfx.fp_src_addr.ip4));
1289  memset (&nh.ip6, 0, sizeof (nh.ip6));
1290  clib_memcpy (&nh.ip4, mp->nh_address, sizeof (nh.ip4));
1291  }
1292  else
1293  {
1294  clib_memcpy (&pfx.fp_grp_addr.ip6, mp->grp_address,
1295  sizeof (pfx.fp_grp_addr.ip6));
1296  clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
1297  sizeof (pfx.fp_src_addr.ip6));
1298  clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6));
1299  }
1300 
1301  return (mroute_add_del_handler (mp->is_add,
1302  mp->is_local,
1303  fib_index, &pfx,
1304  nh_proto,
1305  ntohl (mp->entry_flags),
1306  ntohl (mp->rpf_id),
1307  ntohl (mp->next_hop_sw_if_index),
1308  &nh,
1309  ntohl (mp->itf_flags),
1310  ntohl (mp->bier_imp)));
1311 }
1312 
1313 void
1315 {
1316  vl_api_ip_mroute_add_del_reply_t *rmp;
1317  int rv;
1318  vnet_main_t *vnm = vnet_get_main ();
1319 
1320  vnm->api_errno = 0;
1321 
1322  rv = api_mroute_add_del_t_handler (mp);
1323 
1324  rv = (rv == 0) ? vnm->api_errno : rv;
1325 
1326  REPLY_MACRO (VL_API_IP_MROUTE_ADD_DEL_REPLY);
1327 }
1328 
1329 static void
1331  vl_api_registration_t * reg, u32 sw_if_index, u8 is_ipv6,
1332  u32 context)
1333 {
1334  vl_api_ip_details_t *mp;
1335 
1336  mp = vl_msg_api_alloc (sizeof (*mp));
1337  memset (mp, 0, sizeof (*mp));
1338  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
1339 
1340  mp->sw_if_index = ntohl (sw_if_index);
1341  mp->is_ipv6 = is_ipv6;
1342  mp->context = context;
1343 
1344  vl_api_send_msg (reg, (u8 *) mp);
1345 }
1346 
1347 static void
1349  vl_api_registration_t * reg,
1350  u8 * ip, u16 prefix_length,
1351  u32 sw_if_index, u8 is_ipv6, u32 context)
1352 {
1354 
1355  mp = vl_msg_api_alloc (sizeof (*mp));
1356  memset (mp, 0, sizeof (*mp));
1357  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
1358 
1359  if (is_ipv6)
1360  {
1361  clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
1362  }
1363  else
1364  {
1365  u32 *tp = (u32 *) mp->ip;
1366  *tp = *(u32 *) ip;
1367  }
1368  mp->prefix_length = prefix_length;
1369  mp->context = context;
1370  mp->sw_if_index = htonl (sw_if_index);
1371  mp->is_ipv6 = is_ipv6;
1372 
1373  vl_api_send_msg (reg, (u8 *) mp);
1374 }
1375 
1376 static void
1378 {
1380  vl_api_registration_t *reg;
1381  ip6_address_t *r6;
1382  ip4_address_t *r4;
1383  ip6_main_t *im6 = &ip6_main;
1384  ip4_main_t *im4 = &ip4_main;
1385  ip_lookup_main_t *lm6 = &im6->lookup_main;
1386  ip_lookup_main_t *lm4 = &im4->lookup_main;
1387  ip_interface_address_t *ia = 0;
1388  u32 sw_if_index = ~0;
1389  int rv __attribute__ ((unused)) = 0;
1390 
1391  VALIDATE_SW_IF_INDEX (mp);
1392 
1393  sw_if_index = ntohl (mp->sw_if_index);
1394 
1396  if (!reg)
1397  return;
1398 
1399  if (mp->is_ipv6)
1400  {
1401  /* *INDENT-OFF* */
1402  /* Do not send subnet details of the IP-interface for
1403  * unnumbered interfaces. otherwise listening clients
1404  * will be confused that the subnet is applied on more
1405  * than one interface */
1406  foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
1407  ({
1408  r6 = ip_interface_address_get_address (lm6, ia);
1409  u16 prefix_length = ia->address_length;
1410  send_ip_address_details(am, reg, (u8*)r6, prefix_length,
1411  sw_if_index, 1, mp->context);
1412  }));
1413  /* *INDENT-ON* */
1414  }
1415  else
1416  {
1417  /* *INDENT-OFF* */
1418  foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
1419  ({
1420  r4 = ip_interface_address_get_address (lm4, ia);
1421  u16 prefix_length = ia->address_length;
1422  send_ip_address_details(am, reg, (u8*)r4, prefix_length,
1423  sw_if_index, 0, mp->context);
1424  }));
1425  /* *INDENT-ON* */
1426  }
1428 }
1429 
1430 static void
1432  vl_api_registration_t * reg,
1433  u32 sw_if_index, u32 ip_sw_if_index, u32 context)
1434 {
1436 
1437  mp = vl_msg_api_alloc (sizeof (*mp));
1438  memset (mp, 0, sizeof (*mp));
1439  mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS);
1440 
1441  mp->context = context;
1442  mp->sw_if_index = htonl (sw_if_index);
1443  mp->ip_sw_if_index = htonl (ip_sw_if_index);
1444 
1445  vl_api_send_msg (reg, (u8 *) mp);
1446 }
1447 
1448 static void
1450 {
1451  vnet_main_t *vnm = vnet_get_main ();
1453  int rv __attribute__ ((unused)) = 0;
1455  vl_api_registration_t *reg;
1456  vnet_sw_interface_t *si;
1457  u32 sw_if_index;
1458 
1459  sw_if_index = ntohl (mp->sw_if_index);
1460 
1462  if (!reg)
1463  return;
1464 
1465  if (~0 != sw_if_index)
1466  {
1467  VALIDATE_SW_IF_INDEX (mp);
1468 
1469  si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
1470 
1472  {
1473  send_ip_unnumbered_details (am, reg,
1474  sw_if_index,
1476  mp->context);
1477  }
1478  }
1479  else
1480  {
1481  /* *INDENT-OFF* */
1482  pool_foreach (si, im->sw_interfaces,
1483  ({
1484  if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
1485  {
1486  send_ip_unnumbered_details(am, reg,
1487  si->sw_if_index,
1488  si->unnumbered_sw_if_index,
1489  mp->context);
1490  }
1491  }));
1492  /* *INDENT-ON* */
1493  }
1494 
1496 }
1497 
1498 static void
1500 {
1502  vnet_main_t *vnm = vnet_get_main ();
1505  vl_api_registration_t *reg;
1506  vnet_sw_interface_t *si, *sorted_sis;
1507  u32 sw_if_index = ~0;
1508 
1510  if (!reg)
1511  return;
1512 
1513  /* Gather interfaces. */
1514  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
1515  _vec_len (sorted_sis) = 0;
1516  /* *INDENT-OFF* */
1517  pool_foreach (si, im->sw_interfaces,
1518  ({
1519  vec_add1 (sorted_sis, si[0]);
1520  }));
1521  /* *INDENT-ON* */
1522 
1523  vec_foreach (si, sorted_sis)
1524  {
1526  {
1527  if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
1528  {
1529  continue;
1530  }
1531  sw_if_index = si->sw_if_index;
1532  send_ip_details (am, reg, sw_if_index, mp->is_ipv6, mp->context);
1533  }
1534  }
1535 }
1536 
1537 static void
1539 {
1540  vl_api_set_ip_flow_hash_reply_t *rmp;
1541  int rv;
1542  u32 table_id;
1543  flow_hash_config_t flow_hash_config = 0;
1544 
1545  table_id = ntohl (mp->vrf_id);
1546 
1547 #define _(a,b) if (mp->a) flow_hash_config |= b;
1549 #undef _
1550 
1551  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1552 
1553  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1554 }
1555 
1556 static void
1558 {
1559  vl_api_set_ip_flow_hash_reply_t *rmp;
1560  int rv;
1561  u32 table_id;
1562  flow_hash_config_t flow_hash_config = 0;
1563 
1564  table_id = ntohl (mp->vrf_id);
1565 
1566 #define _(a,b) if (mp->a) flow_hash_config |= b;
1568 #undef _
1569 
1570  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1571 
1572  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1573 }
1574 
1575 
1576 static void
1578 {
1579  if (mp->is_ipv6 == 0)
1580  set_ip4_flow_hash (mp);
1581  else
1582  set_ip6_flow_hash (mp);
1583 }
1584 
1585 static void
1588 {
1589  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1591  int rv = 0;
1592  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1593  default_router;
1594 
1595  is_no = mp->is_no == 1;
1596  suppress = mp->suppress == 1;
1597  managed = mp->managed == 1;
1598  other = mp->other == 1;
1599  ll_option = mp->ll_option == 1;
1600  send_unicast = mp->send_unicast == 1;
1601  cease = mp->cease == 1;
1602  default_router = mp->default_router == 1;
1603 
1604  VALIDATE_SW_IF_INDEX (mp);
1605 
1606  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1607  suppress, managed, other,
1608  ll_option, send_unicast, cease,
1609  default_router, ntohl (mp->lifetime),
1610  ntohl (mp->initial_count),
1611  ntohl (mp->initial_interval),
1612  ntohl (mp->max_interval),
1613  ntohl (mp->min_interval), is_no);
1614 
1616 
1617  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1618 }
1619 
1620 static void
1623 {
1625  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1626  int rv = 0;
1627  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1628 
1629  VALIDATE_SW_IF_INDEX (mp);
1630 
1631  is_no = mp->is_no == 1;
1632  use_default = mp->use_default == 1;
1633  no_advertise = mp->no_advertise == 1;
1634  off_link = mp->off_link == 1;
1635  no_autoconfig = mp->no_autoconfig == 1;
1636  no_onlink = mp->no_onlink == 1;
1637 
1638  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1639  (ip6_address_t *) mp->address,
1640  mp->address_length, use_default,
1641  ntohl (mp->val_lifetime),
1642  ntohl (mp->pref_lifetime), no_advertise,
1643  off_link, no_autoconfig, no_onlink, is_no);
1644 
1646  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1647 }
1648 
1649 static void
1651  u32 context,
1652  const ip46_address_t * addr, u32 sw_if_index)
1653 {
1655 
1656  mp = vl_msg_api_alloc (sizeof (*mp));
1657  memset (mp, 0, sizeof (*mp));
1658  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1659  mp->context = context;
1660  mp->sw_if_index = htonl (sw_if_index);
1661  memcpy (mp->address, addr, 16);
1662 
1663  vl_api_send_msg (reg, (u8 *) mp);
1664 }
1665 
1667 {
1670 
1671 static fib_table_walk_rc_t
1673 {
1675 
1677  {
1678  vec_add1 (ctx->indices, fei);
1679  }
1680 
1681  return (FIB_TABLE_WALK_CONTINUE);
1682 }
1683 
1684 static void
1686 {
1687  ip6_main_t *im6 = &ip6_main;
1688  fib_table_t *fib_table;
1690  .indices = NULL,
1691  };
1692  fib_node_index_t *feip;
1693  fib_prefix_t pfx;
1694  vl_api_registration_t *reg;
1695 
1697  if (!reg)
1698  return;
1699 
1700  /* *INDENT-OFF* */
1701  pool_foreach (fib_table, im6->fibs,
1702  ({
1703  fib_table_walk(fib_table->ft_index,
1704  FIB_PROTOCOL_IP6,
1705  api_ip6nd_proxy_fib_table_walk,
1706  &ctx);
1707  }));
1708  /* *INDENT-ON* */
1709 
1711 
1712  vec_foreach (feip, ctx.indices)
1713  {
1714  fib_entry_get_prefix (*feip, &pfx);
1715 
1717  mp->context,
1718  &pfx.fp_addr,
1720  }
1721 
1722  vec_free (ctx.indices);
1723 }
1724 
1725 static void
1727 {
1728  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1729  int rv = 0;
1730 
1731  VALIDATE_SW_IF_INDEX (mp);
1732 
1733  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index),
1734  (ip6_address_t *) mp->address, mp->is_del);
1735 
1737  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1738 }
1739 
1740 static void
1743 {
1744  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
1747  int rv = 0;
1748 
1749  VALIDATE_SW_IF_INDEX (mp);
1750 
1752  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);
1753 
1754  if (rv != 0)
1755  return;
1756 
1757  params.irt = ntohl (mp->irt);
1758  params.mrt = ntohl (mp->mrt);
1759  params.mrc = ntohl (mp->mrc);
1760  params.mrd = ntohl (mp->mrd);
1761 
1762  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
1763  &params);
1764 }
1765 
1766 static void
1769 {
1771  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1772  vnet_main_t *vnm = vnet_get_main ();
1773  int rv = 0;
1774  clib_error_t *error;
1775 
1776  vnm->api_errno = 0;
1777 
1778  VALIDATE_SW_IF_INDEX (mp);
1779 
1780  error =
1781  (mp->enable == 1) ? enable_ip6_interface (vm,
1782  ntohl (mp->sw_if_index)) :
1783  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1784 
1785  if (error)
1786  {
1787  clib_error_report (error);
1788  rv = VNET_API_ERROR_UNSPECIFIED;
1789  }
1790  else
1791  {
1792  rv = vnm->api_errno;
1793  }
1794 
1796 
1797  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1798 }
1799 
1800 static void
1803 {
1805  vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
1806  int rv = 0;
1807  clib_error_t *error;
1808  vnet_main_t *vnm = vnet_get_main ();
1809 
1810  vnm->api_errno = 0;
1811 
1812  VALIDATE_SW_IF_INDEX (mp);
1813 
1814  error = set_ip6_link_local_address (vm,
1815  ntohl (mp->sw_if_index),
1816  (ip6_address_t *) mp->address);
1817  if (error)
1818  {
1819  clib_error_report (error);
1820  rv = VNET_API_ERROR_UNSPECIFIED;
1821  }
1822  else
1823  {
1824  rv = vnm->api_errno;
1825  }
1826 
1828 
1829  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
1830 }
1831 
1832 void
1834  u32 context, const mfib_signal_t * mfs)
1835 {
1838  mfib_table_t *mfib;
1839  mfib_itf_t *mfi;
1840 
1841  mp = vl_msg_api_alloc (sizeof (*mp));
1842 
1843  memset (mp, 0, sizeof (*mp));
1844  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1845  mp->context = context;
1846 
1847  mfi = mfib_itf_get (mfs->mfs_itf);
1848  mfib_entry_get_prefix (mfs->mfs_entry, &prefix);
1850  prefix.fp_proto);
1851  mp->table_id = ntohl (mfib->mft_table_id);
1852  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1853 
1854  if (FIB_PROTOCOL_IP4 == prefix.fp_proto)
1855  {
1856  mp->grp_address_len = ntohs (prefix.fp_len);
1857 
1858  memcpy (mp->grp_address, &prefix.fp_grp_addr.ip4, 4);
1859  if (prefix.fp_len > 32)
1860  {
1861  memcpy (mp->src_address, &prefix.fp_src_addr.ip4, 4);
1862  }
1863  }
1864  else
1865  {
1866  mp->grp_address_len = ntohs (prefix.fp_len);
1867 
1868  ASSERT (0);
1869  }
1870 
1871  if (0 != mfs->mfs_buffer_len)
1872  {
1873  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1874 
1875  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1876  }
1877  else
1878  {
1879  mp->ip_packet_len = 0;
1880  }
1881 
1882  vl_api_send_msg (reg, (u8 *) mp);
1883 }
1884 
1885 static void
1887 {
1888  vl_api_registration_t *reg;
1889 
1891  if (!reg)
1892  return;
1893 
1894  while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
1895  ;
1896 }
1897 
1898 static void
1901 {
1902  vl_api_ip_container_proxy_add_del_reply_t *rmp;
1904  int rv = 0;
1905  clib_error_t *error;
1906 
1907  memset (&args, 0, sizeof (args));
1908  ip_set (&args.prefix.fp_addr, mp->ip, mp->is_ip4);
1909  args.prefix.fp_len = mp->plen ? mp->plen : (mp->is_ip4 ? 32 : 128);
1910  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
1911  args.is_add = mp->is_add;
1912  if ((error = vnet_ip_container_proxy_add_del (&args)))
1913  {
1914  rv = clib_error_get_code (error);
1915  clib_error_report (error);
1916  }
1917 
1918  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
1919 }
1920 
1921 static void
1923 {
1924  int rv = 0;
1925  vl_api_ioam_enable_reply_t *rmp;
1926  clib_error_t *error;
1927 
1928  /* Ignoring the profile id as currently a single profile
1929  * is supported */
1930  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
1931  mp->seqno, mp->analyse);
1932  if (error)
1933  {
1934  clib_error_report (error);
1935  rv = clib_error_get_code (error);
1936  }
1937 
1938  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
1939 }
1940 
1941 static void
1943 {
1944  int rv = 0;
1945  vl_api_ioam_disable_reply_t *rmp;
1946  clib_error_t *error;
1947 
1948  error = clear_ioam_rewrite_fn ();
1949  if (error)
1950  {
1951  clib_error_report (error);
1952  rv = clib_error_get_code (error);
1953  }
1954 
1955  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
1956 }
1957 
1958 static void
1961 {
1962  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
1963  int rv = 0;
1964 
1965  u8 is_ipv6 = mp->is_ipv6;
1966  u8 is_add = mp->is_add;
1967  u8 mask_length = mp->mask_length;
1968  ip4_address_t ip4_addr;
1969  ip6_address_t ip6_addr;
1970  u16 *low_ports = 0;
1971  u16 *high_ports = 0;
1972  u32 vrf_id;
1973  u16 tmp_low, tmp_high;
1974  u8 num_ranges;
1975  int i;
1976 
1977  // Validate port range
1978  num_ranges = mp->number_of_ranges;
1979  if (num_ranges > 32)
1980  { // This is size of array in VPE.API
1981  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1982  goto reply;
1983  }
1984 
1985  vec_reset_length (low_ports);
1986  vec_reset_length (high_ports);
1987 
1988  for (i = 0; i < num_ranges; i++)
1989  {
1990  tmp_low = mp->low_ports[i];
1991  tmp_high = mp->high_ports[i];
1992  // If tmp_low <= tmp_high then only need to check tmp_low = 0
1993  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
1994  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
1995  {
1996  rv = VNET_API_ERROR_INVALID_VALUE;
1997  goto reply;
1998  }
1999  vec_add1 (low_ports, tmp_low);
2000  vec_add1 (high_ports, tmp_high + 1);
2001  }
2002 
2003  // Validate mask_length
2004  if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
2005  {
2006  rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
2007  goto reply;
2008  }
2009 
2010  vrf_id = ntohl (mp->vrf_id);
2011 
2012  if (vrf_id < 1)
2013  {
2014  rv = VNET_API_ERROR_INVALID_VALUE;
2015  goto reply;
2016  }
2017 
2018 
2019  if (is_ipv6)
2020  {
2021  clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
2023  mask_length,
2024  vrf_id,
2025  low_ports,
2026  high_ports, is_add);
2027  }
2028  else
2029  {
2030  clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
2032  mask_length,
2033  vrf_id,
2034  low_ports,
2035  high_ports, is_add);
2036  }
2037 
2038 reply:
2039  vec_free (low_ports);
2040  vec_free (high_ports);
2041  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
2042 }
2043 
2044 static void
2047 {
2049  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
2050  ip4_main_t *im = &ip4_main;
2051  int rv;
2052  u32 sw_if_index;
2055  uword *p = 0;
2056  int i;
2057 
2059  ntohl (mp->tcp_out_vrf_id);
2061  ntohl (mp->udp_out_vrf_id);
2063  ntohl (mp->tcp_in_vrf_id);
2065  ntohl (mp->udp_in_vrf_id);
2066 
2067 
2068  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
2069  {
2070  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
2071  {
2072  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
2073 
2074  if (p == 0)
2075  {
2076  rv = VNET_API_ERROR_INVALID_VALUE;
2077  goto reply;
2078  }
2079 
2080  fib_index[i] = p[0];
2081  }
2082  else
2083  fib_index[i] = ~0;
2084  }
2085  sw_if_index = ntohl (mp->sw_if_index);
2086 
2087  VALIDATE_SW_IF_INDEX (mp);
2088 
2089  rv =
2090  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
2091  mp->is_add);
2092 
2094 reply:
2095 
2096  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
2097 }
2098 
2099 #define IP4_ARP_EVENT 3
2100 #define IP6_ND_EVENT 4
2101 
2102 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
2103 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
2105 
2106 static void
2108 {
2109  vpe_api_main_t *vam = &vpe_api_main;
2110  vnet_main_t *vnm = vam->vnet_main;
2111  vlib_main_t *vm = vam->vlib_main;
2112  vl_api_ip4_arp_event_t *event;
2114  vl_api_registration_t *reg;
2115 
2116  /* Client can cancel, die, etc. */
2117  if (pool_is_free_index (vam->arp_events, pool_index))
2118  return;
2119 
2120  event = pool_elt_at_index (vam->arp_events, pool_index);
2121 
2123  if (!reg)
2124  {
2127  event->pid, &event->address,
2128  ip_resolver_process_node.index, IP4_ARP_EVENT,
2129  ~0 /* pool index, notused */ , 0 /* is_add */ );
2130  return;
2131  }
2132 
2133  if (vl_api_can_send_msg (reg))
2134  {
2135  mp = vl_msg_api_alloc (sizeof (*mp));
2136  clib_memcpy (mp, event, sizeof (*mp));
2137  vl_api_send_msg (reg, (u8 *) mp);
2138  }
2139  else
2140  {
2141  static f64 last_time;
2142  /*
2143  * Throttle syslog msgs.
2144  * It's pretty tempting to just revoke the registration...
2145  */
2146  if (vlib_time_now (vm) > last_time + 10.0)
2147  {
2148  clib_warning ("arp event for %U to pid %d: queue stuffed!",
2149  format_ip4_address, &event->address, event->pid);
2150  last_time = vlib_time_now (vm);
2151  }
2152  }
2153 }
2154 
2155 static void
2157 {
2158  vpe_api_main_t *vam = &vpe_api_main;
2159  vnet_main_t *vnm = vam->vnet_main;
2160  vlib_main_t *vm = vam->vlib_main;
2161  vl_api_ip6_nd_event_t *event;
2163  vl_api_registration_t *reg;
2164 
2165  /* Client can cancel, die, etc. */
2166  if (pool_is_free_index (vam->nd_events, pool_index))
2167  return;
2168 
2169  event = pool_elt_at_index (vam->nd_events, pool_index);
2170 
2172  if (!reg)
2173  {
2176  event->pid, &event->address,
2177  ip_resolver_process_node.index, IP6_ND_EVENT,
2178  ~0 /* pool index, notused */ , 0 /* is_add */ );
2179  return;
2180  }
2181 
2182  if (vl_api_can_send_msg (reg))
2183  {
2184  mp = vl_msg_api_alloc (sizeof (*mp));
2185  clib_memcpy (mp, event, sizeof (*mp));
2186  vl_api_send_msg (reg, (u8 *) mp);
2187  }
2188  else
2189  {
2190  static f64 last_time;
2191  /*
2192  * Throttle syslog msgs.
2193  * It's pretty tempting to just revoke the registration...
2194  */
2195  if (vlib_time_now (vm) > last_time + 10.0)
2196  {
2197  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
2198  format_ip6_address, &event->address, event->pid);
2199  last_time = vlib_time_now (vm);
2200  }
2201  }
2202 }
2203 
2204 static uword
2207 {
2208  volatile f64 timeout = 100.0;
2209  volatile uword *event_data = 0;
2210 
2211  while (1)
2212  {
2214 
2215  uword event_type =
2216  vlib_process_get_events (vm, (uword **) & event_data);
2217 
2218  int i;
2219  switch (event_type)
2220  {
2221  case IP4_ARP_EVENT:
2222  for (i = 0; i < vec_len (event_data); i++)
2223  handle_ip4_arp_event (event_data[i]);
2224  break;
2225 
2226  case IP6_ND_EVENT:
2227  for (i = 0; i < vec_len (event_data); i++)
2228  handle_ip6_nd_event (event_data[i]);
2229  break;
2230 
2231  case ~0: /* timeout */
2232  break;
2233  }
2234 
2235  vec_reset_length (event_data);
2236  }
2237  return 0; /* or not */
2238 }
2239 
2240 /* *INDENT-OFF* */
2241 VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
2242  .function = resolver_process,
2243  .type = VLIB_NODE_TYPE_PROCESS,
2244  .name = "ip-route-resolver-process",
2245 };
2246 /* *INDENT-ON* */
2247 
2248 static int
2249 nd_change_data_callback (u32 pool_index, u8 * new_mac,
2250  u32 sw_if_index, ip6_address_t * address)
2251 {
2253  vl_api_ip6_nd_event_t *event;
2254 
2255  if (pool_is_free_index (am->nd_events, pool_index))
2256  return 1;
2257 
2258  event = pool_elt_at_index (am->nd_events, pool_index);
2259  if (eth_mac_equal (event->new_mac, new_mac) &&
2260  sw_if_index == ntohl (event->sw_if_index))
2261  {
2262  return 1;
2263  }
2264 
2265  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2266  event->sw_if_index = htonl (sw_if_index);
2267  return 0;
2268 }
2269 
2270 static int
2271 arp_change_delete_callback (u32 pool_index, u8 * notused)
2272 {
2274 
2275  if (pool_is_free_index (am->arp_events, pool_index))
2276  return 1;
2277 
2278  pool_put_index (am->arp_events, pool_index);
2279  return 0;
2280 }
2281 
2282 static int
2283 nd_change_delete_callback (u32 pool_index, u8 * notused)
2284 {
2286 
2287  if (pool_is_free_index (am->nd_events, pool_index))
2288  return 1;
2289 
2290  pool_put_index (am->nd_events, pool_index);
2291  return 0;
2292 }
2293 
2295 
2296 enum
2298 
2299 static uword
2301 {
2302  /* These cross the longjmp boundry (vlib_process_wait_for_event)
2303  * and need to be volatile - to prevent them from being optimized into
2304  * a register - which could change during suspension */
2305 
2306  volatile wc_arp_report_t arp_prev = { 0 };
2307  volatile wc_nd_report_t nd_prev = { 0 };
2308  volatile f64 last_arp = vlib_time_now (vm);
2309  volatile f64 last_nd = vlib_time_now (vm);
2310 
2311  while (1)
2312  {
2314  uword event_type = WC_ARP_REPORT;
2315  void *event_data = vlib_process_get_event_data (vm, &event_type);
2316 
2317  f64 now = vlib_time_now (vm);
2318  int i;
2319  if (event_type == WC_ARP_REPORT)
2320  {
2321  wc_arp_report_t *arp_events = event_data;
2322  for (i = 0; i < vec_len (arp_events); i++)
2323  {
2324  /* discard dup event */
2325  if (arp_prev.ip4 == arp_events[i].ip4 &&
2326  eth_mac_equal ((u8 *) arp_prev.mac, arp_events[i].mac) &&
2327  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
2328  (now - last_arp) < 10.0)
2329  {
2330  continue;
2331  }
2332  arp_prev = arp_events[i];
2333  last_arp = now;
2335  /* *INDENT-OFF* */
2336  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
2337  ({
2338  vl_api_registration_t *vl_reg;
2339  vl_reg = vl_api_client_index_to_registration (reg->client_index);
2340  ASSERT (vl_reg != NULL);
2341  if (reg && vl_api_can_send_msg (vl_reg))
2342  {
2343  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
2344  memset (event, 0, sizeof *event);
2345  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2346  event->client_index = reg->client_index;
2347  event->pid = reg->client_pid;
2348  event->mac_ip = 1;
2349  event->address = arp_events[i].ip4;
2350  event->sw_if_index = htonl(arp_events[i].sw_if_index);
2351  memcpy(event->new_mac, arp_events[i].mac, sizeof event->new_mac);
2352  vl_api_send_msg (vl_reg, (u8 *) event);
2353  }
2354  }));
2355  /* *INDENT-ON* */
2356  }
2357  }
2358  else if (event_type == WC_ND_REPORT)
2359  {
2360  wc_nd_report_t *nd_events = event_data;
2361  for (i = 0; i < vec_len (nd_events); i++)
2362  {
2363  /* discard dup event */
2365  ((ip6_address_t *) & nd_prev.ip6, &nd_events[i].ip6)
2366  && eth_mac_equal ((u8 *) nd_prev.mac, nd_events[i].mac)
2367  && nd_prev.sw_if_index == nd_events[i].sw_if_index
2368  && (now - last_nd) < 10.0)
2369  {
2370  continue;
2371  }
2372  nd_prev = nd_events[i];
2373  last_nd = now;
2375  /* *INDENT-OFF* */
2376  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
2377  ({
2378  vl_api_registration_t *vl_reg;
2379  vl_reg = vl_api_client_index_to_registration (reg->client_index);
2380  if (vl_reg && vl_api_can_send_msg (vl_reg))
2381  {
2382  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
2383  memset (event, 0, sizeof *event);
2384  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
2385  event->client_index = reg->client_index;
2386  event->pid = reg->client_pid;
2387  event->mac_ip = 1;
2388  memcpy(event->address, nd_events[i].ip6.as_u8, sizeof event->address);
2389  event->sw_if_index = htonl(nd_events[i].sw_if_index);
2390  memcpy(event->new_mac, nd_events[i].mac, sizeof event->new_mac);
2391  vl_api_send_msg (vl_reg, (u8 *) event);
2392  }
2393  }));
2394  /* *INDENT-ON* */
2395  }
2396  }
2397  else if (event_type == RA_REPORT)
2398  {
2399  ra_report_t *ra_events = event_data;
2400  for (i = 0; i < vec_len (ra_events); i++)
2401  {
2403  call_ip6_neighbor_callbacks (&ra_events[i],
2404  npm->ra_report_functions);
2405 
2407  /* *INDENT-OFF* */
2408  pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
2409  ({
2410  vl_api_registration_t *vl_reg;
2411  vl_reg =
2412  vl_api_client_index_to_registration (reg->client_index);
2413  if (vl_reg && vl_api_can_send_msg (vl_reg))
2414  {
2415  u32 event_size =
2416  sizeof (vl_api_ip6_ra_event_t) +
2417  vec_len (ra_events[i].prefixes) *
2418  sizeof (vl_api_ip6_ra_prefix_info_t);
2419  vl_api_ip6_ra_event_t *event =
2420  vl_msg_api_alloc (event_size);
2421  memset (event, 0, event_size);
2422  event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT);
2423  event->client_index = reg->client_index;
2424  event->pid = reg->client_pid;
2425 
2426  event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);
2427 
2428  memcpy (event->router_address, ra_events[i].router_address, 16);
2429 
2430  event->current_hop_limit = ra_events[i].current_hop_limit;
2431  event->flags = ra_events[i].flags;
2432  event->router_lifetime_in_sec =
2433  clib_host_to_net_u16 (ra_events
2434  [i].router_lifetime_in_sec);
2435  event->neighbor_reachable_time_in_msec =
2436  clib_host_to_net_u32 (ra_events
2437  [i].neighbor_reachable_time_in_msec);
2438  event->time_in_msec_between_retransmitted_neighbor_solicitations
2439  =
2440  clib_host_to_net_u32 (ra_events
2441  [i].time_in_msec_between_retransmitted_neighbor_solicitations);
2442 
2443  event->n_prefixes =
2444  clib_host_to_net_u32 (vec_len (ra_events[i].prefixes));
2445  vl_api_ip6_ra_prefix_info_t *prefix =
2446  (typeof (prefix)) event->prefixes;
2447  u32 j;
2448  for (j = 0; j < vec_len (ra_events[i].prefixes); j++)
2449  {
2450  ra_report_prefix_info_t *info =
2451  &ra_events[i].prefixes[j];
2452  memcpy (prefix->dst_address, info->dst_address.as_u8,
2453  16);
2454  prefix->dst_address_length = info->dst_address_length;
2455  prefix->flags = info->flags;
2456  prefix->valid_time =
2457  clib_host_to_net_u32 (info->valid_time);
2458  prefix->preferred_time =
2459  clib_host_to_net_u32 (info->preferred_time);
2460  prefix++;
2461  }
2462 
2463  vl_api_send_msg (vl_reg, (u8 *) event);
2464  }
2465  }));
2466  /* *INDENT-ON* */
2467  vec_free (ra_events[i].prefixes);
2468  }
2469  }
2470  vlib_process_put_event_data (vm, event_data);
2471  }
2472 
2473  return 0;
2474 }
2475 
2476 /* *INDENT-OFF* */
2478  .function = wc_arp_process,
2479  .type = VLIB_NODE_TYPE_PROCESS,
2480  .name = "wildcard-ip4-arp-publisher-process",
2481 };
2482 /* *INDENT-ON* */
2483 
2484 static int
2485 arp_change_data_callback (u32 pool_index, u8 * new_mac,
2486  u32 sw_if_index, u32 address)
2487 {
2489  vl_api_ip4_arp_event_t *event;
2490 
2491  if (pool_is_free_index (am->arp_events, pool_index))
2492  return 1;
2493 
2494  event = pool_elt_at_index (am->arp_events, pool_index);
2495  if (eth_mac_equal (event->new_mac, new_mac) &&
2496  sw_if_index == ntohl (event->sw_if_index))
2497  {
2498  return 1;
2499  }
2500 
2501  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2502  event->sw_if_index = htonl (sw_if_index);
2503  return 0;
2504 }
2505 
2506 static void
2508 {
2510  vnet_main_t *vnm = vnet_get_main ();
2511  vl_api_want_ip4_arp_events_reply_t *rmp;
2512  int rv = 0;
2513 
2514  if (mp->address == 0)
2515  {
2516  uword *p =
2517  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
2519  if (p)
2520  {
2521  if (mp->enable_disable)
2522  {
2523  clib_warning ("pid %d: already enabled...", mp->pid);
2524  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2525  goto reply;
2526  }
2527  else
2528  {
2529  rp =
2530  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2531  pool_put (am->wc_ip4_arp_events_registrations, rp);
2532  hash_unset (am->wc_ip4_arp_events_registration_hash,
2533  mp->client_index);
2534  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2536  goto reply;
2537  }
2538  }
2539  if (mp->enable_disable == 0)
2540  {
2541  clib_warning ("pid %d: already disabled...", mp->pid);
2542  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2543  goto reply;
2544  }
2545  pool_get (am->wc_ip4_arp_events_registrations, rp);
2546  rp->client_index = mp->client_index;
2547  rp->client_pid = mp->pid;
2548  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
2549  rp - am->wc_ip4_arp_events_registrations);
2551  goto reply;
2552  }
2553 
2554  if (mp->enable_disable)
2555  {
2556  vl_api_ip4_arp_event_t *event;
2557  pool_get (am->arp_events, event);
2560  mp->pid, &mp->address /* addr, in net byte order */ ,
2562  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2563 
2564  if (rv)
2565  {
2566  pool_put (am->arp_events, event);
2567  goto reply;
2568  }
2569  memset (event, 0, sizeof (*event));
2570 
2571  /* Python API expects events to have no context */
2572  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2573  event->client_index = mp->client_index;
2574  event->address = mp->address;
2575  event->pid = mp->pid;
2576  if (mp->address == 0)
2577  event->mac_ip = 1;
2578  }
2579  else
2580  {
2583  mp->pid, &mp->address /* addr, in net byte order */ ,
2585  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2586  }
2587 reply:
2588  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2589 }
2590 
2591 static clib_error_t *
2593 {
2595  vl_api_ip4_arp_event_t *event;
2596  u32 *to_delete, *event_id;
2597  vpe_api_main_t *am;
2598  vnet_main_t *vnm;
2599  uword *p;
2600 
2601  am = &vpe_api_main;
2602  vnm = vnet_get_main ();
2603  to_delete = NULL;
2604 
2605  /* clear out all of its pending resolutions */
2606  /* *INDENT-OFF* */
2607  pool_foreach(event, am->arp_events,
2608  ({
2609  if (event->client_index == client_index)
2610  {
2611  vec_add1(to_delete, event - am->arp_events);
2612  }
2613  }));
2614  /* *INDENT-ON* */
2615 
2616  vec_foreach (event_id, to_delete)
2617  {
2618  event = pool_elt_at_index (am->arp_events, *event_id);
2621  event->pid, &event->address,
2623  ~0 /* pool index, notused */ , 0 /* is_add */ );
2624  }
2625  vec_free (to_delete);
2626 
2627  /* remove from the registration hash */
2628  p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index);
2629 
2630  if (p)
2631  {
2632  rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2633  pool_put (am->wc_ip4_arp_events_registrations, rp);
2634  hash_unset (am->wc_ip4_arp_events_registration_hash, client_index);
2635  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2637  }
2638  return (NULL);
2639 }
2640 
2642 
2643 static void
2645 {
2647  vnet_main_t *vnm = vnet_get_main ();
2648  vl_api_want_ip6_nd_events_reply_t *rmp;
2649  int rv = 0;
2650 
2652  {
2653  uword *p =
2654  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
2656  if (p)
2657  {
2658  if (mp->enable_disable)
2659  {
2660  clib_warning ("pid %d: already enabled...", mp->pid);
2661  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2662  goto reply;
2663  }
2664  else
2665  {
2666  rp =
2667  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2668  pool_put (am->wc_ip6_nd_events_registrations, rp);
2669  hash_unset (am->wc_ip6_nd_events_registration_hash,
2670  mp->client_index);
2671  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2673  goto reply;
2674  }
2675  }
2676  if (mp->enable_disable == 0)
2677  {
2678  clib_warning ("pid %d: already disabled...", mp->pid);
2679  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2680  goto reply;
2681  }
2682  pool_get (am->wc_ip6_nd_events_registrations, rp);
2683  rp->client_index = mp->client_index;
2684  rp->client_pid = mp->pid;
2685  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
2686  rp - am->wc_ip6_nd_events_registrations);
2688  goto reply;
2689  }
2690 
2691  if (mp->enable_disable)
2692  {
2693  vl_api_ip6_nd_event_t *event;
2694  pool_get (am->nd_events, event);
2695 
2698  mp->pid, mp->address /* addr, in net byte order */ ,
2700  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
2701 
2702  if (rv)
2703  {
2704  pool_put (am->nd_events, event);
2705  goto reply;
2706  }
2707  memset (event, 0, sizeof (*event));
2708 
2709  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2710  event->client_index = mp->client_index;
2711  clib_memcpy (event->address, mp->address, sizeof event->address);
2712  event->pid = mp->pid;
2713  }
2714  else
2715  {
2718  mp->pid, mp->address /* addr, in net byte order */ ,
2720  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2721  }
2722 reply:
2723  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
2724 }
2725 
2726 static clib_error_t *
2728 {
2729 
2731  vl_api_ip6_nd_event_t *event;
2732  u32 *to_delete, *event_id;
2733  vpe_api_main_t *am;
2734  vnet_main_t *vnm;
2735  uword *p;
2736 
2737  am = &vpe_api_main;
2738  vnm = vnet_get_main ();
2739  to_delete = NULL;
2740 
2741  /* clear out all of its pending resolutions */
2742  /* *INDENT-OFF* */
2743  pool_foreach(event, am->nd_events,
2744  ({
2745  if (event->client_index == client_index)
2746  {
2747  vec_add1(to_delete, event - am->nd_events);
2748  }
2749  }));
2750  /* *INDENT-ON* */
2751 
2752  vec_foreach (event_id, to_delete)
2753  {
2754  event = pool_elt_at_index (am->nd_events, *event_id);
2757  event->pid, &event->address,
2759  ~0 /* pool index, notused */ , 0 /* is_add */ );
2760  }
2761  vec_free (to_delete);
2762 
2763  /* remove from the registration hash */
2764  p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index);
2765 
2766  if (p)
2767  {
2768  rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2769  pool_put (am->wc_ip6_nd_events_registrations, rp);
2770  hash_unset (am->wc_ip6_nd_events_registration_hash, client_index);
2771  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2773  }
2774  return (NULL);
2775 }
2776 
2778 
2779 static void
2781 {
2783  vl_api_want_ip6_ra_events_reply_t *rmp;
2784  int rv = 0;
2785 
2786  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
2788  if (p)
2789  {
2790  if (mp->enable_disable)
2791  {
2792  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
2793  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2794  goto reply;
2795  }
2796  else
2797  {
2798  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2799  pool_put (am->ip6_ra_events_registrations, rp);
2800  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
2801  goto reply;
2802  }
2803  }
2804  if (mp->enable_disable == 0)
2805  {
2806  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
2807  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2808  goto reply;
2809  }
2810  pool_get (am->ip6_ra_events_registrations, rp);
2811  rp->client_index = mp->client_index;
2812  rp->client_pid = ntohl (mp->pid);
2813  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
2814  rp - am->ip6_ra_events_registrations);
2815 
2816 reply:
2817  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
2818 }
2819 
2820 static clib_error_t *
2822 {
2825  uword *p;
2826 
2827  p = hash_get (am->ip6_ra_events_registration_hash, client_index);
2828 
2829  if (p)
2830  {
2831  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2832  pool_put (am->ip6_ra_events_registrations, rp);
2833  hash_unset (am->ip6_ra_events_registration_hash, client_index);
2834  }
2835  return (NULL);
2836 }
2837 
2839 
2840 static void
2842 {
2843  vl_api_proxy_arp_add_del_reply_t *rmp;
2844  u32 fib_index;
2845  int rv;
2846  ip4_main_t *im = &ip4_main;
2847  uword *p;
2848 
2849  stats_dslock_with_hint (1 /* release hint */ , 6 /* tag */ );
2850 
2851  p = hash_get (im->fib_index_by_table_id, ntohl (mp->proxy.vrf_id));
2852 
2853  if (!p)
2854  {
2855  rv = VNET_API_ERROR_NO_SUCH_FIB;
2856  goto out;
2857  }
2858 
2859  fib_index = p[0];
2860 
2862  (ip4_address_t *) mp->proxy.hi_address,
2863  fib_index, mp->is_add == 0);
2864 
2865 out:
2866  stats_dsunlock ();
2867  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2868 }
2869 
2871 {
2875 
2876 static walk_rc_t
2878  const ip4_address_t * hi_addr,
2879  u32 fib_index, void *data)
2880 {
2883 
2884  ctx = data;
2885 
2886  mp = vl_msg_api_alloc (sizeof (*mp));
2887  memset (mp, 0, sizeof (*mp));
2888  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
2889  mp->context = ctx->context;
2890  mp->proxy.vrf_id = htonl (fib_index);
2891  clib_memcpy (mp->proxy.low_address, lo_addr,
2892  sizeof (mp->proxy.low_address));
2893  clib_memcpy (mp->proxy.hi_address, hi_addr, sizeof (mp->proxy.hi_address));
2894 
2895  vl_api_send_msg (ctx->reg, (u8 *) mp);
2896 
2897  return (WALK_CONTINUE);
2898 }
2899 
2900 static void
2902 {
2903  vl_api_registration_t *reg;
2904 
2906  if (!reg)
2907  return;
2908 
2909  proxy_arp_walk_ctx_t wctx = {
2910  .reg = reg,
2911  .context = mp->context,
2912  };
2913 
2915 }
2916 
2917 static walk_rc_t
2919  vnet_sw_interface_t * si, void *data)
2920 {
2923 
2925  return (WALK_CONTINUE);
2926 
2927  ctx = data;
2928 
2929  mp = vl_msg_api_alloc (sizeof (*mp));
2930  memset (mp, 0, sizeof (*mp));
2931  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS);
2932  mp->context = ctx->context;
2933  mp->sw_if_index = htonl (si->sw_if_index);
2934 
2935  vl_api_send_msg (ctx->reg, (u8 *) mp);
2936 
2937  return (WALK_CONTINUE);
2938 }
2939 
2940 static void
2942 {
2943  vl_api_registration_t *reg;
2944 
2946  if (!reg)
2947  return;
2948 
2949  proxy_arp_walk_ctx_t wctx = {
2950  .reg = reg,
2951  .context = mp->context,
2952  };
2953 
2956 }
2957 
2958 static void
2961 {
2962  int rv = 0;
2963  vnet_main_t *vnm = vnet_get_main ();
2964  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2965 
2966  VALIDATE_SW_IF_INDEX (mp);
2967 
2968  vnet_sw_interface_t *si =
2969  vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
2970 
2971  ASSERT (si);
2972 
2973  if (mp->enable_disable)
2975  else
2977 
2979 
2980  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2981 }
2982 
2983 static void
2985 {
2986  int rv = 0;
2988  vl_api_ip_probe_neighbor_reply_t *rmp;
2989  clib_error_t *error;
2990 
2991  VALIDATE_SW_IF_INDEX (mp);
2992 
2993  u32 sw_if_index = ntohl (mp->sw_if_index);
2994 
2995  if (mp->is_ipv6)
2996  error = ip6_probe_neighbor (vm, (ip6_address_t *) mp->dst_address,
2997  sw_if_index, 0);
2998  else
2999  error = ip4_probe_neighbor (vm, (ip4_address_t *) mp->dst_address,
3000  sw_if_index, 0);
3001 
3002  if (error)
3003  {
3004  clib_error_report (error);
3005  rv = clib_error_get_code (error);
3006  }
3007 
3009 
3010  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
3011 }
3012 
3013 static void
3016 {
3017  int rv = 0;
3018  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
3020 
3021  arg.mode = mp->mode;
3022  arg.scan_interval = mp->scan_interval;
3023  arg.max_proc_time = mp->max_proc_time;
3024  arg.max_update = mp->max_update;
3025  arg.scan_int_delay = mp->scan_int_delay;
3026  arg.stale_threshold = mp->stale_threshold;
3028 
3029  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
3030 }
3031 
3032 static int
3034 {
3035  vnet_main_t *vnm = vnet_get_main ();
3037  ip4_main_t *im4 = &ip4_main;
3038  static u32 *sw_if_indices_to_shut;
3039  fib_table_t *fib_table;
3040  ip4_fib_t *fib;
3041  u32 sw_if_index;
3042  int i;
3043  int rv = VNET_API_ERROR_NO_SUCH_FIB;
3044  u32 target_fib_id = ntohl (mp->vrf_id);
3045 
3046  stats_dslock_with_hint (1 /* release hint */ , 8 /* tag */ );
3047 
3048  /* *INDENT-OFF* */
3049  pool_foreach (fib_table, im4->fibs,
3050  ({
3051  vnet_sw_interface_t * si;
3052 
3053  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
3054 
3055  if (fib->table_id != target_fib_id)
3056  continue;
3057 
3058  /* remove any mpls encap/decap labels */
3059  mpls_fib_reset_labels (fib->table_id);
3060 
3061  /* remove any proxy arps in this fib */
3062  vnet_proxy_arp_fib_reset (fib->table_id);
3063 
3064  /* Set the flow hash for this fib to the default */
3065  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
3066 
3067  vec_reset_length (sw_if_indices_to_shut);
3068 
3069  /* Shut down interfaces in this FIB / clean out intfc routes */
3070  pool_foreach (si, im->sw_interfaces,
3071  ({
3072  u32 sw_if_index = si->sw_if_index;
3073 
3074  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
3075  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
3076  fib->index))
3077  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3078  }));
3079 
3080  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
3081  sw_if_index = sw_if_indices_to_shut[i];
3082 
3083  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3084  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3085  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3086  }
3087 
3089 
3090  rv = 0;
3091  break;
3092  })); /* pool_foreach (fib) */
3093  /* *INDENT-ON* */
3094 
3095  stats_dsunlock ();
3096  return rv;
3097 }
3098 
3099 static int
3101 {
3102  vnet_main_t *vnm = vnet_get_main ();
3104  ip6_main_t *im6 = &ip6_main;
3105  static u32 *sw_if_indices_to_shut;
3106  fib_table_t *fib_table;
3107  ip6_fib_t *fib;
3108  u32 sw_if_index;
3109  int i;
3110  int rv = VNET_API_ERROR_NO_SUCH_FIB;
3111  u32 target_fib_id = ntohl (mp->vrf_id);
3112 
3113  stats_dslock_with_hint (1 /* release hint */ , 9 /* tag */ );
3114 
3115  /* *INDENT-OFF* */
3116  pool_foreach (fib_table, im6->fibs,
3117  ({
3118  vnet_sw_interface_t * si;
3119 
3120  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
3121 
3122  if (fib->table_id != target_fib_id)
3123  continue;
3124 
3125  vec_reset_length (sw_if_indices_to_shut);
3126 
3127  /* Set the flow hash for this fib to the default */
3128  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
3129 
3130  /* Shut down interfaces in this FIB / clean out intfc routes */
3131  pool_foreach (si, im->sw_interfaces,
3132  ({
3133  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
3134  fib->index)
3135  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3136  }));
3137 
3138  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
3139  sw_if_index = sw_if_indices_to_shut[i];
3140 
3141  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3142  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3143  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3144  }
3145 
3147 
3148  rv = 0;
3149  break;
3150  })); /* pool_foreach (fib) */
3151  /* *INDENT-ON* */
3152 
3153  stats_dsunlock ();
3154  return rv;
3155 }
3156 
3157 static void
3159 {
3160  int rv;
3161  vl_api_reset_fib_reply_t *rmp;
3162 
3163  if (mp->is_ipv6)
3164  rv = ip6_reset_fib_t_handler (mp);
3165  else
3166  rv = ip4_reset_fib_t_handler (mp);
3167 
3168  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
3169 }
3170 
3171 static void
3173 {
3174  int rv;
3175  vl_api_set_arp_neighbor_limit_reply_t *rmp;
3176  vnet_main_t *vnm = vnet_get_main ();
3177  clib_error_t *error;
3178 
3179  vnm->api_errno = 0;
3180 
3181  if (mp->is_ipv6)
3182  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
3183  else
3184  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
3185 
3186  if (error)
3187  {
3188  clib_error_report (error);
3189  rv = VNET_API_ERROR_UNSPECIFIED;
3190  }
3191  else
3192  {
3193  rv = vnm->api_errno;
3194  }
3195 
3196  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3197 }
3198 
3199 void
3201 {
3202  vl_api_ip_reassembly_set_reply_t *rmp;
3203  int rv = 0;
3204  if (mp->is_ip6)
3205  {
3206  rv = ip6_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
3207  clib_net_to_host_u32 (mp->max_reassemblies),
3208  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
3209  }
3210  else
3211  {
3212  rv = ip4_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
3213  clib_net_to_host_u32 (mp->max_reassemblies),
3214  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
3215  }
3216 
3217  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
3218 }
3219 
3220 void
3222 {
3224 
3226 
3227  if (q == 0)
3228  return;
3229 
3230  vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
3231  memset (rmp, 0, sizeof (*rmp));
3232  rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
3233  rmp->context = mp->context;
3234  rmp->retval = 0;
3235  if (mp->is_ip6)
3236  {
3237  rmp->is_ip6 = 1;
3239  &rmp->expire_walk_interval_ms);
3240  }
3241  else
3242  {
3243  rmp->is_ip6 = 0;
3245  &rmp->expire_walk_interval_ms);
3246  }
3247  rmp->timeout_ms = clib_host_to_net_u32 (rmp->timeout_ms);
3248  rmp->max_reassemblies = clib_host_to_net_u32 (rmp->max_reassemblies);
3250  clib_host_to_net_u32 (rmp->expire_walk_interval_ms);
3251  vl_msg_api_send_shmem (q, (u8 *) & rmp);
3252 }
3253 
3254 void
3257 {
3258  vl_api_ip_reassembly_enable_disable_reply_t *rmp;
3259  int rv = 0;
3260  rv = ip4_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
3261  mp->enable_ip4);
3262  if (0 == rv)
3263  {
3264  rv = ip6_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
3265  mp->enable_ip6);
3266  }
3267 
3268  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
3269 }
3270 
3271 #define vl_msg_name_crc_list
3272 #include <vnet/ip/ip.api.h>
3273 #undef vl_msg_name_crc_list
3274 
3275 static void
3277 {
3278 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
3279  foreach_vl_msg_name_crc_ip;
3280 #undef _
3281 }
3282 
3283 static clib_error_t *
3285 {
3286  api_main_t *am = &api_main;
3287 
3288 #define _(N,n) \
3289  vl_msg_api_set_handlers(VL_API_##N, #n, \
3290  vl_api_##n##_t_handler, \
3291  vl_noop_handler, \
3292  vl_api_##n##_t_endian, \
3293  vl_api_##n##_t_print, \
3294  sizeof(vl_api_##n##_t), 1);
3296 #undef _
3297 
3298  /*
3299  * Set up the (msg_name, crc, message-id) table
3300  */
3302 
3304 
3305  return 0;
3306 }
3307 
3309 
3310 /*
3311  * fd.io coding-style-patch-verification: ON
3312  *
3313  * Local Variables:
3314  * eval: (c-set-style "gnu")
3315  * End:
3316  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:437
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:179
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:202
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:668
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1626
static void vl_api_proxy_arp_intfc_enable_disable_t_handler(vl_api_proxy_arp_intfc_enable_disable_t *mp)
Definition: ip_api.c:2960
Proxy ARP add / del request.
Definition: ip.api:882
void ip_null_dpo_add_and_lock(dpo_proto_t proto, ip_null_dpo_action_t action, dpo_id_t *dpo)
Definition: ip_null_dpo.c:78
ip46_address_t frp_addr
The next-hop address.
Definition: fib_types.h:476
Dump IP unnumbered configurations.
Definition: ip.api:544
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:887
Continue on to the next entry.
Definition: fib_table.h:857
typedef address
Definition: ip_types.api:35
VL_MSG_API_REAPER_FUNCTION(want_ip4_arp_events_reaper)
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
A path that resolves via a DVR DPO.
Definition: fib_types.h:371
#define hash_set(h, key, value)
Definition: hash.h:255
vl_api_proxy_arp_t proxy
Definition: ip.api:904
Register for IP6 ND resolution event on recieving NA reply MAC/IP info from ICMP6 Neighbor Solicitati...
Definition: ip.api:769
static void vl_api_ip6nd_proxy_add_del_t_handler(vl_api_ip6nd_proxy_add_del_t *mp)
Definition: ip_api.c:1726
void receive_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, const ip46_address_t *nh_addr, dpo_id_t *dpo)
Definition: receive_dpo.c:56
Pipe Mode - the default.
Definition: fib_types.h:394
#define clib_min(x, y)
Definition: clib.h:289
vnet_main_t * vnet_main
Reset fib table request.
Definition: ip.api:945
static void send_ip6_mfib_details(vpe_api_main_t *am, vl_api_registration_t *reg, u32 table_id, mfib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:495
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:569
static void vl_api_ip_container_proxy_add_del_t_handler(vl_api_ip_container_proxy_add_del_t *mp)
Definition: ip_api.c:1900
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:487
int vnet_set_ip4_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip4_forward.c:2699
Register for ip6 router advertisement events.
Definition: ip.api:808
static uword resolver_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:2205
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
Dump IP neighboors.
Definition: ip.api:108
IP punt redirect.
Definition: ip.api:609
#define hash_unset(h, key)
Definition: hash.h:261
Dump IP fib table.
Definition: ip.api:51
a
Definition: bitmap.h:538
vl_api_fib_path_t path[count]
Definition: ip.api:480
vl_api_fib_path_t path[count]
Definition: ip.api:72
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:619
A representation of a path as described by a route producer.
Definition: fib_types.h:460
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:653
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
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:2877
vnet_interface_main_t interface_main
Definition: vnet.h:56
IP FIB table response.
Definition: ip.api:64
IPv6 Reassembly.
void icmp6_send_router_solicitation(vlib_main_t *vm, u32 sw_if_index, u8 stop, icmp6_send_router_solicitation_params_t *params)
The table that stores ALL routes learned by the DP.
Definition: ip6.h:135
void ip4_punt_redirect_del(u32 rx_sw_if_index)
u8 as_u8[16]
Definition: ip6_packet.h:48
A pair of indicies, for the entry and interface resp.
Definition: mfib_signal.h:29
void fib_entry_get_prefix(fib_node_index_t fib_entry_index, fib_prefix_t *pfx)
Definition: fib_entry.c:1616
Dump IP multicast fib table.
Definition: ip.api:456
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:1124
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:90
fib_node_index_t fib_table_entry_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, fib_route_path_t *paths)
Update an entry to have a new set of paths.
Definition: fib_table.c:723
Proxy ARP interface dump request.
Definition: ip.api:924
clib_error_t * call_ip6_neighbor_callbacks(void *data, _vnet_ip6_neighbor_function_list_elt_t *elt)
#define NULL
Definition: clib.h:55
iOAM disable
Definition: ip.api:991
An entry in a FIB table.
Definition: mfib_entry.h:31
Set max allowed ARP or ip6 neighbor entries request.
Definition: ip.api:959
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:228
static int arp_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, u32 address)
Definition: ip_api.c:2485
fib_node_index_t fib_table_entry_path_add2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, fib_route_path_t *rpath)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:556
A path that resolves via a BIER impostion object.
Definition: fib_types.h:363
int vnet_add_del_ip6_nd_change_event(vnet_main_t *vnm, void *data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
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:2100
clib_error_t * ip4_set_arp_limit(u32 arp_limit)
Definition: arp.c:1526
index_t frp_bier_imp
A path via a BIER imposition object.
Definition: fib_types.h:527
ip6_neighbor_t * ip6_neighbors_entries(u32 sw_if_index)
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
IPv4 Reassembly.
static int arp_change_delete_callback(u32 pool_index, u8 *notused)
Definition: ip_api.c:2271
From the CLI.
Definition: fib_entry.h:78
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
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:706
ip_lookup_main_t lookup_main
Definition: ip4.h:97
void vl_api_ip_reassembly_set_t_handler(vl_api_ip_reassembly_set_t *mp)
Definition: ip_api.c:3200
static void send_ip_mfib_details(vl_api_registration_t *reg, u32 context, u32 table_id, fib_node_index_t mfei)
Definition: ip_api.c:398
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
vlib_main_t * vlib_main
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:165
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:465
IPv6 router advertisement config request.
Definition: ip.api:202
static void vl_api_proxy_arp_intfc_dump_t_handler(vl_api_proxy_arp_intfc_dump_t *mp)
Definition: ip_api.c:2941
Definition: fib_entry.h:284
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:2727
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:339
u8 hi_address[4]
Definition: ip.api:873
void vl_api_ip_reassembly_enable_disable_t_handler(vl_api_ip_reassembly_enable_disable_t *mp)
Definition: ip_api.c:3256
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:228
static void vl_api_ip6nd_proxy_dump_t_handler(vl_api_ip6nd_proxy_dump_t *mp)
Definition: ip_api.c:1685
vl_api_fib_mpls_label_t next_hop_out_label_stack[next_hop_n_out_labels]
Definition: ip.api:422
void * vl_msg_api_alloc(int nbytes)
static void api_ip6_fib_table_put_entries(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip_api.c:331
static fib_table_walk_rc_t api_ip6nd_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:1672
vhost_vring_addr_t addr
Definition: vhost_user.h:116
Dump IP6 fib table.
Definition: ip.api:78
#define IP4_ARP_EVENT
Definition: ip_api.c:2099
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:3221
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
double f64
Definition: types.h:142
static void vl_api_ip_mfib_dump_t_handler(vl_api_ip_mfib_dump_t *mp)
Definition: ip_api.c:457
static int nd_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, ip6_address_t *address)
Definition: ip_api.c:2249
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:343
enum walk_rc_t_ walk_rc_t
Walk return code.
ip6_neighbor_flags_t flags
Definition: ip6_neighbor.h:42
static int vl_api_can_send_msg(vl_api_registration_t *rp)
Definition: api.h:47
static void handle_ip4_arp_event(u32 pool_index)
Definition: ip_api.c:2107
format_function_t format_ip4_address
Definition: format.h:81
Proxy ARP add / del interface request.
Definition: ip.api:913
#define VNET_SW_INTERFACE_FLAG_PROXY_ARP
Definition: interface.h:666
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:443
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:495
Add / del table request A table can be added multiple times, but need be deleted only once...
Definition: ip.api:38
Start / stop sending router solicitation.
Definition: ip.api:320
void ip_neighbor_scan_enable_disable(ip_neighbor_scan_arg_t *arg)
Definition: ip_neighbor.c:51
static uword vlib_process_get_events(vlib_main_t *vm, uword **data_vector)
Return the first event type which has occurred and a vector of per-event data of that type...
Definition: node_funcs.h:542
static int add_del_mroute_check(fib_protocol_t table_proto, u32 table_id, u32 next_hop_sw_if_index, u8 is_local, u32 *fib_index)
Definition: ip_api.c:1184
Dump IP6 multicast fib table.
Definition: ip.api:486
void fib_table_entry_special_remove(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Remove a &#39;special&#39; entry from the FIB.
Definition: fib_table.c:407
clib_error_t * vnet_ip_container_proxy_add_del(vnet_ip_container_proxy_args_t *args)
Definition: lookup.c:1267
vl_api_fib_path_t path[count]
Definition: ip.api:508
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:309
static BVT(clib_bihash)
Definition: adj_nbr.c:26
svm_queue_t unix_shared_memory_queue_t
Definition: queue.h:77
static uword ip6_address_is_equal(ip6_address_t *a, ip6_address_t *b)
Definition: ip6_packet.h:214
Recursion constraint of via a host prefix.
Definition: fib_types.h:314
void proxy_arp_walk(proxy_arp_walk_t cb, void *data)
Definition: arp.c:2001
static void vl_api_ip6_mfib_dump_t_handler(vl_api_ip6_mfib_dump_t *mp)
Definition: ip_api.c:548
Set interface source and L4 port-range request.
Definition: ip.api:665
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:476
int vnet_set_ip6_ethernet_neighbor(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *a, u8 *link_layer_address, uword n_bytes_link_layer_address, int is_static, int is_no_fib_entry)
Definition: ip6_neighbor.c:764
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:1326
Aggregrate type for a prefix.
Definition: fib_types.h:193
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:1499
vnet_api_error_t ip6_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 expire_walk_interval_ms)
set ip6 reassembly configuration
struct vl_api_ip_mfib_dump_ctc_t_ vl_api_ip_mfib_dump_ctc_t
static int ip6_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:1057
static void api_ip6_fib_table_get_all(vl_api_registration_t *reg, vl_api_ip6_fib_dump_t *mp, fib_table_t *fib_table)
Definition: ip_api.c:342
fib_node_index_t mfib_table_entry_path_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath, mfib_itf_flags_t itf_flags)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:219
IPv6 interface enable / disable request.
Definition: ip.api:338
A path via a UDP encap object.
Definition: fib_types.h:351
struct proxy_arp_walk_ctx_t_ proxy_arp_walk_ctx_t
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
unsigned int u32
Definition: types.h:88
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip4.h:106
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
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:1056
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:253
u16 fp_len
The mask length.
Definition: fib_types.h:197
static void vl_api_set_arp_neighbor_limit_t_handler(vl_api_set_arp_neighbor_limit_t *mp)
Definition: ip_api.c:3172
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1886
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index, u8 refresh)
Definition: ip6_forward.c:1438
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1568
int vnet_arp_unset_ip4_over_ethernet(vnet_main_t *vnm, u32 sw_if_index, void *a_arg)
Control Plane hook to remove an ARP entry.
Definition: arp.c:1538
static void vl_api_ip_scan_neighbor_enable_disable_t_handler(vl_api_ip_scan_neighbor_enable_disable_t *mp)
Definition: ip_api.c:3015
u32 mfib_entry_get_fib_index(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1232
Definition: fib_entry.h:275
Configure IP source and L4 port-range check.
Definition: ip.api:644
vnet_api_error_t api_errno
Definition: vnet.h:78
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:168
static int mroute_add_del_handler(u8 is_add, u8 is_local, u32 fib_index, const mfib_prefix_t *prefix, dpo_proto_t nh_proto, u32 entry_flags, fib_rpf_id_t rpf_id, u32 next_hop_sw_if_index, ip46_address_t *nh, u32 itf_flags, u32 bier_imp)
Definition: ip_api.c:1210
#define hash_get(h, key)
Definition: hash.h:249
static int vl_api_ip6_mfib_table_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:538
Definition: fib_entry.h:279
static void vl_api_want_ip6_nd_events_t_handler(vl_api_want_ip6_nd_events_t *mp)
Definition: ip_api.c:2644
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:464
IP probe neighbor address on an interface by sending an ARP request (for IP4) or ICMP6 Neighbor Solic...
Definition: ip.api:709
static fib_table_walk_rc_t vl_api_ip_fib_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:233
vnet_api_error_t ip4_reass_set(u32 timeout_ms, u32 max_reassemblies, u32 expire_walk_interval_ms)
set ip4 reassembly configuration
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
Definition: ip4.h:121
static mfib_itf_t * mfib_itf_get(index_t mi)
Get the MFIB interface representation.
Definition: mfib_itf.h:78
void vnet_sw_interface_walk(vnet_main_t *vnm, vnet_sw_interface_walk_t fn, void *ctx)
Walk all the SW interfaces in the system.
Definition: interface.c:1078
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:558
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:216
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:43
ip4_address_t ip4_address
Definition: arp_packet.h:153
int vnet_unset_ip6_ethernet_neighbor(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *a, u8 *link_layer_address, uword n_bytes_link_layer_address)
Definition: ip6_neighbor.c:924
u32 sw_if_index
Definition: arp_packet.h:152
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:741
static void vl_api_proxy_arp_add_del_t_handler(vl_api_proxy_arp_add_del_t *mp)
Definition: ip_api.c:2841
u8 ethernet_address[6]
Definition: arp_packet.h:155
static void vl_api_sw_interface_ip6nd_ra_prefix_t_handler(vl_api_sw_interface_ip6nd_ra_prefix_t *mp)
Definition: ip_api.c:1622
vnet_api_error_t ip4_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *expire_walk_interval_ms)
get ip4 reassembly configuration
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:274
static int nd_change_delete_callback(u32 pool_index, u8 *notused)
Definition: ip_api.c:2283
IP6 Multicast FIB table response.
Definition: ip.api:500
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:600
vl_api_fib_path_t path[count]
Definition: ip.api:99
Configuration for each label value in the output-stack.
Definition: fib_types.h:415
#define REPLY_MACRO(t)
static void send_ip_neighbor_details(u32 sw_if_index, u8 is_ipv6, u8 is_static, u8 *mac_address, u8 *ip_address, vl_api_registration_t *reg, u32 context)
Definition: ip_api.c:120
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:318
Proxy ARP dump details reply.
Definition: ip.api:901
u32 index
Definition: ip6.h:76
fib_node_index_t * entries
Definition: ip_api.c:327
Tell client about an IP4 ARP resolution event or MAC/IP info from ARP requests in L2 BDs...
Definition: ip.api:745
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:1650
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:1228
static void vl_api_sw_interface_ip6_enable_disable_t_handler(vl_api_sw_interface_ip6_enable_disable_t *mp)
Definition: ip_api.c:1768
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1577
fib_mpls_lsp_mode_t fml_mode
The LSP mode.
Definition: fib_types.h:425
void ra_set_publisher_node(uword node_index, uword event_type)
Definition: ip6_neighbor.c:328
IOAM enable : Enable in-band OAM.
Definition: ip.api:974
static mfib_entry_t * mfib_entry_get(fib_node_index_t index)
Definition: mfib_entry.h:153
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:1921
void stats_dsunlock(void)
static void vl_api_ip_unnumbered_dump_t_handler(vl_api_ip_unnumbered_dump_t *mp)
Definition: ip_api.c:1449
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:201
u32 flags
Definition: vhost_user.h:110
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1409
static clib_error_t * want_ip6_ra_events_reaper(u32 client_index)
Definition: ip_api.c:2821
An API client registration, only in vpp/vlib.
Definition: api_common.h:44
void clib_bihash_foreach_key_value_pair(clib_bihash *h, void *callback, void *arg)
Visit active (key,value) pairs in a bi-hash table.
void wc_nd_set_publisher_node(uword node_index, uword event_type)
Definition: ip6_neighbor.c:297
vl_api_registration_t * reg
Definition: ip_api.c:2872
The IPv4 FIB.
Definition: ip4_fib.h:39
#define BAD_SW_IF_INDEX_LABEL
Proxy ARP interface dump details reply.
Definition: ip.api:933
struct vl_api_ip6_mfib_dump_ctc_t_ vl_api_ip6_mfib_dump_ctc_t
fib_node_index_t ft_index
Index into FIB vector.
Definition: fib_table.h:94
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
void vl_msg_api_send_shmem(svm_queue_t *q, u8 *elem)
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:153
Set the ip flow hash config for a fib request.
Definition: ip.api:171
fib_node_index_t fib_table_entry_special_dpo_update(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Update a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the...
Definition: fib_table.c:346
static void send_ip_fib_details(vpe_api_main_t *am, vl_api_registration_t *reg, const fib_table_t *table, const fib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:191
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:99
vlib_main_t * vm
Definition: buffer.c:294
static void vl_api_ip_punt_redirect_t_handler(vl_api_ip_punt_redirect_t *mp, vlib_main_t *vm)
Definition: ip_api.c:610
svm_queue_t * vl_api_client_index_to_input_queue(u32 index)
Definition: memory_api.c:754
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:339
void fib_table_entry_delete(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source)
Delete a FIB entry.
Definition: fib_table.c:853
struct vl_api_ip_fib_dump_walk_ctx_t_ vl_api_ip_fib_dump_walk_ctx_t
Definition: ip6.h:67
u8 * ft_desc
Table description.
Definition: fib_table.h:114
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:1330
#define clib_warning(format, args...)
Definition: error.h:59
fib_node_index_t * entries
Definition: ip_api.c:534
static vlib_node_registration_t wc_arp_process_node
(constructor) VLIB_REGISTER_NODE (wc_arp_process_node)
Definition: ip_api.c:2294
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:1960
#define clib_memcpy(a, b, c)
Definition: string.h:75
ip6_address_t ip6
Definition: ip6_neighbor.h:99
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:1637
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
mfib_entry_flags_t mfe_flags
Route flags.
Definition: mfib_entry.h:74
static void set_ip6_flow_hash(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1538
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:271
u8 low_address[4]
Definition: ip.api:872
void ip4_punt_policer_add_del(u8 is_add, u32 policer_index)
mpls_label_t fml_value
The label value.
Definition: fib_types.h:420
static void vl_api_proxy_arp_dump_t_handler(vl_api_proxy_arp_dump_t *mp)
Definition: ip_api.c:2901
static vl_api_registration_t * vl_api_client_index_to_registration(u32 index)
Definition: api.h:56
void dpo_set(dpo_id_t *dpo, dpo_type_t type, dpo_proto_t proto, index_t index)
Set/create a DPO ID The DPO will be locked.
Definition: dpo.c:185
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
IP unnumbered configurations.
Definition: ip.api:533
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:2014
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)
static void send_ip_address_details(vpe_api_main_t *am, vl_api_registration_t *reg, u8 *ip, u16 prefix_length, u32 sw_if_index, u8 is_ipv6, u32 context)
Definition: ip_api.c:1348
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:1942
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:381
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:70
#define foreach_flow_hash_bit
Definition: lookup.h:71
static void vl_api_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:3158
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:3033
void vl_api_ip_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:1314
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:661
IP neighbor add / del request.
Definition: ip.api:145
void mfib_entry_get_prefix(fib_node_index_t mfib_entry_index, mfib_prefix_t *pfx)
Definition: mfib_entry.c:1222
#define pool_put_index(p, i)
Free pool element with given index.
Definition: pool.h:299
#define ASSERT(truth)
static uword ip6_address_is_zero(ip6_address_t *a)
Definition: ip6_packet.h:272
static int api_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:1260
IP Multicast FIB table response.
Definition: ip.api:470
ip6_address_t ip6_address
Definition: ip6_neighbor.h:26
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:2574
ip_lookup_main_t lookup_main
Definition: ip6.h:161
long ctx[MAX_CONNS]
Definition: main.c:126
index_t mfs_itf
Definition: mfib_signal.h:32
fib_node_index_t * entries
Definition: ip_api.c:443
static int vl_api_ip_mfib_table_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:447
static int ip4_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:988
FIB path.
Definition: fib_types.api:47
IPv6 router advertisement prefix config request.
Definition: ip.api:251
IPv6 ND proxy details returned after request.
Definition: ip.api:288
IPv4 main type.
Definition: ip4.h:95
static void set_ip4_flow_hash(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1557
An interface associated with a particular MFIB entry.
Definition: mfib_itf.h:25
IPv6 ND proxy dump request.
Definition: ip.api:302
static uword wc_arp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:2300
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:347
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: ip_api.c:1922
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:552
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:170
static void vl_api_ip_probe_neighbor_t_handler(vl_api_ip_probe_neighbor_t *mp)
Definition: ip_api.c:2984
#define clib_error_report(e)
Definition: error.h:113
int add_del_route_check(fib_protocol_t table_proto, u32 table_id, u32 next_hop_sw_if_index, dpo_proto_t next_hop_table_proto, u32 next_hop_table_id, u8 is_rpf_id, u32 *fib_index, u32 *next_hop_fib_index)
Definition: ip_api.c:937
vnet_classify_main_t vnet_classify_main
Definition: vnet_classify.c:22
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:237
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:74
void stats_dslock_with_hint(int hint, int tag)
fib_rpf_id_t mfe_rpf_id
RPF-ID used when the packets ingress not from an interface.
Definition: mfib_entry.h:79
ethernet_arp_entry_flags_t flags
Definition: arp_packet.h:157
A path that resolves via another table.
Definition: fib_types.h:367
static clib_error_t * ip_api_hookup(vlib_main_t *vm)
Definition: ip_api.c:3284
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:82
static void vl_api_ip_fib_dump_t_handler(vl_api_ip_fib_dump_t *mp)
Definition: ip_api.c:243
static vlib_node_registration_t ip_resolver_process_node
(constructor) VLIB_REGISTER_NODE (ip_resolver_process_node)
Definition: ip_api.c:2104
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:2736
void fib_api_path_encode(const fib_route_path_encode_t *api_rpath, vl_api_fib_path_t *out)
Definition: fib_api.c:207
ip6_fib_table_instance_t ip6_table[IP6_FIB_NUM_TABLES]
The two FIB tables; fwding and non-fwding.
Definition: ip6.h:159
IP neighboors dump response.
Definition: ip.api:122
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
void fib_entry_encode(fib_node_index_t fib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: fib_entry.c:1603
void mfib_entry_encode(fib_node_index_t mfib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: mfib_entry.c:1203
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:483
struct _vlib_node_registration vlib_node_registration_t
Add / del route request.
Definition: ip.api:392
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:3276
static void * vlib_process_get_event_data(vlib_main_t *vm, uword *return_event_type_opaque)
Definition: node_funcs.h:489
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:26
static void vl_api_ip_punt_police_t_handler(vl_api_ip_punt_police_t *mp, vlib_main_t *vm)
Definition: ip_api.c:595
ip6_neighbor_key_t key
Definition: ip6_neighbor.h:40
Enable/disable periodic IP neighbor scan.
Definition: ip.api:689
A for-us/local path.
Definition: fib_types.h:322
#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:2507
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:409
u64 uword
Definition: types.h:112
ip6_neighbor_public_main_t ip6_neighbor_public_main
Definition: ip6_neighbor.c:233
IPv6 ND proxy config.
Definition: ip.api:275
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:982
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:802
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:195
#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)
fib_table_t * fib_table_get(fib_node_index_t index, fib_protocol_t proto)
Get a pointer to a FIB table.
Definition: fib_table.c:27
typedef prefix
Definition: ip_types.api:40
Proxy ARP dump request.
Definition: ip.api:892
clib_error_t * set_ip6_link_local_address(vlib_main_t *vm, u32 sw_if_index, ip6_address_t *address)
static clib_error_t * want_ip4_arp_events_reaper(u32 client_index)
Definition: ip_api.c:2592
static void vl_api_sw_interface_ip6nd_ra_config_t_handler(vl_api_sw_interface_ip6nd_ra_config_t *mp)
Definition: ip_api.c:1587
Tell client about an IP6 ND resolution or MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs...
Definition: ip.api:787
vnet_api_error_t ip6_reass_get(u32 *timeout_ms, u32 *max_reassemblies, u32 *expire_walk_interval_ms)
get ip6 reassembly configuration
u32 client_index
Definition: ip.api:560
u32 mfi_sw_if_index
The SW IF index that this MFIB interface represents.
Definition: mfib_itf.h:40
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:832
static void vlib_process_put_event_data(vlib_main_t *vm, void *event_data)
Definition: node_funcs.h:526
static u32 eth_mac_equal(u8 *mac1, u8 *mac2)
Definition: ethernet.h:542
IP6 FIB table entry response.
Definition: ip.api:91
Register for IP4 ARP resolution event on receing ARP reply or MAC/IP info from ARP requests in L2 BDs...
Definition: ip.api:727
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:100
Enable/disable reassembly feature.
Definition: ip.api:1033
IP punt policer.
Definition: ip.api:591
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:231
#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)
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:1144
static void vl_api_sw_interface_ip6_set_link_local_address_t_handler(vl_api_sw_interface_ip6_set_link_local_address_t *mp)
Definition: ip_api.c:1802
u8 fml_exp
EXP bits; valid only at imposition.
Definition: fib_types.h:435
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:549
static void vl_api_ip_address_dump_t_handler(vl_api_ip_address_dump_t *mp)
Definition: ip_api.c:1377
ethernet_arp_ip4_entry_t * ip4_neighbor_entries(u32 sw_if_index)
Definition: arp.c:1379
int vnet_arp_set_ip4_over_ethernet(vnet_main_t *vnm, u32 sw_if_index, void *a_arg, int is_static, int is_no_fib_entry)
Definition: arp.c:1982
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:172
_vnet_ip6_neighbor_function_list_elt_t * ra_report_functions
Definition: ip6_neighbor.h:151
struct apt_ip6_fib_show_ctx_t_ api_ip6_fib_show_ctx_t
u16 fp_len
The mask length.
Definition: mfib_types.h:28
void mfib_table_entry_path_remove(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, const fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:251
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
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)
Add / del route request.
Definition: ip.api:433
vpe_api_main_t vpe_api_main
Definition: pipe_api.c:39
static uword vnet_sw_interface_get_flags(vnet_main_t *vnm, u32 sw_if_index)
u32 frp_udp_encap_id
UDP encap ID.
Definition: fib_types.h:532
void vl_api_ip_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:1125
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:86
void vl_mfib_signal_send_one(vl_api_registration_t *reg, u32 context, const mfib_signal_t *mfs)
Definition: ip_api.c:1833
static walk_rc_t send_proxy_arp_intfc_details(vnet_main_t *vnm, vnet_sw_interface_t *si, void *data)
Definition: ip_api.c:2918
static void handle_ip6_nd_event(u32 pool_index)
Definition: ip_api.c:2156
api_main_t api_main
Definition: api_shared.c:35
struct fib_table_t_ * fibs
Definition: ip6.h:164
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:506
int vnet_add_del_ip4_arp_change_event(vnet_main_t *vnm, void *data_callback, u32 pid, void *address_arg, uword node_index, uword type_opaque, uword data, int is_add)
Definition: arp.c:798
static void vl_api_ip6nd_send_router_solicitation_t_handler(vl_api_ip6nd_send_router_solicitation_t *mp)
Definition: ip_api.c:1742
u8 link_layer_address[8]
Definition: ip6_neighbor.h:41
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:2046
#define foreach_ip_api_msg
Definition: ip_api.c:69
int add_del_route_t_handler(u8 is_multipath, u8 is_add, u8 is_drop, u8 is_unreach, u8 is_prohibit, u8 is_local, u8 is_multicast, u8 is_classify, u32 classify_table_index, u8 is_resolve_host, u8 is_resolve_attached, u8 is_interface_rx, u8 is_rpf_id, u8 is_dvr, u8 is_source_lookup, u8 is_udp_encap, u32 fib_index, const fib_prefix_t *prefix, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, u32 next_hop_id, u32 next_hop_sw_if_index, u8 next_hop_fib_index, u16 next_hop_weight, u16 next_hop_preference, mpls_label_t next_hop_via_label, fib_mpls_label_t *next_hop_out_label_stack)
Definition: ip_api.c:761
static void send_ip6_fib_details(vpe_api_main_t *am, vl_api_registration_t *reg, const fib_table_t *table, const fib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:288
const ip46_address_t zero_addr
Definition: lookup.c:318
ip46_address_t fp_grp_addr
The address type is not deriveable from the fp_addr member.
Definition: mfib_types.h:46
static void vl_api_ip6_fib_dump_t_handler(vl_api_ip6_fib_dump_t *mp)
Definition: ip_api.c:375
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:69
Definition: arp_packet.h:150
fib_node_index_t * feis
Definition: ip_api.c:229
IPv6 Proxy ND.
Definition: fib_entry.h:98
static int ip6_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:3100
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:143
static void vl_api_want_ip6_ra_events_t_handler(vl_api_want_ip6_ra_events_t *mp)
Definition: ip_api.c:2780
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:1431
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