FD.io VPP  v19.04.1-1-ge4a0f9f
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  int rv, ii, n_labels;;
1029 
1031  mp->table_id,
1033  DPO_PROTO_IP4,
1034  mp->next_hop_table_id,
1035  0, &fib_index, &next_hop_fib_index);
1036 
1037  if (0 != rv)
1038  return (rv);
1039 
1040  fib_prefix_t pfx = {
1041  .fp_len = mp->dst_address_length,
1042  .fp_proto = FIB_PROTOCOL_IP4,
1043  };
1044  clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
1045 
1046  ip46_address_t nh;
1047  clib_memset (&nh, 0, sizeof (nh));
1048  memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
1049 
1050  n_labels = mp->next_hop_n_out_labels;
1051  if (n_labels == 0)
1052  ;
1053  else
1054  {
1055  vec_validate (label_stack, n_labels - 1);
1056  for (ii = 0; ii < n_labels; ii++)
1057  {
1058  label_stack[ii].fml_value =
1059  ntohl (mp->next_hop_out_label_stack[ii].label);
1060  label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
1061  label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
1062  label_stack[ii].fml_mode =
1065  }
1066  }
1067 
1069  mp->is_add,
1070  mp->is_drop,
1071  mp->is_unreach,
1072  mp->is_prohibit,
1073  mp->is_local, 0,
1074  mp->is_classify,
1076  mp->is_resolve_host,
1077  mp->is_resolve_attached, 0, 0,
1078  mp->is_dvr,
1079  mp->is_source_lookup,
1080  mp->is_udp_encap,
1081  fib_index, &pfx, DPO_PROTO_IP4,
1082  &nh,
1083  ntohl (mp->next_hop_id),
1084  ntohl (mp->next_hop_sw_if_index),
1085  next_hop_fib_index,
1086  mp->next_hop_weight,
1087  mp->next_hop_preference,
1088  ntohl (mp->next_hop_via_label), label_stack);
1089 
1090  if (mp->is_add && 0 == rv)
1091  *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
1092 
1093  return (rv);
1094 }
1095 
1096 static int
1098  u32 * stats_index)
1099 {
1100  fib_mpls_label_t *label_stack = NULL;
1101  u32 fib_index, next_hop_fib_index;
1102  int rv, ii, n_labels;;
1103 
1105  mp->table_id,
1107  DPO_PROTO_IP6,
1108  mp->next_hop_table_id,
1109  0, &fib_index, &next_hop_fib_index);
1110 
1111  if (0 != rv)
1112  return (rv);
1113 
1114  fib_prefix_t pfx = {
1115  .fp_len = mp->dst_address_length,
1116  .fp_proto = FIB_PROTOCOL_IP6,
1117  };
1118  clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
1119 
1120  ip46_address_t nh;
1121  clib_memset (&nh, 0, sizeof (nh));
1122  memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
1123 
1124  n_labels = mp->next_hop_n_out_labels;
1125  if (n_labels == 0)
1126  ;
1127  else
1128  {
1129  vec_validate (label_stack, n_labels - 1);
1130  for (ii = 0; ii < n_labels; ii++)
1131  {
1132  label_stack[ii].fml_value =
1133  ntohl (mp->next_hop_out_label_stack[ii].label);
1134  label_stack[ii].fml_ttl = mp->next_hop_out_label_stack[ii].ttl;
1135  label_stack[ii].fml_exp = mp->next_hop_out_label_stack[ii].exp;
1136  label_stack[ii].fml_mode =
1139  }
1140  }
1141 
1143  mp->is_add,
1144  mp->is_drop,
1145  mp->is_unreach,
1146  mp->is_prohibit,
1147  mp->is_local, 0,
1148  mp->is_classify,
1150  mp->is_resolve_host,
1151  mp->is_resolve_attached, 0, 0,
1152  mp->is_dvr,
1153  mp->is_source_lookup,
1154  mp->is_udp_encap,
1155  fib_index, &pfx, DPO_PROTO_IP6,
1156  &nh, ntohl (mp->next_hop_id),
1157  ntohl (mp->next_hop_sw_if_index),
1158  next_hop_fib_index,
1159  mp->next_hop_weight,
1160  mp->next_hop_preference,
1161  ntohl (mp->next_hop_via_label), label_stack);
1162 
1163  if (mp->is_add && 0 == rv)
1164  *stats_index = fib_table_entry_get_stats_index (fib_index, &pfx);
1165 
1166  return (rv);
1167 }
1168 
1169 void
1171 {
1173  u32 stats_index;
1174  int rv;
1175  vnet_main_t *vnm = vnet_get_main ();
1176 
1177  vnm->api_errno = 0;
1178  stats_index = ~0;
1179 
1180  if (mp->is_ipv6)
1181  rv = ip6_add_del_route_t_handler (mp, &stats_index);
1182  else
1183  rv = ip4_add_del_route_t_handler (mp, &stats_index);
1184 
1185  rv = (rv == 0) ? vnm->api_errno : rv;
1186 
1187  /* *INDENT-OFF* */
1188  REPLY_MACRO2 (VL_API_IP_ADD_DEL_ROUTE_REPLY,
1189  ({
1190  rmp->stats_index = htonl (stats_index);
1191  }))
1192  /* *INDENT-ON* */
1193 }
1194 
1195 void
1197  u32 table_id, u8 is_api, const u8 * name)
1198 {
1199  u32 fib_index, mfib_index;
1200 
1201  /*
1202  * ignore action on the default table - this is always present
1203  * and cannot be added nor deleted from the API
1204  */
1205  if (0 != table_id)
1206  {
1207  /*
1208  * The API holds only one lock on the table.
1209  * i.e. it can be added many times via the API but needs to be
1210  * deleted only once.
1211  * The FIB index for unicast and multicast is not necessarily the
1212  * same, since internal VPP systesm (like LISP and SR) create
1213  * their own unicast tables.
1214  */
1215  fib_index = fib_table_find (fproto, table_id);
1216  mfib_index = mfib_table_find (fproto, table_id);
1217 
1218  if (~0 == fib_index)
1219  {
1220  fib_table_find_or_create_and_lock_w_name (fproto, table_id,
1221  (is_api ?
1222  FIB_SOURCE_API :
1223  FIB_SOURCE_CLI), name);
1224  }
1225  if (~0 == mfib_index)
1226  {
1228  (is_api ?
1229  MFIB_SOURCE_API :
1230  MFIB_SOURCE_CLI), name);
1231  }
1232  }
1233 }
1234 
1235 static int
1237  u32 table_id,
1238  u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
1239 {
1240  vnet_main_t *vnm = vnet_get_main ();
1241 
1242  *fib_index = mfib_table_find (table_proto, ntohl (table_id));
1243  if (~0 == *fib_index)
1244  {
1245  /* No such table */
1246  return VNET_API_ERROR_NO_SUCH_FIB;
1247  }
1248 
1249  if (~0 != ntohl (next_hop_sw_if_index))
1250  {
1252  ntohl (next_hop_sw_if_index)))
1253  {
1254  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1255  }
1256  }
1257 
1258  return (0);
1259 }
1260 
1261 static fib_node_index_t
1263  u8 is_local,
1264  u32 fib_index,
1265  const mfib_prefix_t * prefix,
1266  dpo_proto_t nh_proto,
1267  u32 entry_flags,
1268  fib_rpf_id_t rpf_id,
1269  u32 next_hop_sw_if_index,
1270  ip46_address_t * nh, u32 itf_flags, u32 bier_imp)
1271 {
1272  fib_node_index_t mfib_entry_index = ~0;
1273 
1274  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
1275 
1276  fib_route_path_t path = {
1277  .frp_sw_if_index = next_hop_sw_if_index,
1278  .frp_proto = nh_proto,
1279  .frp_addr = *nh,
1280  };
1281 
1282  if (is_local)
1284 
1285  if (DPO_PROTO_BIER == nh_proto)
1286  {
1287  path.frp_bier_imp = bier_imp;
1289  }
1290  else if (!is_local && ~0 == next_hop_sw_if_index)
1291  {
1292  mfib_entry_index = mfib_table_entry_update (fib_index, prefix,
1294  rpf_id, entry_flags);
1295  goto done;
1296  }
1297 
1298  if (is_add)
1299  {
1300  mfib_entry_index = mfib_table_entry_path_update (fib_index, prefix,
1302  &path, itf_flags);
1303  }
1304  else
1305  {
1306  mfib_table_entry_path_remove (fib_index, prefix,
1307  MFIB_SOURCE_API, &path);
1308  }
1309 
1310 done:
1311  stats_dsunlock ();
1312  return (mfib_entry_index);
1313 }
1314 
1315 static int
1317  u32 * stats_index)
1318 {
1319  fib_node_index_t mfib_entry_index;
1320  fib_protocol_t fproto;
1321  dpo_proto_t nh_proto;
1322  ip46_address_t nh;
1323  u32 fib_index;
1324  int rv;
1325 
1326  nh_proto = mp->next_hop_afi;
1327  fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
1328  rv = add_del_mroute_check (fproto,
1329  mp->table_id,
1331  mp->is_local, &fib_index);
1332 
1333  if (0 != rv)
1334  return (rv);
1335 
1336  mfib_prefix_t pfx = {
1337  .fp_len = ntohs (mp->grp_address_length),
1338  .fp_proto = fproto,
1339  };
1340 
1341  if (FIB_PROTOCOL_IP4 == fproto)
1342  {
1343  clib_memcpy (&pfx.fp_grp_addr.ip4, mp->grp_address,
1344  sizeof (pfx.fp_grp_addr.ip4));
1345  clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
1346  sizeof (pfx.fp_src_addr.ip4));
1347  clib_memset (&nh.ip6, 0, sizeof (nh.ip6));
1348  clib_memcpy (&nh.ip4, mp->nh_address, sizeof (nh.ip4));
1349  if (!ip46_address_is_zero (&pfx.fp_src_addr))
1350  pfx.fp_len = 64;
1351  }
1352  else
1353  {
1354  clib_memcpy (&pfx.fp_grp_addr.ip6, mp->grp_address,
1355  sizeof (pfx.fp_grp_addr.ip6));
1356  clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
1357  sizeof (pfx.fp_src_addr.ip6));
1358  clib_memcpy (&nh.ip6, mp->nh_address, sizeof (nh.ip6));
1359  if (!ip46_address_is_zero (&pfx.fp_src_addr))
1360  pfx.fp_len = 256;
1361  }
1362 
1363  mfib_entry_index = mroute_add_del_handler (mp->is_add,
1364  mp->is_local,
1365  fib_index, &pfx,
1366  nh_proto,
1367  ntohl (mp->entry_flags),
1368  ntohl (mp->rpf_id),
1369  ntohl (mp->next_hop_sw_if_index),
1370  &nh,
1371  ntohl (mp->itf_flags),
1372  ntohl (mp->bier_imp));
1373 
1374  if (~0 != mfib_entry_index)
1375  *stats_index = mfib_entry_get_stats_index (mfib_entry_index);
1376 
1377  return (rv);
1378 }
1379 
1380 void
1382 {
1384  vnet_main_t *vnm;
1385  u32 stats_index;
1386  int rv;
1387 
1388  vnm = vnet_get_main ();
1389  vnm->api_errno = 0;
1390  stats_index = ~0;
1391 
1392  rv = api_mroute_add_del_t_handler (mp, &stats_index);
1393 
1394  /* *INDENT-OFF* */
1395  REPLY_MACRO2 (VL_API_IP_MROUTE_ADD_DEL_REPLY,
1396  ({
1397  rmp->stats_index = htonl (stats_index);
1398  }));
1399  /* *INDENT-ON* */
1400 }
1401 
1402 static void
1404  vl_api_registration_t * reg, u32 sw_if_index, u8 is_ipv6,
1405  u32 context)
1406 {
1407  vl_api_ip_details_t *mp;
1408 
1409  mp = vl_msg_api_alloc (sizeof (*mp));
1410  clib_memset (mp, 0, sizeof (*mp));
1411  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
1412 
1413  mp->sw_if_index = ntohl (sw_if_index);
1414  mp->is_ipv6 = is_ipv6;
1415  mp->context = context;
1416 
1417  vl_api_send_msg (reg, (u8 *) mp);
1418 }
1419 
1420 static void
1422  vl_api_registration_t * reg,
1423  u8 * ip, u16 prefix_length,
1424  u32 sw_if_index, u8 is_ipv6, u32 context)
1425 {
1427 
1428  mp = vl_msg_api_alloc (sizeof (*mp));
1429  clib_memset (mp, 0, sizeof (*mp));
1430  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
1431 
1432  if (is_ipv6)
1433  {
1434  clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
1435  }
1436  else
1437  {
1438  u32 *tp = (u32 *) mp->ip;
1439  *tp = *(u32 *) ip;
1440  }
1441  mp->prefix_length = prefix_length;
1442  mp->context = context;
1443  mp->sw_if_index = htonl (sw_if_index);
1444  mp->is_ipv6 = is_ipv6;
1445 
1446  vl_api_send_msg (reg, (u8 *) mp);
1447 }
1448 
1449 static void
1451 {
1453  vl_api_registration_t *reg;
1454  ip6_address_t *r6;
1455  ip4_address_t *r4;
1456  ip6_main_t *im6 = &ip6_main;
1457  ip4_main_t *im4 = &ip4_main;
1458  ip_lookup_main_t *lm6 = &im6->lookup_main;
1459  ip_lookup_main_t *lm4 = &im4->lookup_main;
1460  ip_interface_address_t *ia = 0;
1461  u32 sw_if_index = ~0;
1462  int rv __attribute__ ((unused)) = 0;
1463 
1464  VALIDATE_SW_IF_INDEX (mp);
1465 
1466  sw_if_index = ntohl (mp->sw_if_index);
1467 
1469  if (!reg)
1470  return;
1471 
1472  if (mp->is_ipv6)
1473  {
1474  /* *INDENT-OFF* */
1475  /* Do not send subnet details of the IP-interface for
1476  * unnumbered interfaces. otherwise listening clients
1477  * will be confused that the subnet is applied on more
1478  * than one interface */
1479  foreach_ip_interface_address (lm6, ia, sw_if_index, 0,
1480  ({
1481  r6 = ip_interface_address_get_address (lm6, ia);
1482  u16 prefix_length = ia->address_length;
1483  send_ip_address_details(am, reg, (u8*)r6, prefix_length,
1484  sw_if_index, 1, mp->context);
1485  }));
1486  /* *INDENT-ON* */
1487  }
1488  else
1489  {
1490  /* *INDENT-OFF* */
1491  foreach_ip_interface_address (lm4, ia, sw_if_index, 0,
1492  ({
1493  r4 = ip_interface_address_get_address (lm4, ia);
1494  u16 prefix_length = ia->address_length;
1495  send_ip_address_details(am, reg, (u8*)r4, prefix_length,
1496  sw_if_index, 0, mp->context);
1497  }));
1498  /* *INDENT-ON* */
1499  }
1500 
1502 }
1503 
1504 static void
1506  vl_api_registration_t * reg,
1507  u32 sw_if_index, u32 ip_sw_if_index, u32 context)
1508 {
1510 
1511  mp = vl_msg_api_alloc (sizeof (*mp));
1512  clib_memset (mp, 0, sizeof (*mp));
1513  mp->_vl_msg_id = ntohs (VL_API_IP_UNNUMBERED_DETAILS);
1514 
1515  mp->context = context;
1516  mp->sw_if_index = htonl (sw_if_index);
1517  mp->ip_sw_if_index = htonl (ip_sw_if_index);
1518 
1519  vl_api_send_msg (reg, (u8 *) mp);
1520 }
1521 
1522 static void
1524 {
1525  vnet_main_t *vnm = vnet_get_main ();
1527  int rv __attribute__ ((unused)) = 0;
1529  vl_api_registration_t *reg;
1530  vnet_sw_interface_t *si;
1531  u32 sw_if_index;
1532 
1533  sw_if_index = ntohl (mp->sw_if_index);
1534 
1536  if (!reg)
1537  return;
1538 
1539  if (~0 != sw_if_index)
1540  {
1541  VALIDATE_SW_IF_INDEX (mp);
1542 
1543  si = vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
1544 
1546  {
1547  send_ip_unnumbered_details (am, reg,
1548  sw_if_index,
1550  mp->context);
1551  }
1552  }
1553  else
1554  {
1555  /* *INDENT-OFF* */
1556  pool_foreach (si, im->sw_interfaces,
1557  ({
1558  if ((si->flags & VNET_SW_INTERFACE_FLAG_UNNUMBERED))
1559  {
1560  send_ip_unnumbered_details(am, reg,
1561  si->sw_if_index,
1562  si->unnumbered_sw_if_index,
1563  mp->context);
1564  }
1565  }));
1566  /* *INDENT-ON* */
1567  }
1568 
1570 }
1571 
1572 static void
1574 {
1576  vnet_main_t *vnm = vnet_get_main ();
1579  vl_api_registration_t *reg;
1580  vnet_sw_interface_t *si, *sorted_sis;
1581  u32 sw_if_index = ~0;
1582 
1584  if (!reg)
1585  return;
1586 
1587  /* Gather interfaces. */
1588  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
1589  _vec_len (sorted_sis) = 0;
1590  /* *INDENT-OFF* */
1591  pool_foreach (si, im->sw_interfaces,
1592  ({
1593  vec_add1 (sorted_sis, si[0]);
1594  }));
1595  /* *INDENT-ON* */
1596 
1597  vec_foreach (si, sorted_sis)
1598  {
1600  {
1601  if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
1602  {
1603  continue;
1604  }
1605  sw_if_index = si->sw_if_index;
1606  send_ip_details (am, reg, sw_if_index, mp->is_ipv6, mp->context);
1607  }
1608  }
1609 }
1610 
1611 static void
1613 {
1614  vl_api_set_ip_flow_hash_reply_t *rmp;
1615  int rv;
1616  u32 table_id;
1617  flow_hash_config_t flow_hash_config = 0;
1618 
1619  table_id = ntohl (mp->vrf_id);
1620 
1621 #define _(a,b) if (mp->a) flow_hash_config |= b;
1623 #undef _
1624 
1625  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1626 
1627  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1628 }
1629 
1630 static void
1632 {
1633  vl_api_set_ip_flow_hash_reply_t *rmp;
1634  int rv;
1635  u32 table_id;
1636  flow_hash_config_t flow_hash_config = 0;
1637 
1638  table_id = ntohl (mp->vrf_id);
1639 
1640 #define _(a,b) if (mp->a) flow_hash_config |= b;
1642 #undef _
1643 
1644  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1645 
1646  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1647 }
1648 
1649 
1650 static void
1652 {
1653  if (mp->is_ipv6 == 0)
1654  set_ip4_flow_hash (mp);
1655  else
1656  set_ip6_flow_hash (mp);
1657 }
1658 
1659 static void
1662 {
1663  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1665  int rv = 0;
1666  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1667  default_router;
1668 
1669  is_no = mp->is_no == 1;
1670  suppress = mp->suppress == 1;
1671  managed = mp->managed == 1;
1672  other = mp->other == 1;
1673  ll_option = mp->ll_option == 1;
1674  send_unicast = mp->send_unicast == 1;
1675  cease = mp->cease == 1;
1676  default_router = mp->default_router == 1;
1677 
1678  VALIDATE_SW_IF_INDEX (mp);
1679 
1680  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1681  suppress, managed, other,
1682  ll_option, send_unicast, cease,
1683  default_router, ntohl (mp->lifetime),
1684  ntohl (mp->initial_count),
1685  ntohl (mp->initial_interval),
1686  ntohl (mp->max_interval),
1687  ntohl (mp->min_interval), is_no);
1688 
1690 
1691  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1692 }
1693 
1694 static void
1697 {
1699  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1700  fib_prefix_t pfx;
1701  int rv = 0;
1702  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1703 
1704  VALIDATE_SW_IF_INDEX (mp);
1705 
1706  ip_prefix_decode (&mp->prefix, &pfx);
1707  is_no = mp->is_no == 1;
1708  use_default = mp->use_default == 1;
1709  no_advertise = mp->no_advertise == 1;
1710  off_link = mp->off_link == 1;
1711  no_autoconfig = mp->no_autoconfig == 1;
1712  no_onlink = mp->no_onlink == 1;
1713 
1714  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1715  &pfx.fp_addr.ip6,
1716  pfx.fp_len, use_default,
1717  ntohl (mp->val_lifetime),
1718  ntohl (mp->pref_lifetime), no_advertise,
1719  off_link, no_autoconfig, no_onlink, is_no);
1720 
1722  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1723 }
1724 
1725 static void
1727  u32 context,
1728  const ip46_address_t * addr, u32 sw_if_index)
1729 {
1731 
1732  mp = vl_msg_api_alloc (sizeof (*mp));
1733  clib_memset (mp, 0, sizeof (*mp));
1734  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1735  mp->context = context;
1736  mp->sw_if_index = htonl (sw_if_index);
1737 
1738  ip6_address_encode (&addr->ip6, mp->ip);
1739 
1740  vl_api_send_msg (reg, (u8 *) mp);
1741 }
1742 
1744 {
1747 
1748 static fib_table_walk_rc_t
1750 {
1752 
1754  {
1755  vec_add1 (ctx->indices, fei);
1756  }
1757 
1758  return (FIB_TABLE_WALK_CONTINUE);
1759 }
1760 
1761 static void
1763 {
1764  ip6_main_t *im6 = &ip6_main;
1765  fib_table_t *fib_table;
1767  .indices = NULL,
1768  };
1769  fib_node_index_t *feip;
1770  const fib_prefix_t *pfx;
1771  vl_api_registration_t *reg;
1772 
1774  if (!reg)
1775  return;
1776 
1777  /* *INDENT-OFF* */
1778  pool_foreach (fib_table, im6->fibs,
1779  ({
1780  fib_table_walk(fib_table->ft_index,
1781  FIB_PROTOCOL_IP6,
1782  api_ip6nd_proxy_fib_table_walk,
1783  &ctx);
1784  }));
1785  /* *INDENT-ON* */
1786 
1788 
1789  vec_foreach (feip, ctx.indices)
1790  {
1791  pfx = fib_entry_get_prefix (*feip);
1792 
1794  mp->context,
1795  &pfx->fp_addr,
1797  }
1798 
1799  vec_free (ctx.indices);
1800 }
1801 
1802 static void
1804 {
1805  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1806  ip6_address_t ip6;
1807  int rv = 0;
1808 
1809  VALIDATE_SW_IF_INDEX (mp);
1810 
1811  ip6_address_decode (mp->ip, &ip6);
1812  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index), &ip6, mp->is_del);
1813 
1815  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1816 }
1817 
1818 static void
1821 {
1822  vl_api_ip6nd_send_router_solicitation_reply_t *rmp;
1825  int rv = 0;
1826 
1827  VALIDATE_SW_IF_INDEX (mp);
1828 
1830  REPLY_MACRO (VL_API_IP6ND_SEND_ROUTER_SOLICITATION_REPLY);
1831 
1832  if (rv != 0)
1833  return;
1834 
1835  params.irt = ntohl (mp->irt);
1836  params.mrt = ntohl (mp->mrt);
1837  params.mrc = ntohl (mp->mrc);
1838  params.mrd = ntohl (mp->mrd);
1839 
1840  icmp6_send_router_solicitation (vm, ntohl (mp->sw_if_index), mp->stop,
1841  &params);
1842 }
1843 
1844 static void
1847 {
1849  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1850  vnet_main_t *vnm = vnet_get_main ();
1851  int rv = 0;
1852  clib_error_t *error;
1853 
1854  vnm->api_errno = 0;
1855 
1856  VALIDATE_SW_IF_INDEX (mp);
1857 
1858  error =
1859  (mp->enable == 1) ? enable_ip6_interface (vm,
1860  ntohl (mp->sw_if_index)) :
1861  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1862 
1863  if (error)
1864  {
1865  clib_error_report (error);
1866  rv = VNET_API_ERROR_UNSPECIFIED;
1867  }
1868  else
1869  {
1870  rv = vnm->api_errno;
1871  }
1872 
1874 
1875  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1876 }
1877 
1878 void
1880  u32 context, const mfib_signal_t * mfs)
1881 {
1883  const mfib_prefix_t *prefix;
1884  mfib_table_t *mfib;
1885  mfib_itf_t *mfi;
1886 
1887  mp = vl_msg_api_alloc (sizeof (*mp));
1888 
1889  clib_memset (mp, 0, sizeof (*mp));
1890  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1891  mp->context = context;
1892 
1893  mfi = mfib_itf_get (mfs->mfs_itf);
1894  prefix = mfib_entry_get_prefix (mfs->mfs_entry);
1896  prefix->fp_proto);
1897  mp->table_id = ntohl (mfib->mft_table_id);
1898  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1899 
1900  if (FIB_PROTOCOL_IP4 == prefix->fp_proto)
1901  {
1902  mp->grp_address_len = ntohs (prefix->fp_len);
1903 
1904  memcpy (mp->grp_address, &prefix->fp_grp_addr.ip4, 4);
1905  if (prefix->fp_len > 32)
1906  {
1907  memcpy (mp->src_address, &prefix->fp_src_addr.ip4, 4);
1908  }
1909  }
1910  else
1911  {
1912  mp->grp_address_len = ntohs (prefix->fp_len);
1913 
1914  ASSERT (0);
1915  }
1916 
1917  if (0 != mfs->mfs_buffer_len)
1918  {
1919  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1920 
1921  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1922  }
1923  else
1924  {
1925  mp->ip_packet_len = 0;
1926  }
1927 
1928  vl_api_send_msg (reg, (u8 *) mp);
1929 }
1930 
1931 static void
1933 {
1934  vl_api_registration_t *reg;
1935 
1937  if (!reg)
1938  return;
1939 
1940  while (vl_api_can_send_msg (reg) && mfib_signal_send_one (reg, mp->context))
1941  ;
1942 }
1943 
1944 static void
1947 {
1948  vl_api_ip_container_proxy_add_del_reply_t *rmp;
1950  int rv = 0;
1951  clib_error_t *error;
1952 
1953  clib_memset (&args, 0, sizeof (args));
1954 
1955  ip_prefix_decode (&mp->pfx, &args.prefix);
1956 
1957  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
1958  args.is_add = mp->is_add;
1959  if ((error = vnet_ip_container_proxy_add_del (&args)))
1960  {
1961  rv = clib_error_get_code (error);
1962  clib_error_report (error);
1963  }
1964 
1965  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
1966 }
1967 
1969 {
1973 
1974 static int
1976  void *args)
1977 {
1980 
1981  mp = vl_msg_api_alloc (sizeof (*mp));
1982  if (!mp)
1983  return 1;
1984 
1985  clib_memset (mp, 0, sizeof (*mp));
1986  mp->_vl_msg_id = ntohs (VL_API_IP_CONTAINER_PROXY_DETAILS);
1987  mp->context = ctx->context;
1988 
1989  mp->sw_if_index = ntohl (sw_if_index);
1990  ip_prefix_encode (pfx, &mp->prefix);
1991 
1992  vl_api_send_msg (ctx->reg, (u8 *) mp);
1993 
1994  return 1;
1995 }
1996 
1997 static void
1999  mp)
2000 {
2001  vl_api_registration_t *reg;
2002 
2004  if (!reg)
2005  return;
2006 
2008  .context = mp->context,
2009  .reg = reg,
2010  };
2011 
2013 }
2014 
2015 static void
2017 {
2018  int rv = 0;
2019  vl_api_ioam_enable_reply_t *rmp;
2020  clib_error_t *error;
2021 
2022  /* Ignoring the profile id as currently a single profile
2023  * is supported */
2024  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
2025  mp->seqno, mp->analyse);
2026  if (error)
2027  {
2028  clib_error_report (error);
2029  rv = clib_error_get_code (error);
2030  }
2031 
2032  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
2033 }
2034 
2035 static void
2037 {
2038  int rv = 0;
2039  vl_api_ioam_disable_reply_t *rmp;
2040  clib_error_t *error;
2041 
2042  error = clear_ioam_rewrite_fn ();
2043  if (error)
2044  {
2045  clib_error_report (error);
2046  rv = clib_error_get_code (error);
2047  }
2048 
2049  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
2050 }
2051 
2052 static void
2055 {
2056  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
2057  int rv = 0;
2058 
2059  u8 is_add = mp->is_add;
2060  fib_prefix_t pfx;
2061  u16 *low_ports = 0;
2062  u16 *high_ports = 0;
2063  u32 vrf_id;
2064  u16 tmp_low, tmp_high;
2065  u8 num_ranges;
2066  int i;
2067 
2068  ip_prefix_decode (&mp->prefix, &pfx);
2069 
2070  // Validate port range
2071  num_ranges = mp->number_of_ranges;
2072  if (num_ranges > 32)
2073  { // This is size of array in VPE.API
2074  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
2075  goto reply;
2076  }
2077 
2078  vec_reset_length (low_ports);
2079  vec_reset_length (high_ports);
2080 
2081  for (i = 0; i < num_ranges; i++)
2082  {
2083  tmp_low = mp->low_ports[i];
2084  tmp_high = mp->high_ports[i];
2085  // If tmp_low <= tmp_high then only need to check tmp_low = 0
2086  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
2087  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
2088  {
2089  rv = VNET_API_ERROR_INVALID_VALUE;
2090  goto reply;
2091  }
2092  vec_add1 (low_ports, tmp_low);
2093  vec_add1 (high_ports, tmp_high + 1);
2094  }
2095 
2096  vrf_id = ntohl (mp->vrf_id);
2097 
2098  if (vrf_id < 1)
2099  {
2100  rv = VNET_API_ERROR_INVALID_VALUE;
2101  goto reply;
2102  }
2103 
2104 
2105  if (FIB_PROTOCOL_IP6 == pfx.fp_proto)
2106  {
2108  pfx.fp_len,
2109  vrf_id,
2110  low_ports,
2111  high_ports, is_add);
2112  }
2113  else
2114  {
2116  pfx.fp_len,
2117  vrf_id,
2118  low_ports,
2119  high_ports, is_add);
2120  }
2121 
2122 reply:
2123  vec_free (low_ports);
2124  vec_free (high_ports);
2125  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
2126 }
2127 
2128 static void
2131 {
2133  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
2134  ip4_main_t *im = &ip4_main;
2135  int rv;
2136  u32 sw_if_index;
2139  uword *p = 0;
2140  int i;
2141 
2143  ntohl (mp->tcp_out_vrf_id);
2145  ntohl (mp->udp_out_vrf_id);
2147  ntohl (mp->tcp_in_vrf_id);
2149  ntohl (mp->udp_in_vrf_id);
2150 
2151 
2152  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
2153  {
2154  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
2155  {
2156  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
2157 
2158  if (p == 0)
2159  {
2160  rv = VNET_API_ERROR_INVALID_VALUE;
2161  goto reply;
2162  }
2163 
2164  fib_index[i] = p[0];
2165  }
2166  else
2167  fib_index[i] = ~0;
2168  }
2169  sw_if_index = ntohl (mp->sw_if_index);
2170 
2171  VALIDATE_SW_IF_INDEX (mp);
2172 
2173  rv =
2174  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
2175  mp->is_add);
2176 
2178 reply:
2179 
2180  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
2181 }
2182 
2183 typedef union
2184 {
2185  u32 fib_index;
2187 
2188 static void
2191 {
2192  vl_api_ip_source_check_interface_add_del_reply_t *rmp;
2193  int rv;
2194  u32 sw_if_index = ntohl (mp->sw_if_index);
2195  u8 is_add = mp->is_add;
2196  char *feature_name =
2197  mp->loose ? "ip4-source-check-via-any" : "ip4-source-check-via-rx";
2198 
2200 
2201  VALIDATE_SW_IF_INDEX (mp);
2202 
2203  config.fib_index =
2205  rv =
2206  vnet_feature_enable_disable ("ip4-unicast", feature_name, sw_if_index,
2207  is_add, &config, sizeof (config));
2209 
2210  REPLY_MACRO (VL_API_IP_SOURCE_CHECK_INTERFACE_ADD_DEL_REPLY);
2211 }
2212 
2213 #define IP4_ARP_EVENT 3
2214 #define IP6_ND_EVENT 4
2215 
2217 
2218 static int
2220  const mac_address_t * mac,
2222 {
2224 
2225  if (pool_is_free_index (am->arp_events, pool_index))
2226  return 1;
2227 
2228  pool_put_index (am->arp_events, pool_index);
2229  return 0;
2230 }
2231 
2232 static void
2234 {
2235  vpe_api_main_t *vam = &vpe_api_main;
2236  vnet_main_t *vnm = vam->vnet_main;
2237  vlib_main_t *vm = vam->vlib_main;
2238  vl_api_ip4_arp_event_t *event;
2240  vl_api_registration_t *reg;
2241 
2242  /* Client can cancel, die, etc. */
2243  if (pool_is_free_index (vam->arp_events, pool_index))
2244  return;
2245 
2246  event = pool_elt_at_index (vam->arp_events, pool_index);
2247 
2249  if (!reg)
2250  {
2253  event->pid, event->ip,
2254  ip_resolver_process_node.index, IP4_ARP_EVENT,
2255  ~0 /* pool index, notused */ , 0 /* is_add */ );
2256  return;
2257  }
2258 
2259  if (vl_api_can_send_msg (reg))
2260  {
2261  mp = vl_msg_api_alloc (sizeof (*mp));
2262  clib_memcpy (mp, event, sizeof (*mp));
2263  vl_api_send_msg (reg, (u8 *) mp);
2264  }
2265  else
2266  {
2267  static f64 last_time;
2268  /*
2269  * Throttle syslog msgs.
2270  * It's pretty tempting to just revoke the registration...
2271  */
2272  if (vlib_time_now (vm) > last_time + 10.0)
2273  {
2274  clib_warning ("arp event for %U to pid %d: queue stuffed!",
2275  format_ip4_address, event->ip, event->pid);
2276  last_time = vlib_time_now (vm);
2277  }
2278  }
2279 }
2280 
2281 static int
2283  const mac_address_t * mac,
2284  u32 sw_if_index, const ip6_address_t * addr)
2285 {
2287 
2288  if (pool_is_free_index (am->nd_events, pool_index))
2289  return 1;
2290 
2291  pool_put_index (am->nd_events, pool_index);
2292  return 0;
2293 }
2294 
2295 static void
2297 {
2298  vpe_api_main_t *vam = &vpe_api_main;
2299  vnet_main_t *vnm = vam->vnet_main;
2300  vlib_main_t *vm = vam->vlib_main;
2301  vl_api_ip6_nd_event_t *event;
2303  vl_api_registration_t *reg;
2304 
2305  /* Client can cancel, die, etc. */
2306  if (pool_is_free_index (vam->nd_events, pool_index))
2307  return;
2308 
2309  event = pool_elt_at_index (vam->nd_events, pool_index);
2310 
2312  if (!reg)
2313  {
2316  event->pid, event->ip,
2317  ip_resolver_process_node.index, IP6_ND_EVENT,
2318  ~0 /* pool index, notused */ , 0 /* is_add */ );
2319  return;
2320  }
2321 
2322  if (vl_api_can_send_msg (reg))
2323  {
2324  mp = vl_msg_api_alloc (sizeof (*mp));
2325  clib_memcpy (mp, event, sizeof (*mp));
2326  vl_api_send_msg (reg, (u8 *) mp);
2327  }
2328  else
2329  {
2330  static f64 last_time;
2331  /*
2332  * Throttle syslog msgs.
2333  * It's pretty tempting to just revoke the registration...
2334  */
2335  if (vlib_time_now (vm) > last_time + 10.0)
2336  {
2337  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
2338  format_ip6_address, event->ip, event->pid);
2339  last_time = vlib_time_now (vm);
2340  }
2341  }
2342 }
2343 
2344 static uword
2347 {
2348  volatile f64 timeout = 100.0;
2349  volatile uword *event_data = 0;
2350 
2351  while (1)
2352  {
2354 
2355  uword event_type =
2356  vlib_process_get_events (vm, (uword **) & event_data);
2357 
2358  int i;
2359  switch (event_type)
2360  {
2361  case IP4_ARP_EVENT:
2362  for (i = 0; i < vec_len (event_data); i++)
2363  handle_ip4_arp_event (event_data[i]);
2364  break;
2365 
2366  case IP6_ND_EVENT:
2367  for (i = 0; i < vec_len (event_data); i++)
2368  handle_ip6_nd_event (event_data[i]);
2369  break;
2370 
2371  case ~0: /* timeout */
2372  break;
2373  }
2374 
2375  vec_reset_length (event_data);
2376  }
2377  return 0; /* or not */
2378 }
2379 
2380 /* *INDENT-OFF* */
2381 VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
2382  .function = resolver_process,
2383  .type = VLIB_NODE_TYPE_PROCESS,
2384  .name = "ip-route-resolver-process",
2385 };
2386 /* *INDENT-ON* */
2387 
2388 static int
2389 nd_change_data_callback (u32 pool_index, const mac_address_t * new_mac,
2391 {
2393  vl_api_ip6_nd_event_t *event;
2394 
2395  if (pool_is_free_index (am->nd_events, pool_index))
2396  return 1;
2397 
2398  event = pool_elt_at_index (am->nd_events, pool_index);
2399  if (ethernet_mac_address_equal (event->mac, new_mac->bytes) &&
2400  sw_if_index == ntohl (event->sw_if_index))
2401  {
2402  return 1;
2403  }
2404 
2405  mac_address_encode (new_mac, event->mac);
2406  event->sw_if_index = htonl (sw_if_index);
2407  return 0;
2408 }
2409 
2411 
2412 enum
2414 
2415 static uword
2417 {
2418  /* These cross the longjmp boundary (vlib_process_wait_for_event)
2419  * and need to be volatile - to prevent them from being optimized into
2420  * a register - which could change during suspension */
2421 
2422  volatile wc_arp_report_t arp_prev = { 0 };
2423  volatile wc_nd_report_t nd_prev = { 0 };
2424  volatile f64 last_arp = vlib_time_now (vm);
2425  volatile f64 last_nd = vlib_time_now (vm);
2426 
2427  while (1)
2428  {
2430  uword event_type = WC_ARP_REPORT;
2431  void *event_data = vlib_process_get_event_data (vm, &event_type);
2432 
2433  f64 now = vlib_time_now (vm);
2434  int i;
2435  if (event_type == WC_ARP_REPORT)
2436  {
2437  wc_arp_report_t *arp_events = event_data;
2438  for (i = 0; i < vec_len (arp_events); i++)
2439  {
2440  /* discard dup event - cast away volatile */
2441  if (arp_prev.ip.as_u32 == arp_events[i].ip.as_u32 &&
2442  mac_address_equal ((const mac_address_t *) &arp_prev.mac,
2443  &arp_events[i].mac) &&
2444  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
2445  (now - last_arp) < 10.0)
2446  {
2447  continue;
2448  }
2449  arp_prev = arp_events[i];
2450  last_arp = now;
2452  /* *INDENT-OFF* */
2453  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
2454  ({
2455  vl_api_registration_t *vl_reg;
2456  vl_reg = vl_api_client_index_to_registration (reg->client_index);
2457  ASSERT (vl_reg != NULL);
2458  if (reg && vl_api_can_send_msg (vl_reg))
2459  {
2460  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
2461  clib_memset (event, 0, sizeof *event);
2462  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2463  event->client_index = reg->client_index;
2464  event->pid = reg->client_pid;
2465  event->mac_ip = 1;
2466  ip4_address_encode(&arp_events[i].ip, event->ip);
2467  event->sw_if_index = htonl(arp_events[i].sw_if_index);
2468  mac_address_encode(&arp_events[i].mac, event->mac);
2469  vl_api_send_msg (vl_reg, (u8 *) event);
2470  }
2471  }));
2472  /* *INDENT-ON* */
2473  }
2474  }
2475  else if (event_type == WC_ND_REPORT)
2476  {
2477  wc_nd_report_t *nd_events = event_data;
2478  for (i = 0; i < vec_len (nd_events); i++)
2479  {
2480  /* discard dup event - cast away volatile */
2481  if (ip6_address_is_equal ((const ip6_address_t *) &nd_prev.ip6,
2482  &nd_events[i].ip6)
2483  && mac_address_equal ((const mac_address_t *) &nd_prev.mac,
2484  &nd_events[i].mac)
2485  && nd_prev.sw_if_index == nd_events[i].sw_if_index
2486  && (now - last_nd) < 10.0)
2487  {
2488  continue;
2489  }
2490  nd_prev = nd_events[i];
2491  last_nd = now;
2493  /* *INDENT-OFF* */
2494  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
2495  ({
2496  vl_api_registration_t *vl_reg;
2497  vl_reg = vl_api_client_index_to_registration (reg->client_index);
2498  if (vl_reg && vl_api_can_send_msg (vl_reg))
2499  {
2500  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
2501  clib_memset (event, 0, sizeof *event);
2502  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
2503  event->client_index = reg->client_index;
2504  event->pid = reg->client_pid;
2505  event->mac_ip = 1;
2506  ip6_address_encode(&nd_events[i].ip6, event->ip);
2507  event->sw_if_index = htonl(nd_events[i].sw_if_index);
2508  mac_address_encode(&nd_events[i].mac, event->mac);
2509  vl_api_send_msg (vl_reg, (u8 *) event);
2510  }
2511  }));
2512  /* *INDENT-ON* */
2513  }
2514  }
2515  else if (event_type == RA_REPORT)
2516  {
2517  ra_report_t *ra_events = event_data;
2518  for (i = 0; i < vec_len (ra_events); i++)
2519  {
2521  call_ip6_neighbor_callbacks (&ra_events[i],
2522  npm->ra_report_functions);
2523 
2525  /* *INDENT-OFF* */
2526  pool_foreach(reg, vpe_api_main.ip6_ra_events_registrations,
2527  ({
2528  vl_api_registration_t *vl_reg;
2529  vl_reg =
2530  vl_api_client_index_to_registration (reg->client_index);
2531  if (vl_reg && vl_api_can_send_msg (vl_reg))
2532  {
2533  u32 event_size =
2534  sizeof (vl_api_ip6_ra_event_t) +
2535  vec_len (ra_events[i].prefixes) *
2536  sizeof (vl_api_ip6_ra_prefix_info_t);
2537  vl_api_ip6_ra_event_t *event =
2538  vl_msg_api_alloc (event_size);
2539  clib_memset (event, 0, event_size);
2540  event->_vl_msg_id = htons (VL_API_IP6_RA_EVENT);
2541  event->client_index = reg->client_index;
2542  event->pid = reg->client_pid;
2543 
2544  event->sw_if_index = clib_host_to_net_u32 (ra_events[i].sw_if_index);
2545 
2546  ip6_address_encode (&ra_events[i].router_address,
2547  event->router_addr);
2548 
2549  event->current_hop_limit = ra_events[i].current_hop_limit;
2550  event->flags = ra_events[i].flags;
2551  event->router_lifetime_in_sec =
2552  clib_host_to_net_u16 (ra_events
2553  [i].router_lifetime_in_sec);
2554  event->neighbor_reachable_time_in_msec =
2555  clib_host_to_net_u32 (ra_events
2556  [i].neighbor_reachable_time_in_msec);
2557  event->time_in_msec_between_retransmitted_neighbor_solicitations
2558  =
2559  clib_host_to_net_u32 (ra_events
2560  [i].time_in_msec_between_retransmitted_neighbor_solicitations);
2561 
2562  event->n_prefixes =
2563  clib_host_to_net_u32 (vec_len (ra_events[i].prefixes));
2564  vl_api_ip6_ra_prefix_info_t *prefix =
2565  (typeof (prefix)) event->prefixes;
2566  u32 j;
2567  for (j = 0; j < vec_len (ra_events[i].prefixes); j++)
2568  {
2569  ra_report_prefix_info_t *info =
2570  &ra_events[i].prefixes[j];
2571  ip_prefix_encode(&info->prefix, &prefix->prefix);
2572  prefix->flags = info->flags;
2573  prefix->valid_time =
2574  clib_host_to_net_u32 (info->valid_time);
2575  prefix->preferred_time =
2576  clib_host_to_net_u32 (info->preferred_time);
2577  prefix++;
2578  }
2579 
2580  vl_api_send_msg (vl_reg, (u8 *) event);
2581  }
2582  }));
2583  /* *INDENT-ON* */
2584  vec_free (ra_events[i].prefixes);
2585  }
2586  }
2587  vlib_process_put_event_data (vm, event_data);
2588  }
2589 
2590  return 0;
2591 }
2592 
2593 /* *INDENT-OFF* */
2595  .function = wc_arp_process,
2596  .type = VLIB_NODE_TYPE_PROCESS,
2597  .name = "wildcard-ip4-arp-publisher-process",
2598 };
2599 /* *INDENT-ON* */
2600 
2601 static int
2603  const mac_address_t * mac,
2605 {
2607  vl_api_ip4_arp_event_t *event;
2608 
2609  if (pool_is_free_index (am->arp_events, pool_index))
2610  return 1;
2611 
2612  event = pool_elt_at_index (am->arp_events, pool_index);
2613  if (ethernet_mac_address_equal (event->mac, mac->bytes) &&
2614  sw_if_index == ntohl (event->sw_if_index))
2615  {
2616  return 1;
2617  }
2618 
2619  mac_address_encode (mac, event->mac);
2620  event->sw_if_index = htonl (sw_if_index);
2621  return 0;
2622 }
2623 
2624 static void
2626 {
2628  vnet_main_t *vnm = vnet_get_main ();
2629  vl_api_want_ip4_arp_events_reply_t *rmp;
2630  ip4_address_t ip;
2631  int rv = 0;
2632 
2633  ip4_address_decode (mp->ip, &ip);
2634 
2635  if (ip.as_u32 == 0)
2636  {
2637  uword *p =
2638  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
2640  if (p)
2641  {
2642  if (mp->enable_disable)
2643  {
2644  clib_warning ("pid %d: already enabled...", mp->pid);
2645  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2646  goto reply;
2647  }
2648  else
2649  {
2650  rp =
2651  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2652  pool_put (am->wc_ip4_arp_events_registrations, rp);
2653  hash_unset (am->wc_ip4_arp_events_registration_hash,
2654  mp->client_index);
2655  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2657  goto reply;
2658  }
2659  }
2660  if (mp->enable_disable == 0)
2661  {
2662  clib_warning ("pid %d: already disabled...", mp->pid);
2663  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2664  goto reply;
2665  }
2666  pool_get (am->wc_ip4_arp_events_registrations, rp);
2667  rp->client_index = mp->client_index;
2668  rp->client_pid = mp->pid;
2669  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
2670  rp - am->wc_ip4_arp_events_registrations);
2672  goto reply;
2673  }
2674 
2675  if (mp->enable_disable)
2676  {
2677  vl_api_ip4_arp_event_t *event;
2678  pool_get (am->arp_events, event);
2681  mp->pid, mp->ip /* addr, in net byte order */ ,
2683  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2684 
2685  if (rv)
2686  {
2687  pool_put (am->arp_events, event);
2688  goto reply;
2689  }
2690  clib_memset (event, 0, sizeof (*event));
2691 
2692  /* Python API expects events to have no context */
2693  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2694  event->client_index = mp->client_index;
2695  memcpy (event->ip, mp->ip, 4);
2696  event->pid = mp->pid;
2697  if (ip.as_u32 == 0)
2698  event->mac_ip = 1;
2699  }
2700  else
2701  {
2704  mp->pid, mp->ip /* addr, in net byte order */ ,
2706  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2707  }
2708 reply:
2709  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2710 }
2711 
2712 static clib_error_t *
2714 {
2716  vl_api_ip4_arp_event_t *event;
2717  u32 *to_delete, *event_id;
2718  vpe_api_main_t *am;
2719  vnet_main_t *vnm;
2720  uword *p;
2721 
2722  am = &vpe_api_main;
2723  vnm = vnet_get_main ();
2724  to_delete = NULL;
2725 
2726  /* clear out all of its pending resolutions */
2727  /* *INDENT-OFF* */
2728  pool_foreach(event, am->arp_events,
2729  ({
2730  if (event->client_index == client_index)
2731  {
2732  vec_add1(to_delete, event - am->arp_events);
2733  }
2734  }));
2735  /* *INDENT-ON* */
2736 
2737  vec_foreach (event_id, to_delete)
2738  {
2739  event = pool_elt_at_index (am->arp_events, *event_id);
2742  event->pid, event->ip,
2744  ~0 /* pool index, notused */ , 0 /* is_add */ );
2745  }
2746  vec_free (to_delete);
2747 
2748  /* remove from the registration hash */
2749  p = hash_get (am->wc_ip4_arp_events_registration_hash, client_index);
2750 
2751  if (p)
2752  {
2753  rp = pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2754  pool_put (am->wc_ip4_arp_events_registrations, rp);
2755  hash_unset (am->wc_ip4_arp_events_registration_hash, client_index);
2756  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2758  }
2759  return (NULL);
2760 }
2761 
2763 
2764 static void
2766 {
2768  vnet_main_t *vnm = vnet_get_main ();
2769  vl_api_want_ip6_nd_events_reply_t *rmp;
2770  ip6_address_t ip6;
2771  int rv = 0;
2772 
2773  ip6_address_decode (mp->ip, &ip6);
2774 
2775  if (ip6_address_is_zero (&ip6))
2776  {
2777  uword *p =
2778  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
2780  if (p)
2781  {
2782  if (mp->enable_disable)
2783  {
2784  clib_warning ("pid %d: already enabled...", mp->pid);
2785  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2786  goto reply;
2787  }
2788  else
2789  {
2790  rp =
2791  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2792  pool_put (am->wc_ip6_nd_events_registrations, rp);
2793  hash_unset (am->wc_ip6_nd_events_registration_hash,
2794  mp->client_index);
2795  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2797  goto reply;
2798  }
2799  }
2800  if (mp->enable_disable == 0)
2801  {
2802  clib_warning ("pid %d: already disabled...", mp->pid);
2803  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2804  goto reply;
2805  }
2806  pool_get (am->wc_ip6_nd_events_registrations, rp);
2807  rp->client_index = mp->client_index;
2808  rp->client_pid = mp->pid;
2809  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
2810  rp - am->wc_ip6_nd_events_registrations);
2812  goto reply;
2813  }
2814 
2815  if (mp->enable_disable)
2816  {
2817  vl_api_ip6_nd_event_t *event;
2818  pool_get (am->nd_events, event);
2819 
2822  mp->pid, &ip6,
2824  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
2825 
2826  if (rv)
2827  {
2828  pool_put (am->nd_events, event);
2829  goto reply;
2830  }
2831  clib_memset (event, 0, sizeof (*event));
2832 
2833  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2834  event->client_index = mp->client_index;
2835  ip6_address_encode (&ip6, event->ip);
2836  event->pid = mp->pid;
2837  }
2838  else
2839  {
2842  mp->pid, &ip6 /* addr, in net byte order */ ,
2844  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2845  }
2846 reply:
2847  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
2848 }
2849 
2850 static clib_error_t *
2852 {
2853 
2855  vl_api_ip6_nd_event_t *event;
2856  u32 *to_delete, *event_id;
2857  vpe_api_main_t *am;
2858  vnet_main_t *vnm;
2859  uword *p;
2860 
2861  am = &vpe_api_main;
2862  vnm = vnet_get_main ();
2863  to_delete = NULL;
2864 
2865  /* clear out all of its pending resolutions */
2866  /* *INDENT-OFF* */
2867  pool_foreach(event, am->nd_events,
2868  ({
2869  if (event->client_index == client_index)
2870  {
2871  vec_add1(to_delete, event - am->nd_events);
2872  }
2873  }));
2874  /* *INDENT-ON* */
2875 
2876  vec_foreach (event_id, to_delete)
2877  {
2878  event = pool_elt_at_index (am->nd_events, *event_id);
2881  event->pid, event->ip,
2883  ~0 /* pool index, notused */ , 0 /* is_add */ );
2884  }
2885  vec_free (to_delete);
2886 
2887  /* remove from the registration hash */
2888  p = hash_get (am->wc_ip6_nd_events_registration_hash, client_index);
2889 
2890  if (p)
2891  {
2892  rp = pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2893  pool_put (am->wc_ip6_nd_events_registrations, rp);
2894  hash_unset (am->wc_ip6_nd_events_registration_hash, client_index);
2895  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2897  }
2898  return (NULL);
2899 }
2900 
2902 
2903 static void
2905 {
2907  vl_api_want_ip6_ra_events_reply_t *rmp;
2908  int rv = 0;
2909 
2910  uword *p = hash_get (am->ip6_ra_events_registration_hash, mp->client_index);
2912  if (p)
2913  {
2914  if (mp->enable_disable)
2915  {
2916  clib_warning ("pid %d: already enabled...", ntohl (mp->pid));
2917  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2918  goto reply;
2919  }
2920  else
2921  {
2922  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2923  pool_put (am->ip6_ra_events_registrations, rp);
2924  hash_unset (am->ip6_ra_events_registration_hash, mp->client_index);
2925  goto reply;
2926  }
2927  }
2928  if (mp->enable_disable == 0)
2929  {
2930  clib_warning ("pid %d: already disabled...", ntohl (mp->pid));
2931  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2932  goto reply;
2933  }
2934  pool_get (am->ip6_ra_events_registrations, rp);
2935  rp->client_index = mp->client_index;
2936  rp->client_pid = ntohl (mp->pid);
2937  hash_set (am->ip6_ra_events_registration_hash, rp->client_index,
2938  rp - am->ip6_ra_events_registrations);
2939 
2940 reply:
2941  REPLY_MACRO (VL_API_WANT_IP6_RA_EVENTS_REPLY);
2942 }
2943 
2944 static clib_error_t *
2946 {
2949  uword *p;
2950 
2951  p = hash_get (am->ip6_ra_events_registration_hash, client_index);
2952 
2953  if (p)
2954  {
2955  rp = pool_elt_at_index (am->ip6_ra_events_registrations, p[0]);
2956  pool_put (am->ip6_ra_events_registrations, rp);
2957  hash_unset (am->ip6_ra_events_registration_hash, client_index);
2958  }
2959  return (NULL);
2960 }
2961 
2963 
2964 static void
2966 {
2967  vl_api_proxy_arp_add_del_reply_t *rmp;
2968  ip4_address_t lo, hi;
2969  u32 fib_index;
2970  int rv;
2971 
2972  stats_dslock_with_hint (1 /* release hint */ , 6 /* tag */ );
2973 
2974  fib_index = fib_table_find (FIB_PROTOCOL_IP4, ntohl (mp->proxy.table_id));
2975 
2976  if (~0 == fib_index)
2977  {
2978  rv = VNET_API_ERROR_NO_SUCH_FIB;
2979  goto out;
2980  }
2981 
2982  ip4_address_decode (mp->proxy.low, &lo);
2983  ip4_address_decode (mp->proxy.hi, &hi);
2984 
2985  rv = vnet_proxy_arp_add_del (&lo, &hi, fib_index, mp->is_add == 0);
2986 
2987 out:
2988  stats_dsunlock ();
2989  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2990 }
2991 
2993 {
2997 
2998 static walk_rc_t
3000  const ip4_address_t * hi_addr,
3001  u32 fib_index, void *data)
3002 {
3005 
3006  ctx = data;
3007 
3008  mp = vl_msg_api_alloc (sizeof (*mp));
3009  clib_memset (mp, 0, sizeof (*mp));
3010  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_DETAILS);
3011  mp->context = ctx->context;
3012  mp->proxy.table_id = htonl (fib_index);
3013 
3014  ip4_address_encode (lo_addr, mp->proxy.low);
3015  ip4_address_encode (hi_addr, mp->proxy.hi);
3016 
3017  vl_api_send_msg (ctx->reg, (u8 *) mp);
3018 
3019  return (WALK_CONTINUE);
3020 }
3021 
3022 static void
3024 {
3025  vl_api_registration_t *reg;
3026 
3028  if (!reg)
3029  return;
3030 
3031  proxy_arp_walk_ctx_t wctx = {
3032  .reg = reg,
3033  .context = mp->context,
3034  };
3035 
3037 }
3038 
3039 static walk_rc_t
3041  vnet_sw_interface_t * si, void *data)
3042 {
3045 
3047  return (WALK_CONTINUE);
3048 
3049  ctx = data;
3050 
3051  mp = vl_msg_api_alloc (sizeof (*mp));
3052  clib_memset (mp, 0, sizeof (*mp));
3053  mp->_vl_msg_id = ntohs (VL_API_PROXY_ARP_INTFC_DETAILS);
3054  mp->context = ctx->context;
3055  mp->sw_if_index = htonl (si->sw_if_index);
3056 
3057  vl_api_send_msg (ctx->reg, (u8 *) mp);
3058 
3059  return (WALK_CONTINUE);
3060 }
3061 
3062 static void
3064 {
3065  vl_api_registration_t *reg;
3066 
3068  if (!reg)
3069  return;
3070 
3071  proxy_arp_walk_ctx_t wctx = {
3072  .reg = reg,
3073  .context = mp->context,
3074  };
3075 
3078 }
3079 
3080 static void
3083 {
3084  int rv = 0;
3085  vnet_main_t *vnm = vnet_get_main ();
3086  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
3087 
3088  VALIDATE_SW_IF_INDEX (mp);
3089 
3090  vnet_sw_interface_t *si =
3091  vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
3092 
3093  ASSERT (si);
3094 
3095  if (mp->enable_disable)
3097  else
3099 
3101 
3102  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
3103 }
3104 
3105 static void
3107 {
3108  int rv = 0;
3110  vl_api_ip_probe_neighbor_reply_t *rmp;
3111  clib_error_t *error;
3112  ip46_address_t dst;
3113  ip46_type_t itype;
3114 
3115  VALIDATE_SW_IF_INDEX (mp);
3116 
3117  u32 sw_if_index = ntohl (mp->sw_if_index);
3118  itype = ip_address_decode (&mp->dst, &dst);
3119 
3120  if (IP46_TYPE_IP6 == itype)
3121  error = ip6_probe_neighbor (vm, &dst.ip6, sw_if_index, 0);
3122  else
3123  error = ip4_probe_neighbor (vm, &dst.ip4, sw_if_index, 0);
3124 
3125  if (error)
3126  {
3127  clib_error_report (error);
3128  rv = clib_error_get_code (error);
3129  }
3130 
3132 
3133  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
3134 }
3135 
3136 static void
3139 {
3140  int rv = 0;
3141  vl_api_ip_scan_neighbor_enable_disable_reply_t *rmp;
3143 
3144  arg.mode = mp->mode;
3145  arg.scan_interval = mp->scan_interval;
3146  arg.max_proc_time = mp->max_proc_time;
3147  arg.max_update = mp->max_update;
3148  arg.scan_int_delay = mp->scan_int_delay;
3149  arg.stale_threshold = mp->stale_threshold;
3151 
3152  REPLY_MACRO (VL_API_IP_SCAN_NEIGHBOR_ENABLE_DISABLE_REPLY);
3153 }
3154 
3155 static int
3157 {
3158  vnet_main_t *vnm = vnet_get_main ();
3160  ip4_main_t *im4 = &ip4_main;
3161  static u32 *sw_if_indices_to_shut;
3162  fib_table_t *fib_table;
3163  ip4_fib_t *fib;
3164  u32 sw_if_index;
3165  int i;
3166  int rv = VNET_API_ERROR_NO_SUCH_FIB;
3167  u32 target_fib_id = ntohl (mp->vrf_id);
3168 
3169  stats_dslock_with_hint (1 /* release hint */ , 8 /* tag */ );
3170 
3171  /* *INDENT-OFF* */
3172  pool_foreach (fib_table, im4->fibs,
3173  ({
3174  vnet_sw_interface_t * si;
3175 
3176  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
3177 
3178  if (fib->table_id != target_fib_id)
3179  continue;
3180 
3181  /* remove any mpls encap/decap labels */
3182  mpls_fib_reset_labels (fib->table_id);
3183 
3184  /* remove any proxy arps in this fib */
3185  vnet_proxy_arp_fib_reset (fib->table_id);
3186 
3187  /* Set the flow hash for this fib to the default */
3188  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
3189 
3190  vec_reset_length (sw_if_indices_to_shut);
3191 
3192  /* Shut down interfaces in this FIB / clean out intfc routes */
3193  pool_foreach (si, im->sw_interfaces,
3194  ({
3195  u32 sw_if_index = si->sw_if_index;
3196 
3197  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
3198  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
3199  fib->index))
3200  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3201  }));
3202 
3203  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
3204  sw_if_index = sw_if_indices_to_shut[i];
3205 
3206  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3207  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3208  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3209  }
3210 
3212 
3213  rv = 0;
3214  break;
3215  })); /* pool_foreach (fib) */
3216  /* *INDENT-ON* */
3217 
3218  stats_dsunlock ();
3219  return rv;
3220 }
3221 
3222 static int
3224 {
3225  vnet_main_t *vnm = vnet_get_main ();
3227  ip6_main_t *im6 = &ip6_main;
3228  static u32 *sw_if_indices_to_shut;
3229  fib_table_t *fib_table;
3230  ip6_fib_t *fib;
3231  u32 sw_if_index;
3232  int i;
3233  int rv = VNET_API_ERROR_NO_SUCH_FIB;
3234  u32 target_fib_id = ntohl (mp->vrf_id);
3235 
3236  stats_dslock_with_hint (1 /* release hint */ , 9 /* tag */ );
3237 
3238  /* *INDENT-OFF* */
3239  pool_foreach (fib_table, im6->fibs,
3240  ({
3241  vnet_sw_interface_t * si;
3242 
3243  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
3244 
3245  if (fib->table_id != target_fib_id)
3246  continue;
3247 
3248  vec_reset_length (sw_if_indices_to_shut);
3249 
3250  /* Set the flow hash for this fib to the default */
3251  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
3252 
3253  /* Shut down interfaces in this FIB / clean out intfc routes */
3254  pool_foreach (si, im->sw_interfaces,
3255  ({
3256  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
3257  fib->index)
3258  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
3259  }));
3260 
3261  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
3262  sw_if_index = sw_if_indices_to_shut[i];
3263 
3264  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
3265  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
3266  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
3267  }
3268 
3270 
3271  rv = 0;
3272  break;
3273  })); /* pool_foreach (fib) */
3274  /* *INDENT-ON* */
3275 
3276  stats_dsunlock ();
3277  return rv;
3278 }
3279 
3280 static void
3282 {
3283  int rv;
3284  vl_api_reset_fib_reply_t *rmp;
3285 
3286  if (mp->is_ipv6)
3287  rv = ip6_reset_fib_t_handler (mp);
3288  else
3289  rv = ip4_reset_fib_t_handler (mp);
3290 
3291  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
3292 }
3293 
3294 static void
3296 {
3297  int rv;
3298  vl_api_set_arp_neighbor_limit_reply_t *rmp;
3299  vnet_main_t *vnm = vnet_get_main ();
3300  clib_error_t *error;
3301 
3302  vnm->api_errno = 0;
3303 
3304  if (mp->is_ipv6)
3305  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
3306  else
3307  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
3308 
3309  if (error)
3310  {
3311  clib_error_report (error);
3312  rv = VNET_API_ERROR_UNSPECIFIED;
3313  }
3314  else
3315  {
3316  rv = vnm->api_errno;
3317  }
3318 
3319  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
3320 }
3321 
3322 void
3324 {
3325  vl_api_ip_reassembly_set_reply_t *rmp;
3326  int rv = 0;
3327  if (mp->is_ip6)
3328  {
3329  rv = ip6_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
3330  clib_net_to_host_u32 (mp->max_reassemblies),
3331  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
3332  }
3333  else
3334  {
3335  rv = ip4_reass_set (clib_net_to_host_u32 (mp->timeout_ms),
3336  clib_net_to_host_u32 (mp->max_reassemblies),
3337  clib_net_to_host_u32 (mp->expire_walk_interval_ms));
3338  }
3339 
3340  REPLY_MACRO (VL_API_IP_REASSEMBLY_SET_REPLY);
3341 }
3342 
3343 void
3345 {
3347 
3349  if (rp == 0)
3350  return;
3351 
3352  vl_api_ip_reassembly_get_reply_t *rmp = vl_msg_api_alloc (sizeof (*rmp));
3353  clib_memset (rmp, 0, sizeof (*rmp));
3354  rmp->_vl_msg_id = ntohs (VL_API_IP_REASSEMBLY_GET_REPLY);
3355  rmp->context = mp->context;
3356  rmp->retval = 0;
3357  if (mp->is_ip6)
3358  {
3359  rmp->is_ip6 = 1;
3361  &rmp->expire_walk_interval_ms);
3362  }
3363  else
3364  {
3365  rmp->is_ip6 = 0;
3367  &rmp->expire_walk_interval_ms);
3368  }
3369  rmp->timeout_ms = clib_host_to_net_u32 (rmp->timeout_ms);
3370  rmp->max_reassemblies = clib_host_to_net_u32 (rmp->max_reassemblies);
3372  clib_host_to_net_u32 (rmp->expire_walk_interval_ms);
3373  vl_api_send_msg (rp, (u8 *) rmp);
3374 }
3375 
3376 void
3379 {
3380  vl_api_ip_reassembly_enable_disable_reply_t *rmp;
3381  int rv = 0;
3382  rv = ip4_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
3383  mp->enable_ip4);
3384  if (0 == rv)
3385  {
3386  rv = ip6_reass_enable_disable (clib_net_to_host_u32 (mp->sw_if_index),
3387  mp->enable_ip6);
3388  }
3389 
3390  REPLY_MACRO (VL_API_IP_REASSEMBLY_ENABLE_DISABLE_REPLY);
3391 }
3392 
3393 void
3396  ip_punt_redirect_rx_t * pr, u8 is_ipv6)
3397 {
3399 
3400  mp = vl_msg_api_alloc (sizeof (*mp));
3401  if (!mp)
3402  return;
3403 
3404  clib_memset (mp, 0, sizeof (*mp));
3405  mp->_vl_msg_id = ntohs (VL_API_IP_PUNT_REDIRECT_DETAILS);
3406  mp->context = context;
3407  mp->punt.rx_sw_if_index = htonl (sw_if_index);
3408  mp->punt.tx_sw_if_index = htonl (pr->tx_sw_if_index);
3409  if (is_ipv6)
3410  {
3411  ip_address_encode (&pr->nh, IP46_TYPE_IP6, &mp->punt.nh);
3412  }
3413  else
3414  {
3415  ip_address_encode (&pr->nh, IP46_TYPE_IP4, &mp->punt.nh);
3416  }
3417 
3418  vl_api_send_msg (reg, (u8 *) mp);
3419 }
3420 
3421 static void
3423 {
3424  vl_api_registration_t *reg;
3425  u32 sw_if_index;
3426  int rv __attribute__ ((unused)) = 0;
3427 
3428  sw_if_index = ntohl (mp->sw_if_index);
3430  if (!reg)
3431  return;
3432 
3433  if (~0 != sw_if_index)
3434  VALIDATE_SW_IF_INDEX (mp);
3435 
3436  ip_punt_redirect_detail_t *pr, *prs;
3437  if (mp->is_ipv6)
3438  {
3439  prs = ip6_punt_redirect_entries (sw_if_index);
3440  /* *INDENT-OFF* */
3441  vec_foreach (pr, prs)
3442  {
3444  }
3445  /* *INDENT-ON* */
3446  vec_free (prs);
3447  }
3448  else
3449  {
3450  prs = ip4_punt_redirect_entries (sw_if_index);
3451  /* *INDENT-OFF* */
3452  vec_foreach (pr, prs)
3453  {
3455  }
3456  /* *INDENT-ON* */
3457  vec_free (prs);
3458  }
3459 
3461 }
3462 
3463 #define vl_msg_name_crc_list
3464 #include <vnet/ip/ip.api.h>
3465 #undef vl_msg_name_crc_list
3466 
3467 static void
3469 {
3470 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
3471  foreach_vl_msg_name_crc_ip;
3472 #undef _
3473 }
3474 
3475 static clib_error_t *
3477 {
3478  api_main_t *am = &api_main;
3479 
3480 #define _(N,n) \
3481  vl_msg_api_set_handlers(VL_API_##N, #n, \
3482  vl_api_##n##_t_handler, \
3483  vl_noop_handler, \
3484  vl_api_##n##_t_endian, \
3485  vl_api_##n##_t_print, \
3486  sizeof(vl_api_##n##_t), 1);
3488 #undef _
3489 
3490  /*
3491  * Mark the route add/del API as MP safe
3492  */
3493  am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE] = 1;
3494  am->is_mp_safe[VL_API_IP_ADD_DEL_ROUTE_REPLY] = 1;
3495 
3496  /*
3497  * Set up the (msg_name, crc, message-id) table
3498  */
3500 
3502 
3503  return 0;
3504 }
3505 
3507 
3508 /*
3509  * fd.io coding-style-patch-verification: ON
3510  *
3511  * Local Variables:
3512  * eval: (c-set-style "gnu")
3513  * End:
3514  */
#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:1688
static void vl_api_proxy_arp_intfc_enable_disable_t_handler(vl_api_proxy_arp_intfc_enable_disable_t *mp)
Definition: ip_api.c:3082
Proxy ARP add / del request.
Definition: ip.api:966
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:585
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:971
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:2282
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:988
Register for IP6 ND resolution event on recieving NA reply MAC/IP info from ICMP6 Neighbor Solicitati...
Definition: ip.api:854
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:1803
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:1029
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:1946
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:2746
Register for ip6 router advertisement events.
Definition: ip.api:893
static uword resolver_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:2345
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:661
#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:2999
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:492
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:1008
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:860
#define REPLY_MACRO2(t, body)
#define NULL
Definition: clib.h:58
iOAM disable
Definition: ip.api:1075
An entry in a FIB table.
Definition: mfib_entry.h:32
Set max allowed ARP or ip6 neighbor entries request.
Definition: ip.api:1043
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:836
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:2214
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:523
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:2389
vl_api_punt_redirect_t punt
Definition: ip.api:665
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:551
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:3323
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:1678
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:1970
static void vl_api_proxy_arp_intfc_dump_t_handler(vl_api_proxy_arp_intfc_dump_t *mp)
Definition: ip_api.c:3063
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:2851
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:3378
#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:1762
vl_api_fib_mpls_label_t next_hop_out_label_stack[next_hop_n_out_labels]
Definition: ip.api:424
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:1749
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:2213
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:3344
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:2233
format_function_t format_ip4_address
Definition: format.h:75
Proxy ARP add / del interface request.
Definition: ip.api:997
#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:1236
Dump IP6 multicast fib table.
Definition: ip.api:529
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:736
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:1573
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:1262
static void vl_api_set_arp_neighbor_limit_t_handler(vl_api_set_arp_neighbor_limit_t *mp)
Definition: ip_api.c:3295
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1932
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index, u8 refresh)
Definition: ip6_forward.c:1478
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1616
void send_ip_punt_redirect_details(vl_api_registration_t *reg, u32 context, u32 sw_if_index, ip_punt_redirect_rx_t *pr, u8 is_ipv6)
Definition: ip_api.c:3394
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:3138
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:800
Definition: fib_entry.h:275
Configure IP source and L4 port-range check.
Definition: ip.api:717
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:1316
Set interface source check request.
Definition: ip.api:755
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:2765
#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:795
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:1061
void mfib_table_unlock(u32 fib_index, fib_protocol_t proto, mfib_source_t source)
Take a reference counting lock on the table.
Definition: mfib_table.c:653
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:43
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:2965
static void vl_api_sw_interface_ip6nd_ra_prefix_t_handler(vl_api_sw_interface_ip6nd_ra_prefix_t *mp)
Definition: ip_api.c:1696
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:543
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:833
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:985
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:830
vl_api_ip4_address_t low
Definition: ip.api:956
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:1726
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:1846
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1651
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:1058
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:1993
void stats_dsunlock(void)
static void vl_api_ip_unnumbered_dump_t_handler(vl_api_ip_unnumbered_dump_t *mp)
Definition: ip_api.c:1523
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:202
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1451
static clib_error_t * want_ip6_ra_events_reaper(u32 client_index)
Definition: ip_api.c:2945
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:2994
The IPv4 FIB.
Definition: ip4_fib.h:39
#define BAD_SW_IF_INDEX_LABEL
Proxy ARP interface dump details reply.
Definition: ip.api:1017
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:2602
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:1097
static void vl_api_ip_container_proxy_dump_t_handler(vl_api_ip_container_proxy_dump_t *mp)
Definition: ip_api.c:1998
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:1403
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:2410
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:2054
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:1612
#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:3023
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:575
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:1421
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:2036
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:3281
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:3156
void vl_api_ip_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:1381
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:957
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:2680
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:2219
static int ip_container_proxy_send_details(const fib_prefix_t *pfx, u32 sw_if_index, void *args)
Definition: ip_api.c:1975
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:1631
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:2416
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:2190
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: ip_api.c:2016
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:3106
#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:3476
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:2216
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:2818
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:680
void fib_entry_encode(fib_node_index_t fib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: fib_entry.c:1652
vl_api_address_t nh
Definition: ip.api:652
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:394
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:3468
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:877
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:776
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:2625
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:976
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:2713
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:1661
Tell client about an IP6 ND resolution or MAC/IP info from ICMP6 Neighbor Solicitation in L2 BDs...
Definition: ip.api:872
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:878
u32 client_index
Definition: ip.api:601
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:812
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:101
Enable/disable reassembly feature.
Definition: ip.api:1116
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:631
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:3422
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:1196
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:1450
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:818
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:462
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:1170
#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:1879
static walk_rc_t send_proxy_arp_intfc_details(vnet_main_t *vnm, vnet_sw_interface_t *si, void *data)
Definition: ip_api.c:3040
static void handle_ip6_nd_event(u32 pool_index)
Definition: ip_api.c:2296
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:1820
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:2130
#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:3223
u32 itf_flags
Definition: ip.api:509
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:2904
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:1505
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