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