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