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