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