FD.io VPP  v18.01-8-g0eacf49
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 
46 #include <vnet/vnet_msg_enum.h>
47 
48 #define vl_typedefs /* define message structures */
49 #include <vnet/vnet_all_api_h.h>
50 #undef vl_typedefs
51 
52 #define vl_endianfun /* define message structures */
53 #include <vnet/vnet_all_api_h.h>
54 #undef vl_endianfun
55 
56 /* instantiate all the print functions we know about */
57 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
58 #define vl_printfun
59 #include <vnet/vnet_all_api_h.h>
60 #undef vl_printfun
61 
63 
64 
65 #define foreach_ip_api_msg \
66 _(IP_FIB_DUMP, ip_fib_dump) \
67 _(IP6_FIB_DUMP, ip6_fib_dump) \
68 _(IP_MFIB_DUMP, ip_mfib_dump) \
69 _(IP6_MFIB_DUMP, ip6_mfib_dump) \
70 _(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
71 _(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
72 _(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
73 _(IP_ADDRESS_DUMP, ip_address_dump) \
74 _(IP_DUMP, ip_dump) \
75 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
76 _(SET_ARP_NEIGHBOR_LIMIT, set_arp_neighbor_limit) \
77 _(WANT_IP4_ARP_EVENTS, want_ip4_arp_events) \
78 _(WANT_IP6_ND_EVENTS, want_ip6_nd_events) \
79 _(PROXY_ARP_ADD_DEL, proxy_arp_add_del) \
80 _(PROXY_ARP_INTFC_ENABLE_DISABLE, proxy_arp_intfc_enable_disable) \
81 _(RESET_FIB, reset_fib) \
82 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
83 _(IP_TABLE_ADD_DEL, ip_table_add_del) \
84 _(IP_PUNT_POLICE, ip_punt_police) \
85 _(IP_PUNT_REDIRECT, ip_punt_redirect) \
86 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
87 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
88 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
89 _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
90 _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
91 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
92 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
93  sw_interface_ip6_set_link_local_address) \
94 _(IP_CONTAINER_PROXY_ADD_DEL, ip_container_proxy_add_del) \
95 _(IOAM_ENABLE, ioam_enable) \
96 _(IOAM_DISABLE, ioam_disable) \
97 _(IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL, \
98  ip_source_and_port_range_check_add_del) \
99 _(IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL, \
100  ip_source_and_port_range_check_interface_add_del)
101 
102 extern void stats_dslock_with_hint (int hint, int tag);
103 extern void stats_dsunlock (void);
104 
105 static void
107  u8 is_ipv6,
108  u8 is_static,
109  u8 * mac_address,
110  u8 * ip_address,
111  unix_shared_memory_queue_t * q, u32 context)
112 {
114 
115  mp = vl_msg_api_alloc (sizeof (*mp));
116  memset (mp, 0, sizeof (*mp));
117  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
118  mp->context = context;
119  mp->sw_if_index = htonl (sw_if_index);
120  mp->is_ipv6 = is_ipv6;
121  mp->is_static = is_static;
122  memcpy (mp->mac_address, mac_address, 6);
123  memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
124 
125  vl_msg_api_send_shmem (q, (u8 *) & mp);
126 }
127 
128 static void
130 {
132 
134  if (q == 0)
135  return;
136 
137  u32 sw_if_index = ntohl (mp->sw_if_index);
138 
139  if (mp->is_ipv6)
140  {
141  ip6_neighbor_t *n, *ns;
142 
143  ns = ip6_neighbors_entries (sw_if_index);
144  /* *INDENT-OFF* */
145  vec_foreach (n, ns)
146  {
148  (sw_if_index, mp->is_ipv6,
149  ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0),
150  (u8 *) n->link_layer_address,
151  (u8 *) & (n->key.ip6_address.as_u8),
152  q, mp->context);
153  }
154  /* *INDENT-ON* */
155  vec_free (ns);
156  }
157  else
158  {
159  ethernet_arp_ip4_entry_t *n, *ns;
160 
161  ns = ip4_neighbor_entries (sw_if_index);
162  /* *INDENT-OFF* */
163  vec_foreach (n, ns)
164  {
165  send_ip_neighbor_details (sw_if_index, mp->is_ipv6,
166  ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0),
167  (u8*) n->ethernet_address,
168  (u8*) & (n->ip4_address.as_u8),
169  q, mp->context);
170  }
171  /* *INDENT-ON* */
172  vec_free (ns);
173  }
174 }
175 
176 
177 void
178 copy_fib_next_hop (fib_route_path_encode_t * api_rpath, void *fp_arg)
179 {
180  int is_ip4;
181  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
182 
183  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
184  fp->afi = IP46_TYPE_IP4;
185  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
186  fp->afi = IP46_TYPE_IP6;
187  else
188  {
189  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
190  if (is_ip4)
191  fp->afi = IP46_TYPE_IP4;
192  else
193  fp->afi = IP46_TYPE_IP6;
194  }
195  if (fp->afi == IP46_TYPE_IP4)
196  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
197  sizeof (api_rpath->rpath.frp_addr.ip4));
198  else
199  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
200  sizeof (api_rpath->rpath.frp_addr.ip6));
201 }
202 
203 static void
206  const fib_table_t * table,
207  const fib_prefix_t * pfx,
208  fib_route_path_encode_t * api_rpaths, u32 context)
209 {
211  fib_route_path_encode_t *api_rpath;
212  vl_api_fib_path_t *fp;
213  int path_count;
214 
215  path_count = vec_len (api_rpaths);
216  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
217  if (!mp)
218  return;
219  memset (mp, 0, sizeof (*mp));
220  mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
221  mp->context = context;
222 
223  mp->table_id = htonl (table->ft_table_id);
224  memcpy (mp->table_name, table->ft_desc,
225  clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
226  mp->address_length = pfx->fp_len;
227  memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
228 
229  mp->count = htonl (path_count);
230  fp = mp->path;
231  vec_foreach (api_rpath, api_rpaths)
232  {
233  memset (fp, 0, sizeof (*fp));
234  switch (api_rpath->dpo.dpoi_type)
235  {
236  case DPO_RECEIVE:
237  fp->is_local = true;
238  break;
239  case DPO_DROP:
240  fp->is_drop = true;
241  break;
242  case DPO_IP_NULL:
243  switch (api_rpath->dpo.dpoi_index)
244  {
245  case IP_NULL_ACTION_NONE:
246  fp->is_drop = true;
247  break;
249  fp->is_unreach = true;
250  break;
252  fp->is_prohibit = true;
253  break;
254  default:
255  break;
256  }
257  break;
258  default:
259  break;
260  }
261  fp->weight = api_rpath->rpath.frp_weight;
262  fp->preference = api_rpath->rpath.frp_preference;
263  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
264  copy_fib_next_hop (api_rpath, fp);
265  fp++;
266  }
267 
268  vl_msg_api_send_shmem (q, (u8 *) & mp);
269 }
270 
272 {
275 
276 static int
278 {
280 
281  vec_add1 (ctx->feis, fei);
282 
283  return (1);
284 }
285 
286 static void
288 {
291  ip4_main_t *im = &ip4_main;
292  fib_table_t *fib_table;
293  fib_node_index_t *lfeip;
294  fib_prefix_t pfx;
295  u32 fib_index;
296  fib_route_path_encode_t *api_rpaths;
298  .feis = NULL,
299  };
300 
302  if (q == 0)
303  return;
304 
305  /* *INDENT-OFF* */
306  pool_foreach (fib_table, im->fibs,
307  ({
308  fib_table_walk(fib_table->ft_index,
309  FIB_PROTOCOL_IP4,
310  vl_api_ip_fib_dump_walk,
311  &ctx);
312  }));
313  /* *INDENT-ON* */
314 
316 
317  vec_foreach (lfeip, ctx.feis)
318  {
319  fib_entry_get_prefix (*lfeip, &pfx);
320  fib_index = fib_entry_get_fib_index (*lfeip);
321  fib_table = fib_table_get (fib_index, pfx.fp_proto);
322  api_rpaths = NULL;
323  fib_entry_encode (*lfeip, &api_rpaths);
324  send_ip_fib_details (am, q, fib_table, &pfx, api_rpaths, mp->context);
325  vec_free (api_rpaths);
326  }
327 
328  vec_free (ctx.feis);
329 }
330 
331 static void
334  const fib_table_t * table,
335  const fib_prefix_t * pfx,
336  fib_route_path_encode_t * api_rpaths, u32 context)
337 {
339  fib_route_path_encode_t *api_rpath;
340  vl_api_fib_path_t *fp;
341  int path_count;
342 
343  path_count = vec_len (api_rpaths);
344  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
345  if (!mp)
346  return;
347  memset (mp, 0, sizeof (*mp));
348  mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
349  mp->context = context;
350 
351  mp->table_id = htonl (table->ft_table_id);
352  mp->address_length = pfx->fp_len;
353  memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
354  memcpy (mp->table_name, table->ft_desc,
355  clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
356 
357  mp->count = htonl (path_count);
358  fp = mp->path;
359  vec_foreach (api_rpath, api_rpaths)
360  {
361  memset (fp, 0, sizeof (*fp));
362  switch (api_rpath->dpo.dpoi_type)
363  {
364  case DPO_RECEIVE:
365  fp->is_local = true;
366  break;
367  case DPO_DROP:
368  fp->is_drop = true;
369  break;
370  case DPO_IP_NULL:
371  switch (api_rpath->dpo.dpoi_index)
372  {
374  fp->is_drop = true;
375  break;
377  fp->is_unreach = true;
378  break;
380  fp->is_prohibit = true;
381  break;
382  default:
383  break;
384  }
385  break;
386  default:
387  break;
388  }
389  fp->weight = api_rpath->rpath.frp_weight;
390  fp->preference = api_rpath->rpath.frp_preference;
391  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
392  copy_fib_next_hop (api_rpath, fp);
393  fp++;
394  }
395 
396  vl_msg_api_send_shmem (q, (u8 *) & mp);
397 }
398 
400 {
404 
405 static void
407 {
409 
410  if ((kvp->key[2] >> 32) == ctx->fib_index)
411  {
412  vec_add1 (ctx->entries, kvp->value);
413  }
414 }
415 
416 static void
419  fib_table_t * fib_table)
420 {
422  ip6_main_t *im6 = &ip6_main;
423  fib_node_index_t *fib_entry_index;
425  .fib_index = fib_table->ft_index,
426  .entries = NULL,
427  };
428  fib_route_path_encode_t *api_rpaths;
429  fib_prefix_t pfx;
430 
432  ((BVT (clib_bihash) *) & im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].
433  ip6_hash, api_ip6_fib_table_put_entries, &ctx);
434 
436 
437  vec_foreach (fib_entry_index, ctx.entries)
438  {
439  fib_entry_get_prefix (*fib_entry_index, &pfx);
440  api_rpaths = NULL;
441  fib_entry_encode (*fib_entry_index, &api_rpaths);
442  send_ip6_fib_details (am, q, fib_table, &pfx, api_rpaths, mp->context);
443  vec_free (api_rpaths);
444  }
445 
446  vec_free (ctx.entries);
447 }
448 
449 static void
451 {
453  ip6_main_t *im6 = &ip6_main;
454  fib_table_t *fib_table;
455 
457  if (q == 0)
458  return;
459 
460  /* *INDENT-OFF* */
461  pool_foreach (fib_table, im6->fibs,
462  ({
463  api_ip6_fib_table_get_all(q, mp, fib_table);
464  }));
465  /* *INDENT-ON* */
466 }
467 
468 static void
470  u32 context, u32 table_id, fib_node_index_t mfei)
471 {
472  fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
474  mfib_entry_t *mfib_entry;
475  vl_api_fib_path_t *fp;
476  mfib_prefix_t pfx;
477  int path_count;
478 
479  mfib_entry = mfib_entry_get (mfei);
480  mfib_entry_get_prefix (mfei, &pfx);
481  mfib_entry_encode (mfei, &api_rpaths);
482 
483  path_count = vec_len (api_rpaths);
484  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
485  if (!mp)
486  return;
487  memset (mp, 0, sizeof (*mp));
488  mp->_vl_msg_id = ntohs (VL_API_IP_MFIB_DETAILS);
489  mp->context = context;
490 
491  mp->rpf_id = mfib_entry->mfe_rpf_id;
492  mp->entry_flags = mfib_entry->mfe_flags;
493  mp->table_id = htonl (table_id);
494  mp->address_length = pfx.fp_len;
495  memcpy (mp->grp_address, &pfx.fp_grp_addr.ip4,
496  sizeof (pfx.fp_grp_addr.ip4));
497  memcpy (mp->src_address, &pfx.fp_src_addr.ip4,
498  sizeof (pfx.fp_src_addr.ip4));
499 
500  mp->count = htonl (path_count);
501  fp = mp->path;
502  vec_foreach (api_rpath, api_rpaths)
503  {
504  memset (fp, 0, sizeof (*fp));
505 
506  fp->weight = 0;
507  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
508  copy_fib_next_hop (api_rpath, fp);
509  fp++;
510  }
511  vec_free (api_rpaths);
512 
513  vl_msg_api_send_shmem (q, (u8 *) & mp);
514 }
515 
517 {
520 
521 static int
523 {
525 
526  vec_add1 (ctx->entries, fei);
527 
528  return (0);
529 }
530 
531 static void
533 {
535  ip4_main_t *im = &ip4_main;
536  mfib_table_t *mfib_table;
537  fib_node_index_t *mfeip;
539  .entries = NULL,
540  };
541 
543  if (q == 0)
544  return;
545 
546 
547  /* *INDENT-OFF* */
548  pool_foreach (mfib_table, im->mfibs,
549  ({
550  ip4_mfib_table_walk(&mfib_table->v4,
551  vl_api_ip_mfib_table_dump_walk,
552  &ctx);
553 
554  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
555 
556  vec_foreach (mfeip, ctx.entries)
557  {
558  send_ip_mfib_details (q, mp->context,
559  mfib_table->mft_table_id,
560  *mfeip);
561  }
563 
564  }));
565  /* *INDENT-ON* */
566 
567  vec_free (ctx.entries);
568 }
569 
570 static void
573  u32 table_id,
574  mfib_prefix_t * pfx,
575  fib_route_path_encode_t * api_rpaths, u32 context)
576 {
578  fib_route_path_encode_t *api_rpath;
579  vl_api_fib_path_t *fp;
580  int path_count;
581 
582  path_count = vec_len (api_rpaths);
583  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
584  if (!mp)
585  return;
586  memset (mp, 0, sizeof (*mp));
587  mp->_vl_msg_id = ntohs (VL_API_IP6_MFIB_DETAILS);
588  mp->context = context;
589 
590  mp->table_id = htonl (table_id);
591  mp->address_length = pfx->fp_len;
592  memcpy (mp->grp_address, &pfx->fp_grp_addr.ip6,
593  sizeof (pfx->fp_grp_addr.ip6));
594  memcpy (mp->src_address, &pfx->fp_src_addr.ip6,
595  sizeof (pfx->fp_src_addr.ip6));
596 
597  mp->count = htonl (path_count);
598  fp = mp->path;
599  vec_foreach (api_rpath, api_rpaths)
600  {
601  memset (fp, 0, sizeof (*fp));
602 
603  fp->weight = 0;
604  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
605  copy_fib_next_hop (api_rpath, fp);
606  fp++;
607  }
608 
609  vl_msg_api_send_shmem (q, (u8 *) & mp);
610 }
611 
613 {
616 
617 static int
619 {
621 
622  vec_add1 (ctx->entries, fei);
623 
624  return (0);
625 }
626 
627 static void
629 {
632  ip6_main_t *im = &ip6_main;
633  mfib_table_t *mfib_table;
634  fib_node_index_t *mfeip;
635  mfib_prefix_t pfx;
636  fib_route_path_encode_t *api_rpaths = NULL;
638  .entries = NULL,
639  };
640 
642  if (q == 0)
643  return;
644 
645 
646  /* *INDENT-OFF* */
647  pool_foreach (mfib_table, im->mfibs,
648  ({
649  ip6_mfib_table_walk(&mfib_table->v6,
650  vl_api_ip6_mfib_table_dump_walk,
651  &ctx);
652 
653  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
654 
655  vec_foreach(mfeip, ctx.entries)
656  {
657  mfib_entry_get_prefix (*mfeip, &pfx);
658  mfib_entry_encode (*mfeip, &api_rpaths);
659  send_ip6_mfib_details (am, q,
660  mfib_table->mft_table_id,
661  &pfx, api_rpaths,
662  mp->context);
663  }
664  vec_reset_length (api_rpaths);
666 
667  }));
668  /* *INDENT-ON* */
669 
670  vec_free (ctx.entries);
671  vec_free (api_rpaths);
672 }
673 
674 static void
676  vlib_main_t * vm)
677 {
678  vl_api_ip_punt_police_reply_t *rmp;
679  int rv = 0;
680 
681  if (mp->is_ip6)
682  ip6_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
683  else
684  ip4_punt_policer_add_del (mp->is_add, ntohl (mp->policer_index));
685 
686  REPLY_MACRO (VL_API_IP_PUNT_POLICE_REPLY);
687 }
688 
689 static void
691  vlib_main_t * vm)
692 {
693  vl_api_ip_punt_redirect_reply_t *rmp;
694  int rv = 0;
695 
696  if (mp->is_add)
697  {
698  ip46_address_t nh;
699 
700  memset (&nh, 0, sizeof (nh));
701 
702  if (mp->is_ip6)
703  {
704  memcpy (&nh.ip6, mp->nh, sizeof (nh.ip6));
705 
707  ntohl (mp->tx_sw_if_index), &nh);
708  }
709  else
710  {
711  memcpy (&nh.ip4, mp->nh, sizeof (nh.ip4));
712 
714  ntohl (mp->tx_sw_if_index), &nh);
715  }
716  }
717  else
718  {
719  if (mp->is_ip6)
720  {
722  }
723  else
724  {
726  }
727  }
728 
729  REPLY_MACRO (VL_API_IP_PUNT_REDIRECT_REPLY);
730 }
731 
732 static void
734  vlib_main_t * vm)
735 {
736  vl_api_ip_neighbor_add_del_reply_t *rmp;
737  vnet_main_t *vnm = vnet_get_main ();
738  int rv = 0;
739 
741 
742  stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ );
743 
744  /*
745  * there's no validation here of the ND/ARP entry being added.
746  * The expectation is that the FIB will ensure that nothing bad
747  * will come of adding bogus entries.
748  */
749  if (mp->is_ipv6)
750  {
751  if (mp->is_add)
753  (vm, ntohl (mp->sw_if_index),
754  (ip6_address_t *) (mp->dst_address),
755  mp->mac_address, sizeof (mp->mac_address), mp->is_static,
756  mp->is_no_adj_fib);
757  else
759  (vm, ntohl (mp->sw_if_index),
760  (ip6_address_t *) (mp->dst_address),
761  mp->mac_address, sizeof (mp->mac_address));
762  }
763  else
764  {
765  ethernet_arp_ip4_over_ethernet_address_t a;
766 
767  clib_memcpy (&a.ethernet, mp->mac_address, 6);
768  clib_memcpy (&a.ip4, mp->dst_address, 4);
769 
770  if (mp->is_add)
771  rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
772  &a, mp->is_static,
773  mp->is_no_adj_fib);
774  else
775  rv =
776  vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
777  }
778 
779  stats_dsunlock ();
780 
782  REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
783 }
784 
785 void
786 ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
787 {
788  u32 fib_index, mfib_index;
789 
790  /*
791  * ignore action on the default table - this is always present
792  * and cannot be added nor deleted from the API
793  */
794  if (0 != table_id)
795  {
796  /*
797  * The API holds only one lock on the table.
798  * i.e. it can be added many times via the API but needs to be
799  * deleted only once.
800  * The FIB index for unicast and multicast is not necessarily the
801  * same, since internal VPP systesm (like LISP and SR) create
802  * their own unicast tables.
803  */
804  fib_index = fib_table_find (fproto, table_id);
805  mfib_index = mfib_table_find (fproto, table_id);
806 
807  if (~0 != fib_index)
808  {
809  fib_table_unlock (fib_index, fproto,
810  (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
811  }
812  if (~0 != mfib_index)
813  {
814  mfib_table_unlock (mfib_index, fproto,
815  (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
816  }
817  }
818 }
819 
820 void
822 {
823  vl_api_ip_table_add_del_reply_t *rmp;
825  u32 table_id = ntohl (mp->table_id);
826  int rv = 0;
827 
828  if (mp->is_add)
829  {
830  ip_table_create (fproto, table_id, 1, mp->name);
831  }
832  else
833  {
834  ip_table_delete (fproto, table_id, 1);
835  }
836 
837  REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
838 }
839 
840 int
842  u8 is_add,
843  u8 is_drop,
844  u8 is_unreach,
845  u8 is_prohibit,
846  u8 is_local,
847  u8 is_multicast,
848  u8 is_classify,
849  u32 classify_table_index,
850  u8 is_resolve_host,
851  u8 is_resolve_attached,
852  u8 is_interface_rx,
853  u8 is_rpf_id,
854  u8 is_l2_bridged,
855  u8 is_source_lookup,
856  u8 is_udp_encap,
857  u32 fib_index,
858  const fib_prefix_t * prefix,
859  dpo_proto_t next_hop_proto,
860  const ip46_address_t * next_hop,
861  u32 next_hop_id,
862  u32 next_hop_sw_if_index,
863  u8 next_hop_fib_index,
864  u16 next_hop_weight,
865  u16 next_hop_preference,
866  mpls_label_t next_hop_via_label,
867  mpls_label_t * next_hop_out_label_stack)
868 {
871  fib_route_path_t path = {
872  .frp_proto = next_hop_proto,
873  .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
874  .frp_sw_if_index = next_hop_sw_if_index,
875  .frp_fib_index = next_hop_fib_index,
876  .frp_weight = next_hop_weight,
877  .frp_preference = next_hop_preference,
878  .frp_label_stack = next_hop_out_label_stack,
879  };
880  fib_route_path_t *paths = NULL;
882 
883  /*
884  * the special INVALID label meams we are not recursing via a
885  * label. Exp-null value is never a valid via-label so that
886  * also means it's not a via-label and means clients that set
887  * it to 0 by default get the expected behaviour
888  */
889  if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
890  {
891  path.frp_proto = DPO_PROTO_MPLS;
892  path.frp_local_label = next_hop_via_label;
893  path.frp_eos = MPLS_NON_EOS;
894  }
895  if (is_l2_bridged)
897  if (is_resolve_host)
898  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
899  if (is_resolve_attached)
901  if (is_interface_rx)
902  path_flags |= FIB_ROUTE_PATH_INTF_RX;
903  if (is_rpf_id)
904  path_flags |= FIB_ROUTE_PATH_RPF_ID;
905  if (is_source_lookup)
906  path_flags |= FIB_ROUTE_PATH_SOURCE_LOOKUP;
907  if (is_multicast)
908  entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
909  if (is_udp_encap)
910  {
911  path_flags |= FIB_ROUTE_PATH_UDP_ENCAP;
912  path.frp_udp_encap_id = next_hop_id;
913  }
914  if (path.frp_sw_if_index == ~0 && ip46_address_is_zero (&path.frp_addr)
915  && path.frp_fib_index != ~0)
916  {
917  path_flags |= FIB_ROUTE_PATH_DEAG;
918  }
919 
920  path.frp_flags = path_flags;
921 
922  if (is_multipath)
923  {
924  stats_dslock_with_hint (1 /* release hint */ , 10 /* tag */ );
925 
926 
927  vec_add1 (paths, path);
928 
929  if (is_add)
930  fib_table_entry_path_add2 (fib_index,
931  prefix,
932  FIB_SOURCE_API, entry_flags, paths);
933  else
934  fib_table_entry_path_remove2 (fib_index,
935  prefix, FIB_SOURCE_API, paths);
936 
937  vec_free (paths);
938  stats_dsunlock ();
939  return 0;
940  }
941 
942  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
943 
944  if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
945  {
946  /*
947  * special route types that link directly to the adj
948  */
949  if (is_add)
950  {
951  dpo_id_t dpo = DPO_INVALID;
952  dpo_proto_t dproto;
953 
954  dproto = fib_proto_to_dpo (prefix->fp_proto);
955 
956  if (is_drop)
958  else if (is_local)
959  receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
960  else if (is_unreach)
961  ip_null_dpo_add_and_lock (dproto,
963  else if (is_prohibit)
964  ip_null_dpo_add_and_lock (dproto,
966  &dpo);
967  else if (is_classify)
968  {
969  if (pool_is_free_index (cm->tables,
970  ntohl (classify_table_index)))
971  {
972  stats_dsunlock ();
973  return VNET_API_ERROR_NO_SUCH_TABLE;
974  }
975 
976  dpo_set (&dpo, DPO_CLASSIFY, dproto,
977  classify_dpo_create (dproto,
978  ntohl (classify_table_index)));
979  }
980  else
981  {
982  stats_dsunlock ();
983  return VNET_API_ERROR_NO_SUCH_TABLE;
984  }
985 
987  prefix,
990  dpo_reset (&dpo);
991  }
992  else
993  {
994  fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
995  }
996  }
997  else
998  {
999  if (is_add)
1000  {
1001  vec_add1 (paths, path);
1002  fib_table_entry_update (fib_index,
1003  prefix, FIB_SOURCE_API, entry_flags, paths);
1004  vec_free (paths);
1005  }
1006  else
1007  {
1008  fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
1009  }
1010  }
1011 
1012  stats_dsunlock ();
1013  return (0);
1014 }
1015 
1016 int
1018  u32 table_id,
1019  u32 next_hop_sw_if_index,
1020  dpo_proto_t next_hop_table_proto,
1021  u32 next_hop_table_id,
1022  u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
1023 {
1024  vnet_main_t *vnm = vnet_get_main ();
1025 
1026  /* Temporaray whilst I do the CSIT dance */
1027  u8 create_missing_tables = 1;
1028 
1029  *fib_index = fib_table_find (table_proto, ntohl (table_id));
1030  if (~0 == *fib_index)
1031  {
1032  if (create_missing_tables)
1033  {
1034  *fib_index = fib_table_find_or_create_and_lock (table_proto,
1035  ntohl (table_id),
1036  FIB_SOURCE_API);
1037  }
1038  else
1039  {
1040  /* No such VRF, and we weren't asked to create one */
1041  return VNET_API_ERROR_NO_SUCH_FIB;
1042  }
1043  }
1044 
1045  if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
1046  {
1048  ntohl (next_hop_sw_if_index)))
1049  {
1050  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1051  }
1052  }
1053  else
1054  {
1055  fib_protocol_t fib_nh_proto;
1056 
1057  if (next_hop_table_proto > DPO_PROTO_MPLS)
1058  return (0);
1059 
1060  fib_nh_proto = dpo_proto_to_fib (next_hop_table_proto);
1061 
1062  if (is_rpf_id)
1063  *next_hop_fib_index = mfib_table_find (fib_nh_proto,
1064  ntohl (next_hop_table_id));
1065  else
1066  *next_hop_fib_index = fib_table_find (fib_nh_proto,
1067  ntohl (next_hop_table_id));
1068 
1069  if (~0 == *next_hop_fib_index)
1070  {
1071  if (create_missing_tables)
1072  {
1073  if (is_rpf_id)
1074  *next_hop_fib_index =
1075  mfib_table_find_or_create_and_lock (fib_nh_proto,
1076  ntohl
1077  (next_hop_table_id),
1078  MFIB_SOURCE_API);
1079  else
1080  *next_hop_fib_index =
1081  fib_table_find_or_create_and_lock (fib_nh_proto,
1082  ntohl
1083  (next_hop_table_id),
1084  FIB_SOURCE_API);
1085  }
1086  else
1087  {
1088  /* No such VRF, and we weren't asked to create one */
1089  return VNET_API_ERROR_NO_SUCH_FIB;
1090  }
1091  }
1092  }
1093 
1094  return (0);
1095 }
1096 
1097 static int
1099 {
1100  u32 fib_index, next_hop_fib_index;
1101  mpls_label_t *label_stack = NULL;
1102  int rv, ii, n_labels;;
1103 
1105  mp->table_id,
1107  DPO_PROTO_IP4,
1108  mp->next_hop_table_id,
1109  0, &fib_index, &next_hop_fib_index);
1110 
1111  if (0 != rv)
1112  return (rv);
1113 
1114  fib_prefix_t pfx = {
1115  .fp_len = mp->dst_address_length,
1116  .fp_proto = FIB_PROTOCOL_IP4,
1117  };
1118  clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
1119 
1120  ip46_address_t nh;
1121  memset (&nh, 0, sizeof (nh));
1122  memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
1123 
1124  n_labels = mp->next_hop_n_out_labels;
1125  if (n_labels == 0)
1126  ;
1127  else if (1 == n_labels)
1128  vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
1129  else
1130  {
1131  vec_validate (label_stack, n_labels - 1);
1132  for (ii = 0; ii < n_labels; ii++)
1133  label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
1134  }
1135 
1137  mp->is_add,
1138  mp->is_drop,
1139  mp->is_unreach,
1140  mp->is_prohibit,
1141  mp->is_local, 0,
1142  mp->is_classify,
1144  mp->is_resolve_host,
1145  mp->is_resolve_attached, 0, 0,
1146  mp->is_l2_bridged,
1147  mp->is_source_lookup,
1148  mp->is_udp_encap,
1149  fib_index, &pfx, DPO_PROTO_IP4,
1150  &nh,
1151  ntohl (mp->next_hop_id),
1152  ntohl (mp->next_hop_sw_if_index),
1153  next_hop_fib_index,
1154  mp->next_hop_weight,
1155  mp->next_hop_preference,
1156  ntohl (mp->next_hop_via_label),
1157  label_stack));
1158 }
1159 
1160 static int
1162 {
1163  u32 fib_index, next_hop_fib_index;
1164  mpls_label_t *label_stack = NULL;
1165  int rv, ii, n_labels;;
1166 
1168  mp->table_id,
1170  DPO_PROTO_IP6,
1171  mp->next_hop_table_id,
1172  0, &fib_index, &next_hop_fib_index);
1173 
1174  if (0 != rv)
1175  return (rv);
1176 
1177  fib_prefix_t pfx = {
1178  .fp_len = mp->dst_address_length,
1179  .fp_proto = FIB_PROTOCOL_IP6,
1180  };
1181  clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
1182 
1183  ip46_address_t nh;
1184  memset (&nh, 0, sizeof (nh));
1185  memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
1186 
1187  n_labels = mp->next_hop_n_out_labels;
1188  if (n_labels == 0)
1189  ;
1190  else if (1 == n_labels)
1191  vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
1192  else
1193  {
1194  vec_validate (label_stack, n_labels - 1);
1195  for (ii = 0; ii < n_labels; ii++)
1196  label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
1197  }
1198 
1200  mp->is_add,
1201  mp->is_drop,
1202  mp->is_unreach,
1203  mp->is_prohibit,
1204  mp->is_local, 0,
1205  mp->is_classify,
1207  mp->is_resolve_host,
1208  mp->is_resolve_attached, 0, 0,
1209  mp->is_l2_bridged,
1210  mp->is_source_lookup,
1211  mp->is_udp_encap,
1212  fib_index, &pfx, DPO_PROTO_IP6,
1213  &nh, ntohl (mp->next_hop_id),
1214  ntohl (mp->next_hop_sw_if_index),
1215  next_hop_fib_index,
1216  mp->next_hop_weight,
1217  mp->next_hop_preference,
1218  ntohl (mp->next_hop_via_label),
1219  label_stack));
1220 }
1221 
1222 void
1224 {
1225  vl_api_ip_add_del_route_reply_t *rmp;
1226  int rv;
1227  vnet_main_t *vnm = vnet_get_main ();
1228 
1229  vnm->api_errno = 0;
1230 
1231  if (mp->is_ipv6)
1232  rv = ip6_add_del_route_t_handler (mp);
1233  else
1234  rv = ip4_add_del_route_t_handler (mp);
1235 
1236  rv = (rv == 0) ? vnm->api_errno : rv;
1237 
1238  REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
1239 }
1240 
1241 void
1243  u32 table_id, u8 is_api, const u8 * name)
1244 {
1245  u32 fib_index, mfib_index;
1246 
1247  /*
1248  * ignore action on the default table - this is always present
1249  * and cannot be added nor deleted from the API
1250  */
1251  if (0 != table_id)
1252  {
1253  /*
1254  * The API holds only one lock on the table.
1255  * i.e. it can be added many times via the API but needs to be
1256  * deleted only once.
1257  * The FIB index for unicast and multicast is not necessarily the
1258  * same, since internal VPP systesm (like LISP and SR) create
1259  * their own unicast tables.
1260  */
1261  fib_index = fib_table_find (fproto, table_id);
1262  mfib_index = mfib_table_find (fproto, table_id);
1263 
1264  if (~0 == fib_index)
1265  {
1266  fib_table_find_or_create_and_lock_w_name (fproto, table_id,
1267  (is_api ?
1268  FIB_SOURCE_API :
1269  FIB_SOURCE_CLI), name);
1270  }
1271  if (~0 == mfib_index)
1272  {
1274  (is_api ?
1275  MFIB_SOURCE_API :
1276  MFIB_SOURCE_CLI), name);
1277  }
1278  }
1279 }
1280 
1281 static int
1283  u32 table_id,
1284  u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
1285 {
1286  vnet_main_t *vnm = vnet_get_main ();
1287 
1288  *fib_index = mfib_table_find (table_proto, ntohl (table_id));
1289  if (~0 == *fib_index)
1290  {
1291  /* No such table */
1292  return VNET_API_ERROR_NO_SUCH_FIB;
1293  }
1294 
1295  if (~0 != ntohl (next_hop_sw_if_index))
1296  {
1298  ntohl (next_hop_sw_if_index)))
1299  {
1300  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1301  }
1302  }
1303 
1304  return (0);
1305 }
1306 
1307 static int
1309  u8 is_local,
1310  u32 fib_index,
1311  const mfib_prefix_t * prefix,
1312  dpo_proto_t nh_proto,
1313  u32 entry_flags,
1314  fib_rpf_id_t rpf_id,
1315  u32 next_hop_sw_if_index, u32 itf_flags, u32 bier_imp)
1316 {
1317  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
1318 
1319  fib_route_path_t path = {
1320  .frp_sw_if_index = next_hop_sw_if_index,
1321  .frp_proto = nh_proto,
1322  };
1323 
1324  if (is_local)
1326 
1327  if (DPO_PROTO_BIER == nh_proto)
1328  {
1329  path.frp_bier_imp = bier_imp;
1331  }
1332  else if (!is_local && ~0 == next_hop_sw_if_index)
1333  {
1334  mfib_table_entry_update (fib_index, prefix,
1335  MFIB_SOURCE_API, rpf_id, entry_flags);
1336  goto done;
1337  }
1338 
1339  if (is_add)
1340  {
1341  mfib_table_entry_path_update (fib_index, prefix,
1342  MFIB_SOURCE_API, &path, itf_flags);
1343  }
1344  else
1345  {
1346  mfib_table_entry_path_remove (fib_index, prefix,
1347  MFIB_SOURCE_API, &path);
1348  }
1349 
1350 done:
1351  stats_dsunlock ();
1352  return (0);
1353 }
1354 
1355 static int
1357 {
1358  fib_protocol_t fproto;
1359  dpo_proto_t nh_proto;
1360  u32 fib_index;
1361  int rv;
1362 
1363  nh_proto = mp->next_hop_afi;
1364  fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
1365  rv = add_del_mroute_check (fproto,
1366  mp->table_id,
1368  mp->is_local, &fib_index);
1369 
1370  if (0 != rv)
1371  return (rv);
1372 
1373  mfib_prefix_t pfx = {
1374  .fp_len = ntohs (mp->grp_address_length),
1375  .fp_proto = fproto,
1376  };
1377 
1378  if (FIB_PROTOCOL_IP4 == fproto)
1379  {
1380  clib_memcpy (&pfx.fp_grp_addr.ip4, mp->grp_address,
1381  sizeof (pfx.fp_grp_addr.ip4));
1382  clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
1383  sizeof (pfx.fp_src_addr.ip4));
1384  }
1385  else
1386  {
1387  clib_memcpy (&pfx.fp_grp_addr.ip6, mp->grp_address,
1388  sizeof (pfx.fp_grp_addr.ip6));
1389  clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
1390  sizeof (pfx.fp_src_addr.ip6));
1391  }
1392 
1393  return (mroute_add_del_handler (mp->is_add,
1394  mp->is_local,
1395  fib_index, &pfx,
1396  nh_proto,
1397  ntohl (mp->entry_flags),
1398  ntohl (mp->rpf_id),
1399  ntohl (mp->next_hop_sw_if_index),
1400  ntohl (mp->itf_flags),
1401  ntohl (mp->bier_imp)));
1402 }
1403 
1404 void
1406 {
1407  vl_api_ip_mroute_add_del_reply_t *rmp;
1408  int rv;
1409  vnet_main_t *vnm = vnet_get_main ();
1410 
1411  vnm->api_errno = 0;
1412 
1413  rv = api_mroute_add_del_t_handler (mp);
1414 
1415  rv = (rv == 0) ? vnm->api_errno : rv;
1416 
1417  REPLY_MACRO (VL_API_IP_MROUTE_ADD_DEL_REPLY);
1418 }
1419 
1420 static void
1422  unix_shared_memory_queue_t * q, u32 sw_if_index,
1423  u8 is_ipv6, u32 context)
1424 {
1425  vl_api_ip_details_t *mp;
1426 
1427  mp = vl_msg_api_alloc (sizeof (*mp));
1428  memset (mp, 0, sizeof (*mp));
1429  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
1430 
1431  mp->sw_if_index = ntohl (sw_if_index);
1432  mp->is_ipv6 = is_ipv6;
1433  mp->context = context;
1434 
1435  vl_msg_api_send_shmem (q, (u8 *) & mp);
1436 }
1437 
1438 static void
1441  u8 * ip, u16 prefix_length,
1442  u32 sw_if_index, u8 is_ipv6, u32 context)
1443 {
1445 
1446  mp = vl_msg_api_alloc (sizeof (*mp));
1447  memset (mp, 0, sizeof (*mp));
1448  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
1449 
1450  if (is_ipv6)
1451  {
1452  clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
1453  }
1454  else
1455  {
1456  u32 *tp = (u32 *) mp->ip;
1457  *tp = *(u32 *) ip;
1458  }
1459  mp->prefix_length = prefix_length;
1460  mp->context = context;
1461  mp->sw_if_index = htonl (sw_if_index);
1462  mp->is_ipv6 = is_ipv6;
1463 
1464  vl_msg_api_send_shmem (q, (u8 *) & mp);
1465 }
1466 
1467 static void
1469 {
1472  ip6_address_t *r6;
1473  ip4_address_t *r4;
1474  ip6_main_t *im6 = &ip6_main;
1475  ip4_main_t *im4 = &ip4_main;
1476  ip_lookup_main_t *lm6 = &im6->lookup_main;
1477  ip_lookup_main_t *lm4 = &im4->lookup_main;
1478  ip_interface_address_t *ia = 0;
1479  u32 sw_if_index = ~0;
1480  int rv __attribute__ ((unused)) = 0;
1481 
1482  VALIDATE_SW_IF_INDEX (mp);
1483 
1484  sw_if_index = ntohl (mp->sw_if_index);
1485 
1487  if (q == 0)
1488  return;
1489 
1490  if (mp->is_ipv6)
1491  {
1492  /* *INDENT-OFF* */
1493  foreach_ip_interface_address (lm6, ia, sw_if_index,
1494  1 /* honor unnumbered */,
1495  ({
1496  r6 = ip_interface_address_get_address (lm6, ia);
1497  u16 prefix_length = ia->address_length;
1498  send_ip_address_details(am, q, (u8*)r6, prefix_length,
1499  sw_if_index, 1, mp->context);
1500  }));
1501  /* *INDENT-ON* */
1502  }
1503  else
1504  {
1505  /* *INDENT-OFF* */
1506  foreach_ip_interface_address (lm4, ia, sw_if_index,
1507  1 /* honor unnumbered */,
1508  ({
1509  r4 = ip_interface_address_get_address (lm4, ia);
1510  u16 prefix_length = ia->address_length;
1511  send_ip_address_details(am, q, (u8*)r4, prefix_length,
1512  sw_if_index, 0, mp->context);
1513  }));
1514  /* *INDENT-ON* */
1515  }
1517 }
1518 
1519 static void
1521 {
1523  vnet_main_t *vnm = vnet_get_main ();
1527  vnet_sw_interface_t *si, *sorted_sis;
1528  u32 sw_if_index = ~0;
1529 
1531  if (q == 0)
1532  {
1533  return;
1534  }
1535 
1536  /* Gather interfaces. */
1537  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
1538  _vec_len (sorted_sis) = 0;
1539  /* *INDENT-OFF* */
1540  pool_foreach (si, im->sw_interfaces,
1541  ({
1542  vec_add1 (sorted_sis, si[0]);
1543  }));
1544  /* *INDENT-ON* */
1545 
1546  vec_foreach (si, sorted_sis)
1547  {
1549  {
1550  if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
1551  {
1552  continue;
1553  }
1554  sw_if_index = si->sw_if_index;
1555  send_ip_details (am, q, sw_if_index, mp->is_ipv6, mp->context);
1556  }
1557  }
1558 }
1559 
1560 static void
1562 {
1563  vl_api_set_ip_flow_hash_reply_t *rmp;
1564  int rv;
1565  u32 table_id;
1566  flow_hash_config_t flow_hash_config = 0;
1567 
1568  table_id = ntohl (mp->vrf_id);
1569 
1570 #define _(a,b) if (mp->a) flow_hash_config |= b;
1572 #undef _
1573 
1574  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1575 
1576  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1577 }
1578 
1579 static void
1581 {
1582  vl_api_set_ip_flow_hash_reply_t *rmp;
1583  int rv;
1584  u32 table_id;
1585  flow_hash_config_t flow_hash_config = 0;
1586 
1587  table_id = ntohl (mp->vrf_id);
1588 
1589 #define _(a,b) if (mp->a) flow_hash_config |= b;
1591 #undef _
1592 
1593  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1594 
1595  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1596 }
1597 
1598 
1599 static void
1601 {
1602  if (mp->is_ipv6 == 0)
1603  set_ip4_flow_hash (mp);
1604  else
1605  set_ip6_flow_hash (mp);
1606 }
1607 
1608 static void
1611 {
1612  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1614  int rv = 0;
1615  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1616  default_router;
1617 
1618  is_no = mp->is_no == 1;
1619  suppress = mp->suppress == 1;
1620  managed = mp->managed == 1;
1621  other = mp->other == 1;
1622  ll_option = mp->ll_option == 1;
1623  send_unicast = mp->send_unicast == 1;
1624  cease = mp->cease == 1;
1625  default_router = mp->default_router == 1;
1626 
1627  VALIDATE_SW_IF_INDEX (mp);
1628 
1629  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1630  suppress, managed, other,
1631  ll_option, send_unicast, cease,
1632  default_router, ntohl (mp->lifetime),
1633  ntohl (mp->initial_count),
1634  ntohl (mp->initial_interval),
1635  ntohl (mp->max_interval),
1636  ntohl (mp->min_interval), is_no);
1637 
1639 
1640  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1641 }
1642 
1643 static void
1646 {
1648  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1649  int rv = 0;
1650  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1651 
1652  VALIDATE_SW_IF_INDEX (mp);
1653 
1654  is_no = mp->is_no == 1;
1655  use_default = mp->use_default == 1;
1656  no_advertise = mp->no_advertise == 1;
1657  off_link = mp->off_link == 1;
1658  no_autoconfig = mp->no_autoconfig == 1;
1659  no_onlink = mp->no_onlink == 1;
1660 
1661  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1662  (ip6_address_t *) mp->address,
1663  mp->address_length, use_default,
1664  ntohl (mp->val_lifetime),
1665  ntohl (mp->pref_lifetime), no_advertise,
1666  off_link, no_autoconfig, no_onlink, is_no);
1667 
1669  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1670 }
1671 
1672 static void
1674  u32 context,
1675  const ip46_address_t * addr, u32 sw_if_index)
1676 {
1678 
1679  mp = vl_msg_api_alloc (sizeof (*mp));
1680  memset (mp, 0, sizeof (*mp));
1681  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1682  mp->context = context;
1683  mp->sw_if_index = htonl (sw_if_index);
1684  memcpy (mp->address, addr, 16);
1685 
1686  vl_msg_api_send_shmem (q, (u8 *) & mp);
1687 }
1688 
1690 {
1693 
1694 static int
1696 {
1698 
1700  {
1701  vec_add1 (ctx->indices, fei);
1702  }
1703 
1704  return (1);
1705 }
1706 
1707 static void
1709 {
1710  ip6_main_t *im6 = &ip6_main;
1711  fib_table_t *fib_table;
1713  .indices = NULL,
1714  };
1715  fib_node_index_t *feip;
1716  fib_prefix_t pfx;
1718 
1720  if (q == 0)
1721  {
1722  return;
1723  }
1724 
1725  /* *INDENT-OFF* */
1726  pool_foreach (fib_table, im6->fibs,
1727  ({
1728  fib_table_walk(fib_table->ft_index,
1729  FIB_PROTOCOL_IP6,
1730  api_ip6nd_proxy_fib_table_walk,
1731  &ctx);
1732  }));
1733  /* *INDENT-ON* */
1734 
1736 
1737  vec_foreach (feip, ctx.indices)
1738  {
1739  fib_entry_get_prefix (*feip, &pfx);
1740 
1742  mp->context,
1743  &pfx.fp_addr,
1745  }
1746 
1747  vec_free (ctx.indices);
1748 }
1749 
1750 static void
1752 {
1753  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1754  int rv = 0;
1755 
1756  VALIDATE_SW_IF_INDEX (mp);
1757 
1758  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index),
1759  (ip6_address_t *) mp->address, mp->is_del);
1760 
1762  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1763 }
1764 
1765 static void
1768 {
1770  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1771  vnet_main_t *vnm = vnet_get_main ();
1772  int rv = 0;
1773  clib_error_t *error;
1774 
1775  vnm->api_errno = 0;
1776 
1777  VALIDATE_SW_IF_INDEX (mp);
1778 
1779  error =
1780  (mp->enable == 1) ? enable_ip6_interface (vm,
1781  ntohl (mp->sw_if_index)) :
1782  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1783 
1784  if (error)
1785  {
1786  clib_error_report (error);
1787  rv = VNET_API_ERROR_UNSPECIFIED;
1788  }
1789  else
1790  {
1791  rv = vnm->api_errno;
1792  }
1793 
1795 
1796  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1797 }
1798 
1799 static void
1802 {
1804  vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
1805  int rv = 0;
1806  clib_error_t *error;
1807  vnet_main_t *vnm = vnet_get_main ();
1808 
1809  vnm->api_errno = 0;
1810 
1811  VALIDATE_SW_IF_INDEX (mp);
1812 
1813  error = set_ip6_link_local_address (vm,
1814  ntohl (mp->sw_if_index),
1815  (ip6_address_t *) mp->address);
1816  if (error)
1817  {
1818  clib_error_report (error);
1819  rv = VNET_API_ERROR_UNSPECIFIED;
1820  }
1821  else
1822  {
1823  rv = vnm->api_errno;
1824  }
1825 
1827 
1828  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
1829 }
1830 
1831 void
1833  u32 context, const mfib_signal_t * mfs)
1834 {
1836  mfib_prefix_t prefix;
1837  mfib_table_t *mfib;
1838  mfib_itf_t *mfi;
1839 
1840  mp = vl_msg_api_alloc (sizeof (*mp));
1841 
1842  memset (mp, 0, sizeof (*mp));
1843  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1844  mp->context = context;
1845 
1846  mfi = mfib_itf_get (mfs->mfs_itf);
1847  mfib_entry_get_prefix (mfs->mfs_entry, &prefix);
1849  prefix.fp_proto);
1850  mp->table_id = ntohl (mfib->mft_table_id);
1851  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1852 
1853  if (FIB_PROTOCOL_IP4 == prefix.fp_proto)
1854  {
1855  mp->grp_address_len = ntohs (prefix.fp_len);
1856 
1857  memcpy (mp->grp_address, &prefix.fp_grp_addr.ip4, 4);
1858  if (prefix.fp_len > 32)
1859  {
1860  memcpy (mp->src_address, &prefix.fp_src_addr.ip4, 4);
1861  }
1862  }
1863  else
1864  {
1865  mp->grp_address_len = ntohs (prefix.fp_len);
1866 
1867  ASSERT (0);
1868  }
1869 
1870  if (0 != mfs->mfs_buffer_len)
1871  {
1872  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1873 
1874  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1875  }
1876  else
1877  {
1878  mp->ip_packet_len = 0;
1879  }
1880 
1881  vl_msg_api_send_shmem (q, (u8 *) & mp);
1882 }
1883 
1884 static void
1886 {
1888 
1890  if (q == 0)
1891  {
1892  return;
1893  }
1894 
1895  while (q->cursize < q->maxsize && mfib_signal_send_one (q, mp->context))
1896  ;
1897 }
1898 
1899 static void
1902 {
1903  vl_api_ip_container_proxy_add_del_reply_t *rmp;
1905  int rv = 0;
1906  clib_error_t *error;
1907 
1908  memset (&args, 0, sizeof (args));
1909  ip_set (&args.prefix.fp_addr, mp->ip, mp->is_ip4);
1910  args.prefix.fp_len = mp->plen ? mp->plen : (mp->is_ip4 ? 32 : 128);
1911  args.sw_if_index = clib_net_to_host_u32 (mp->sw_if_index);
1912  args.is_add = mp->is_add;
1913  if ((error = vnet_ip_container_proxy_add_del (&args)))
1914  {
1915  rv = clib_error_get_code (error);
1916  clib_error_report (error);
1917  }
1918 
1919  REPLY_MACRO (VL_API_IP_CONTAINER_PROXY_ADD_DEL_REPLY);
1920 }
1921 
1922 static void
1924 {
1925  int rv = 0;
1926  vl_api_ioam_enable_reply_t *rmp;
1927  clib_error_t *error;
1928 
1929  /* Ignoring the profile id as currently a single profile
1930  * is supported */
1931  error = ip6_ioam_enable (mp->trace_enable, mp->pot_enable,
1932  mp->seqno, mp->analyse);
1933  if (error)
1934  {
1935  clib_error_report (error);
1936  rv = clib_error_get_code (error);
1937  }
1938 
1939  REPLY_MACRO (VL_API_IOAM_ENABLE_REPLY);
1940 }
1941 
1942 static void
1944 {
1945  int rv = 0;
1946  vl_api_ioam_disable_reply_t *rmp;
1947  clib_error_t *error;
1948 
1949  error = clear_ioam_rewrite_fn ();
1950  if (error)
1951  {
1952  clib_error_report (error);
1953  rv = clib_error_get_code (error);
1954  }
1955 
1956  REPLY_MACRO (VL_API_IOAM_DISABLE_REPLY);
1957 }
1958 
1959 static void
1962 {
1963  vl_api_ip_source_and_port_range_check_add_del_reply_t *rmp;
1964  int rv = 0;
1965 
1966  u8 is_ipv6 = mp->is_ipv6;
1967  u8 is_add = mp->is_add;
1968  u8 mask_length = mp->mask_length;
1969  ip4_address_t ip4_addr;
1970  ip6_address_t ip6_addr;
1971  u16 *low_ports = 0;
1972  u16 *high_ports = 0;
1973  u32 vrf_id;
1974  u16 tmp_low, tmp_high;
1975  u8 num_ranges;
1976  int i;
1977 
1978  // Validate port range
1979  num_ranges = mp->number_of_ranges;
1980  if (num_ranges > 32)
1981  { // This is size of array in VPE.API
1982  rv = VNET_API_ERROR_EXCEEDED_NUMBER_OF_RANGES_CAPACITY;
1983  goto reply;
1984  }
1985 
1986  vec_reset_length (low_ports);
1987  vec_reset_length (high_ports);
1988 
1989  for (i = 0; i < num_ranges; i++)
1990  {
1991  tmp_low = mp->low_ports[i];
1992  tmp_high = mp->high_ports[i];
1993  // If tmp_low <= tmp_high then only need to check tmp_low = 0
1994  // If tmp_low <= tmp_high then only need to check tmp_high > 65535
1995  if (tmp_low > tmp_high || tmp_low == 0 || tmp_high > 65535)
1996  {
1997  rv = VNET_API_ERROR_INVALID_VALUE;
1998  goto reply;
1999  }
2000  vec_add1 (low_ports, tmp_low);
2001  vec_add1 (high_ports, tmp_high + 1);
2002  }
2003 
2004  // Validate mask_length
2005  if ((is_ipv6 && mask_length > 128) || (!is_ipv6 && mask_length > 32))
2006  {
2007  rv = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
2008  goto reply;
2009  }
2010 
2011  vrf_id = ntohl (mp->vrf_id);
2012 
2013  if (vrf_id < 1)
2014  {
2015  rv = VNET_API_ERROR_INVALID_VALUE;
2016  goto reply;
2017  }
2018 
2019 
2020  if (is_ipv6)
2021  {
2022  clib_memcpy (ip6_addr.as_u8, mp->address, sizeof (ip6_addr.as_u8));
2024  mask_length,
2025  vrf_id,
2026  low_ports,
2027  high_ports, is_add);
2028  }
2029  else
2030  {
2031  clib_memcpy (ip4_addr.data, mp->address, sizeof (ip4_addr));
2033  mask_length,
2034  vrf_id,
2035  low_ports,
2036  high_ports, is_add);
2037  }
2038 
2039 reply:
2040  vec_free (low_ports);
2041  vec_free (high_ports);
2042  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_ADD_DEL_REPLY);
2043 }
2044 
2045 static void
2048 {
2050  vl_api_ip_source_and_port_range_check_interface_add_del_reply_t *rmp;
2051  ip4_main_t *im = &ip4_main;
2052  int rv;
2053  u32 sw_if_index;
2056  uword *p = 0;
2057  int i;
2058 
2060  ntohl (mp->tcp_out_vrf_id);
2062  ntohl (mp->udp_out_vrf_id);
2064  ntohl (mp->tcp_in_vrf_id);
2066  ntohl (mp->udp_in_vrf_id);
2067 
2068 
2069  for (i = 0; i < IP_SOURCE_AND_PORT_RANGE_CHECK_N_PROTOCOLS; i++)
2070  {
2071  if (vrf_id[i] != 0 && vrf_id[i] != ~0)
2072  {
2073  p = hash_get (im->fib_index_by_table_id, vrf_id[i]);
2074 
2075  if (p == 0)
2076  {
2077  rv = VNET_API_ERROR_INVALID_VALUE;
2078  goto reply;
2079  }
2080 
2081  fib_index[i] = p[0];
2082  }
2083  else
2084  fib_index[i] = ~0;
2085  }
2086  sw_if_index = ntohl (mp->sw_if_index);
2087 
2088  VALIDATE_SW_IF_INDEX (mp);
2089 
2090  rv =
2091  set_ip_source_and_port_range_check (vm, fib_index, sw_if_index,
2092  mp->is_add);
2093 
2095 reply:
2096 
2097  REPLY_MACRO (VL_API_IP_SOURCE_AND_PORT_RANGE_CHECK_INTERFACE_ADD_DEL_REPLY);
2098 }
2099 
2100 #define IP4_ARP_EVENT 3
2101 #define IP6_ND_EVENT 4
2102 
2103 static int arp_change_delete_callback (u32 pool_index, u8 * notused);
2104 static int nd_change_delete_callback (u32 pool_index, u8 * notused);
2106 
2107 static void
2109 {
2110  vpe_api_main_t *vam = &vpe_api_main;
2111  vnet_main_t *vnm = vam->vnet_main;
2112  vlib_main_t *vm = vam->vlib_main;
2113  vl_api_ip4_arp_event_t *event;
2116 
2117  /* Client can cancel, die, etc. */
2118  if (pool_is_free_index (vam->arp_events, pool_index))
2119  return;
2120 
2121  event = pool_elt_at_index (vam->arp_events, pool_index);
2122 
2124  if (!q)
2125  {
2128  event->pid, &event->address,
2129  ip_resolver_process_node.index, IP4_ARP_EVENT,
2130  ~0 /* pool index, notused */ , 0 /* is_add */ );
2131  return;
2132  }
2133 
2134  if (q->cursize < q->maxsize)
2135  {
2136  mp = vl_msg_api_alloc (sizeof (*mp));
2137  clib_memcpy (mp, event, sizeof (*mp));
2138  vl_msg_api_send_shmem (q, (u8 *) & mp);
2139  }
2140  else
2141  {
2142  static f64 last_time;
2143  /*
2144  * Throttle syslog msgs.
2145  * It's pretty tempting to just revoke the registration...
2146  */
2147  if (vlib_time_now (vm) > last_time + 10.0)
2148  {
2149  clib_warning ("arp event for %U to pid %d: queue stuffed!",
2150  format_ip4_address, &event->address, event->pid);
2151  last_time = vlib_time_now (vm);
2152  }
2153  }
2154 }
2155 
2156 void
2158 {
2159  vpe_api_main_t *vam = &vpe_api_main;
2160  vnet_main_t *vnm = vam->vnet_main;
2161  vlib_main_t *vm = vam->vlib_main;
2162  vl_api_ip6_nd_event_t *event;
2165 
2166  /* Client can cancel, die, etc. */
2167  if (pool_is_free_index (vam->nd_events, pool_index))
2168  return;
2169 
2170  event = pool_elt_at_index (vam->nd_events, pool_index);
2171 
2173  if (!q)
2174  {
2177  event->pid, &event->address,
2178  ip_resolver_process_node.index, IP6_ND_EVENT,
2179  ~0 /* pool index, notused */ , 0 /* is_add */ );
2180  return;
2181  }
2182 
2183  if (q->cursize < q->maxsize)
2184  {
2185  mp = vl_msg_api_alloc (sizeof (*mp));
2186  clib_memcpy (mp, event, sizeof (*mp));
2187  vl_msg_api_send_shmem (q, (u8 *) & mp);
2188  }
2189  else
2190  {
2191  static f64 last_time;
2192  /*
2193  * Throttle syslog msgs.
2194  * It's pretty tempting to just revoke the registration...
2195  */
2196  if (vlib_time_now (vm) > last_time + 10.0)
2197  {
2198  clib_warning ("ip6 nd event for %U to pid %d: queue stuffed!",
2199  format_ip6_address, &event->address, event->pid);
2200  last_time = vlib_time_now (vm);
2201  }
2202  }
2203 }
2204 
2205 static uword
2208 {
2209  volatile f64 timeout = 100.0;
2210  volatile uword *event_data = 0;
2211 
2212  while (1)
2213  {
2215 
2216  uword event_type =
2217  vlib_process_get_events (vm, (uword **) & event_data);
2218 
2219  int i;
2220  switch (event_type)
2221  {
2222  case IP4_ARP_EVENT:
2223  for (i = 0; i < vec_len (event_data); i++)
2224  handle_ip4_arp_event (event_data[i]);
2225  break;
2226 
2227  case IP6_ND_EVENT:
2228  for (i = 0; i < vec_len (event_data); i++)
2229  handle_ip6_nd_event (event_data[i]);
2230  break;
2231 
2232  case ~0: /* timeout */
2233  break;
2234  }
2235 
2236  vec_reset_length (event_data);
2237  }
2238  return 0; /* or not */
2239 }
2240 
2241 /* *INDENT-OFF* */
2242 VLIB_REGISTER_NODE (ip_resolver_process_node,static) = {
2243  .function = resolver_process,
2244  .type = VLIB_NODE_TYPE_PROCESS,
2245  .name = "ip-route-resolver-process",
2246 };
2247 /* *INDENT-ON* */
2248 
2249 static int
2250 nd_change_data_callback (u32 pool_index, u8 * new_mac,
2251  u32 sw_if_index, ip6_address_t * address)
2252 {
2254  vl_api_ip6_nd_event_t *event;
2255 
2256  if (pool_is_free_index (am->nd_events, pool_index))
2257  return 1;
2258 
2259  event = pool_elt_at_index (am->nd_events, pool_index);
2260  if (eth_mac_equal (event->new_mac, new_mac) &&
2261  sw_if_index == ntohl (event->sw_if_index))
2262  {
2263  return 1;
2264  }
2265 
2266  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2267  event->sw_if_index = htonl (sw_if_index);
2268  return 0;
2269 }
2270 
2271 static int
2272 arp_change_delete_callback (u32 pool_index, u8 * notused)
2273 {
2275 
2276  if (pool_is_free_index (am->arp_events, pool_index))
2277  return 1;
2278 
2279  pool_put_index (am->arp_events, pool_index);
2280  return 0;
2281 }
2282 
2283 static int
2284 nd_change_delete_callback (u32 pool_index, u8 * notused)
2285 {
2287 
2288  if (pool_is_free_index (am->nd_events, pool_index))
2289  return 1;
2290 
2291  pool_put_index (am->nd_events, pool_index);
2292  return 0;
2293 }
2294 
2296 
2297 enum
2299 
2300 static uword
2302 {
2303  /* These cross the longjmp boundry (vlib_process_wait_for_event)
2304  * and need to be volatile - to prevent them from being optimized into
2305  * a register - which could change during suspension */
2306 
2307  volatile wc_arp_report_t arp_prev = { 0 };
2308  volatile wc_nd_report_t nd_prev = { 0 };
2309  volatile f64 last_arp = vlib_time_now (vm);
2310  volatile f64 last_nd = vlib_time_now (vm);
2311 
2312  while (1)
2313  {
2315  uword event_type = WC_ARP_REPORT;
2316  void *event_data = vlib_process_get_event_data (vm, &event_type);
2317 
2318  f64 now = vlib_time_now (vm);
2319  int i;
2320  if (event_type == WC_ARP_REPORT)
2321  {
2322  wc_arp_report_t *arp_events = event_data;
2323  for (i = 0; i < vec_len (arp_events); i++)
2324  {
2325  /* discard dup event */
2326  if (arp_prev.ip4 == arp_events[i].ip4 &&
2327  eth_mac_equal ((u8 *) arp_prev.mac, arp_events[i].mac) &&
2328  arp_prev.sw_if_index == arp_events[i].sw_if_index &&
2329  (now - last_arp) < 10.0)
2330  {
2331  continue;
2332  }
2333  arp_prev = arp_events[i];
2334  last_arp = now;
2336  /* *INDENT-OFF* */
2337  pool_foreach(reg, vpe_api_main.wc_ip4_arp_events_registrations,
2338  ({
2339  unix_shared_memory_queue_t *q;
2340  q = vl_api_client_index_to_input_queue (reg->client_index);
2341  if (q && q->cursize < q->maxsize)
2342  {
2343  vl_api_ip4_arp_event_t * event = vl_msg_api_alloc (sizeof *event);
2344  memset (event, 0, sizeof *event);
2345  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2346  event->client_index = reg->client_index;
2347  event->pid = reg->client_pid;
2348  event->mac_ip = 1;
2349  event->address = arp_events[i].ip4;
2350  event->sw_if_index = htonl(arp_events[i].sw_if_index);
2351  memcpy(event->new_mac, arp_events[i].mac, sizeof event->new_mac);
2352  vl_msg_api_send_shmem (q, (u8 *) &event);
2353  }
2354  }));
2355  /* *INDENT-ON* */
2356  }
2357  }
2358  else if (event_type == WC_ND_REPORT)
2359  {
2360  wc_nd_report_t *nd_events = event_data;
2361  for (i = 0; i < vec_len (nd_events); i++)
2362  {
2363  /* discard dup event */
2365  ((ip6_address_t *) & nd_prev.ip6, &nd_events[i].ip6)
2366  && eth_mac_equal ((u8 *) nd_prev.mac, nd_events[i].mac)
2367  && nd_prev.sw_if_index == nd_events[i].sw_if_index
2368  && (now - last_nd) < 10.0)
2369  {
2370  continue;
2371  }
2372  nd_prev = nd_events[i];
2373  last_nd = now;
2375  /* *INDENT-OFF* */
2376  pool_foreach(reg, vpe_api_main.wc_ip6_nd_events_registrations,
2377  ({
2378  unix_shared_memory_queue_t *q;
2379  q = vl_api_client_index_to_input_queue (reg->client_index);
2380  if (q && q->cursize < q->maxsize)
2381  {
2382  vl_api_ip6_nd_event_t * event = vl_msg_api_alloc (sizeof *event);
2383  memset (event, 0, sizeof *event);
2384  event->_vl_msg_id = htons (VL_API_IP6_ND_EVENT);
2385  event->client_index = reg->client_index;
2386  event->pid = reg->client_pid;
2387  event->mac_ip = 1;
2388  memcpy(event->address, nd_events[i].ip6.as_u8, sizeof event->address);
2389  event->sw_if_index = htonl(nd_events[i].sw_if_index);
2390  memcpy(event->new_mac, nd_events[i].mac, sizeof event->new_mac);
2391  vl_msg_api_send_shmem (q, (u8 *) &event);
2392  }
2393  }));
2394  /* *INDENT-ON* */
2395  }
2396  }
2397  vlib_process_put_event_data (vm, event_data);
2398  }
2399 
2400  return 0;
2401 }
2402 
2403 /* *INDENT-OFF* */
2405  .function = wc_arp_process,
2406  .type = VLIB_NODE_TYPE_PROCESS,
2407  .name = "wildcard-ip4-arp-publisher-process",
2408 };
2409 /* *INDENT-ON* */
2410 
2411 static int
2412 arp_change_data_callback (u32 pool_index, u8 * new_mac,
2413  u32 sw_if_index, u32 address)
2414 {
2416  vl_api_ip4_arp_event_t *event;
2417 
2418  if (pool_is_free_index (am->arp_events, pool_index))
2419  return 1;
2420 
2421  event = pool_elt_at_index (am->arp_events, pool_index);
2422  if (eth_mac_equal (event->new_mac, new_mac) &&
2423  sw_if_index == ntohl (event->sw_if_index))
2424  {
2425  return 1;
2426  }
2427 
2428  clib_memcpy (event->new_mac, new_mac, sizeof (event->new_mac));
2429  event->sw_if_index = htonl (sw_if_index);
2430  return 0;
2431 }
2432 
2433 static void
2435 {
2437  vnet_main_t *vnm = vnet_get_main ();
2438  vl_api_want_ip4_arp_events_reply_t *rmp;
2439  int rv = 0;
2440 
2441  if (mp->address == 0)
2442  {
2443  uword *p =
2444  hash_get (am->wc_ip4_arp_events_registration_hash, mp->client_index);
2446  if (p)
2447  {
2448  if (mp->enable_disable)
2449  {
2450  clib_warning ("pid %d: already enabled...", mp->pid);
2451  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2452  goto reply;
2453  }
2454  else
2455  {
2456  rp =
2457  pool_elt_at_index (am->wc_ip4_arp_events_registrations, p[0]);
2458  pool_put (am->wc_ip4_arp_events_registrations, rp);
2459  hash_unset (am->wc_ip4_arp_events_registration_hash,
2460  mp->client_index);
2461  if (pool_elts (am->wc_ip4_arp_events_registrations) == 0)
2463  goto reply;
2464  }
2465  }
2466  if (mp->enable_disable == 0)
2467  {
2468  clib_warning ("pid %d: already disabled...", mp->pid);
2469  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2470  goto reply;
2471  }
2472  pool_get (am->wc_ip4_arp_events_registrations, rp);
2473  rp->client_index = mp->client_index;
2474  rp->client_pid = mp->pid;
2475  hash_set (am->wc_ip4_arp_events_registration_hash, rp->client_index,
2476  rp - am->wc_ip4_arp_events_registrations);
2478  goto reply;
2479  }
2480 
2481  if (mp->enable_disable)
2482  {
2483  vl_api_ip4_arp_event_t *event;
2484  pool_get (am->arp_events, event);
2487  mp->pid, &mp->address /* addr, in net byte order */ ,
2489  IP4_ARP_EVENT, event - am->arp_events, 1 /* is_add */ );
2490 
2491  if (rv)
2492  {
2493  pool_put (am->arp_events, event);
2494  goto reply;
2495  }
2496  memset (event, 0, sizeof (*event));
2497 
2498  /* Python API expects events to have no context */
2499  event->_vl_msg_id = htons (VL_API_IP4_ARP_EVENT);
2500  event->client_index = mp->client_index;
2501  event->address = mp->address;
2502  event->pid = mp->pid;
2503  if (mp->address == 0)
2504  event->mac_ip = 1;
2505  }
2506  else
2507  {
2510  mp->pid, &mp->address /* addr, in net byte order */ ,
2512  IP4_ARP_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2513  }
2514 reply:
2515  REPLY_MACRO (VL_API_WANT_IP4_ARP_EVENTS_REPLY);
2516 }
2517 
2518 static void
2520 {
2522  vnet_main_t *vnm = vnet_get_main ();
2523  vl_api_want_ip6_nd_events_reply_t *rmp;
2524  int rv = 0;
2525 
2527  {
2528  uword *p =
2529  hash_get (am->wc_ip6_nd_events_registration_hash, mp->client_index);
2531  if (p)
2532  {
2533  if (mp->enable_disable)
2534  {
2535  clib_warning ("pid %d: already enabled...", mp->pid);
2536  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2537  goto reply;
2538  }
2539  else
2540  {
2541  rp =
2542  pool_elt_at_index (am->wc_ip6_nd_events_registrations, p[0]);
2543  pool_put (am->wc_ip6_nd_events_registrations, rp);
2544  hash_unset (am->wc_ip6_nd_events_registration_hash,
2545  mp->client_index);
2546  if (pool_elts (am->wc_ip6_nd_events_registrations) == 0)
2547  wc_nd_set_publisher_node (~0, 2);
2548  goto reply;
2549  }
2550  }
2551  if (mp->enable_disable == 0)
2552  {
2553  clib_warning ("pid %d: already disabled...", mp->pid);
2554  rv = VNET_API_ERROR_INVALID_REGISTRATION;
2555  goto reply;
2556  }
2557  pool_get (am->wc_ip6_nd_events_registrations, rp);
2558  rp->client_index = mp->client_index;
2559  rp->client_pid = mp->pid;
2560  hash_set (am->wc_ip6_nd_events_registration_hash, rp->client_index,
2561  rp - am->wc_ip6_nd_events_registrations);
2563  goto reply;
2564  }
2565 
2566  if (mp->enable_disable)
2567  {
2568  vl_api_ip6_nd_event_t *event;
2569  pool_get (am->nd_events, event);
2570 
2573  mp->pid, mp->address /* addr, in net byte order */ ,
2575  IP6_ND_EVENT, event - am->nd_events, 1 /* is_add */ );
2576 
2577  if (rv)
2578  {
2579  pool_put (am->nd_events, event);
2580  goto reply;
2581  }
2582  memset (event, 0, sizeof (*event));
2583 
2584  event->_vl_msg_id = ntohs (VL_API_IP6_ND_EVENT);
2585  event->client_index = mp->client_index;
2586  clib_memcpy (event->address, mp->address, sizeof event->address);
2587  event->pid = mp->pid;
2588  }
2589  else
2590  {
2593  mp->pid, mp->address /* addr, in net byte order */ ,
2595  IP6_ND_EVENT, ~0 /* pool index */ , 0 /* is_add */ );
2596  }
2597 reply:
2598  REPLY_MACRO (VL_API_WANT_IP6_ND_EVENTS_REPLY);
2599 }
2600 
2601 static void
2603 {
2604  vl_api_proxy_arp_add_del_reply_t *rmp;
2605  u32 fib_index;
2606  int rv;
2607  ip4_main_t *im = &ip4_main;
2608  int vnet_proxy_arp_add_del (ip4_address_t * lo_addr,
2609  ip4_address_t * hi_addr,
2610  u32 fib_index, int is_del);
2611  uword *p;
2612 
2613  stats_dslock_with_hint (1 /* release hint */ , 6 /* tag */ );
2614 
2615  p = hash_get (im->fib_index_by_table_id, ntohl (mp->vrf_id));
2616 
2617  if (!p)
2618  {
2619  rv = VNET_API_ERROR_NO_SUCH_FIB;
2620  goto out;
2621  }
2622 
2623  fib_index = p[0];
2624 
2626  (ip4_address_t *) mp->hi_address,
2627  fib_index, mp->is_add == 0);
2628 
2629 out:
2630  stats_dsunlock ();
2631  REPLY_MACRO (VL_API_PROXY_ARP_ADD_DEL_REPLY);
2632 }
2633 
2634 static void
2637 {
2638  int rv = 0;
2639  vnet_main_t *vnm = vnet_get_main ();
2640  vl_api_proxy_arp_intfc_enable_disable_reply_t *rmp;
2641 
2642  VALIDATE_SW_IF_INDEX (mp);
2643 
2644  vnet_sw_interface_t *si =
2645  vnet_get_sw_interface (vnm, ntohl (mp->sw_if_index));
2646 
2647  ASSERT (si);
2648 
2649  if (mp->enable_disable)
2651  else
2653 
2655 
2656  REPLY_MACRO (VL_API_PROXY_ARP_INTFC_ENABLE_DISABLE_REPLY);
2657 }
2658 
2659 static int
2661 {
2662  vnet_main_t *vnm = vnet_get_main ();
2664  ip4_main_t *im4 = &ip4_main;
2665  static u32 *sw_if_indices_to_shut;
2666  fib_table_t *fib_table;
2667  ip4_fib_t *fib;
2668  u32 sw_if_index;
2669  int i;
2670  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2671  u32 target_fib_id = ntohl (mp->vrf_id);
2672 
2673  stats_dslock_with_hint (1 /* release hint */ , 8 /* tag */ );
2674 
2675  /* *INDENT-OFF* */
2676  pool_foreach (fib_table, im4->fibs,
2677  ({
2678  vnet_sw_interface_t * si;
2679 
2680  fib = pool_elt_at_index (im4->v4_fibs, fib_table->ft_index);
2681 
2682  if (fib->table_id != target_fib_id)
2683  continue;
2684 
2685  /* remove any mpls encap/decap labels */
2686  mpls_fib_reset_labels (fib->table_id);
2687 
2688  /* remove any proxy arps in this fib */
2689  vnet_proxy_arp_fib_reset (fib->table_id);
2690 
2691  /* Set the flow hash for this fib to the default */
2692  vnet_set_ip4_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2693 
2694  vec_reset_length (sw_if_indices_to_shut);
2695 
2696  /* Shut down interfaces in this FIB / clean out intfc routes */
2697  pool_foreach (si, im->sw_interfaces,
2698  ({
2699  u32 sw_if_index = si->sw_if_index;
2700 
2701  if (sw_if_index < vec_len (im4->fib_index_by_sw_if_index)
2702  && (im4->fib_index_by_sw_if_index[si->sw_if_index] ==
2703  fib->index))
2704  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2705  }));
2706 
2707  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2708  sw_if_index = sw_if_indices_to_shut[i];
2709 
2710  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2711  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2712  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2713  }
2714 
2716 
2717  rv = 0;
2718  break;
2719  })); /* pool_foreach (fib) */
2720  /* *INDENT-ON* */
2721 
2722  stats_dsunlock ();
2723  return rv;
2724 }
2725 
2726 static int
2728 {
2729  vnet_main_t *vnm = vnet_get_main ();
2731  ip6_main_t *im6 = &ip6_main;
2732  static u32 *sw_if_indices_to_shut;
2733  fib_table_t *fib_table;
2734  ip6_fib_t *fib;
2735  u32 sw_if_index;
2736  int i;
2737  int rv = VNET_API_ERROR_NO_SUCH_FIB;
2738  u32 target_fib_id = ntohl (mp->vrf_id);
2739 
2740  stats_dslock_with_hint (1 /* release hint */ , 9 /* tag */ );
2741 
2742  /* *INDENT-OFF* */
2743  pool_foreach (fib_table, im6->fibs,
2744  ({
2745  vnet_sw_interface_t * si;
2746 
2747  fib = pool_elt_at_index (im6->v6_fibs, fib_table->ft_index);
2748 
2749  if (fib->table_id != target_fib_id)
2750  continue;
2751 
2752  vec_reset_length (sw_if_indices_to_shut);
2753 
2754  /* Set the flow hash for this fib to the default */
2755  vnet_set_ip6_flow_hash (fib->table_id, IP_FLOW_HASH_DEFAULT);
2756 
2757  /* Shut down interfaces in this FIB / clean out intfc routes */
2758  pool_foreach (si, im->sw_interfaces,
2759  ({
2760  if (im6->fib_index_by_sw_if_index[si->sw_if_index] ==
2761  fib->index)
2762  vec_add1 (sw_if_indices_to_shut, si->sw_if_index);
2763  }));
2764 
2765  for (i = 0; i < vec_len (sw_if_indices_to_shut); i++) {
2766  sw_if_index = sw_if_indices_to_shut[i];
2767 
2768  u32 flags = vnet_sw_interface_get_flags (vnm, sw_if_index);
2769  flags &= ~(VNET_SW_INTERFACE_FLAG_ADMIN_UP);
2770  vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
2771  }
2772 
2774 
2775  rv = 0;
2776  break;
2777  })); /* pool_foreach (fib) */
2778  /* *INDENT-ON* */
2779 
2780  stats_dsunlock ();
2781  return rv;
2782 }
2783 
2784 static void
2786 {
2787  int rv;
2788  vl_api_reset_fib_reply_t *rmp;
2789 
2790  if (mp->is_ipv6)
2791  rv = ip6_reset_fib_t_handler (mp);
2792  else
2793  rv = ip4_reset_fib_t_handler (mp);
2794 
2795  REPLY_MACRO (VL_API_RESET_FIB_REPLY);
2796 }
2797 
2798 static void
2800 {
2801  int rv;
2802  vl_api_set_arp_neighbor_limit_reply_t *rmp;
2803  vnet_main_t *vnm = vnet_get_main ();
2804  clib_error_t *error;
2805 
2806  vnm->api_errno = 0;
2807 
2808  if (mp->is_ipv6)
2809  error = ip6_set_neighbor_limit (ntohl (mp->arp_neighbor_limit));
2810  else
2811  error = ip4_set_arp_limit (ntohl (mp->arp_neighbor_limit));
2812 
2813  if (error)
2814  {
2815  clib_error_report (error);
2816  rv = VNET_API_ERROR_UNSPECIFIED;
2817  }
2818  else
2819  {
2820  rv = vnm->api_errno;
2821  }
2822 
2823  REPLY_MACRO (VL_API_SET_ARP_NEIGHBOR_LIMIT_REPLY);
2824 }
2825 
2826 #define vl_msg_name_crc_list
2827 #include <vnet/ip/ip.api.h>
2828 #undef vl_msg_name_crc_list
2829 
2830 static void
2832 {
2833 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
2834  foreach_vl_msg_name_crc_ip;
2835 #undef _
2836 }
2837 
2838 static clib_error_t *
2840 {
2841  api_main_t *am = &api_main;
2842 
2843 #define _(N,n) \
2844  vl_msg_api_set_handlers(VL_API_##N, #n, \
2845  vl_api_##n##_t_handler, \
2846  vl_noop_handler, \
2847  vl_api_##n##_t_endian, \
2848  vl_api_##n##_t_print, \
2849  sizeof(vl_api_##n##_t), 1);
2851 #undef _
2852 
2853  /*
2854  * Set up the (msg_name, crc, message-id) table
2855  */
2857 
2858  return 0;
2859 }
2860 
2862 
2863 /*
2864  * fd.io coding-style-patch-verification: ON
2865  *
2866  * Local Variables:
2867  * eval: (c-set-style "gnu")
2868  * End:
2869  */
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:432
#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:181
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:583
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1556
static void vl_api_proxy_arp_intfc_enable_disable_t_handler(vl_api_proxy_arp_intfc_enable_disable_t *mp)
Definition: ip_api.c:2636
Proxy ARP add / del request.
Definition: ip.api:730
u32 mfib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, mfib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: mfib_table.c:467
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:393
void ip4_punt_redirect_add(u32 rx_sw_if_index, u32 tx_sw_if_index, ip46_address_t *nh)
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
#define hash_set(h, key, value)
Definition: hash.h:254
Register for ip6 nd resolution events.
Definition: ip.api:695
static void vl_api_ip6nd_proxy_add_del_t_handler(vl_api_ip6nd_proxy_add_del_t *mp)
Definition: ip_api.c:1751
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:337
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
#define clib_min(x, y)
Definition: clib.h:340
vnet_main_t * vnet_main
static int vl_api_ip_fib_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:277
Reset fib table request.
Definition: ip.api:761
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:486
static void vl_api_ip_container_proxy_add_del_t_handler(vl_api_ip_container_proxy_add_del_t *mp)
Definition: ip_api.c:1901
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:404
int vnet_set_ip4_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip4_forward.c:2916
u8 next_hop[16]
Definition: ip.api:79
static uword resolver_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:2206
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:133
IP punt redirect.
Definition: ip.api:586
#define hash_unset(h, key)
Definition: hash.h:260
Dump IP fib table.
Definition: ip.api:49
a
Definition: bitmap.h:516
vl_api_fib_path_t path[count]
Definition: ip.api:479
vl_api_fib_path_t path[count]
Definition: ip.api:97
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:377
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:733
static void send_ip6_mfib_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, u32 table_id, mfib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:571
vnet_main_t * vnet_get_main(void)
Definition: misc.c:47
static void send_ip6_fib_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, const fib_table_t *table, const fib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:332
vnet_interface_main_t interface_main
Definition: vnet.h:56
IP FIB table response.
Definition: ip.api:89
The table that stores ALL routes learned by the DP.
Definition: ip6.h:132
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:1546
Dump IP multicast fib table.
Definition: ip.api:455
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:1096
void ip_set(ip46_address_t *dst, void *src, u8 is_ip4)
Definition: ip.c:76
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:706
#define NULL
Definition: clib.h:55
iOAM disable
Definition: ip.api:807
An entry in a FIB table.
Definition: mfib_entry.h:31
Set max allowed ARP or ip6 neighbor entries request.
Definition: ip.api:775
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:224
static int arp_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, u32 address)
Definition: ip_api.c:2412
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:539
A path that resolves via a BIER impostion object.
Definition: fib_types.h:342
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)
#define IP6_ND_EVENT
Definition: ip_api.c:2101
clib_error_t * ip4_set_arp_limit(u32 arp_limit)
Definition: arp.c:1449
index_t frp_bier_imp
A path via a BIER imposition object.
Definition: fib_types.h:444
ip6_neighbor_t * ip6_neighbors_entries(u32 sw_if_index)
Definition: ip6_neighbor.c:877
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
static int arp_change_delete_callback(u32 pool_index, u8 *notused)
Definition: ip_api.c:2272
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:518
#define IP_NULL_DPO_ACTION_NUM
Definition: ip_null_dpo.h:48
struct _vlib_node_registration vlib_node_registration_t
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:786
ip_lookup_main_t lookup_main
Definition: ip4.h:97
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:382
IPv6 router advertisement config request.
Definition: ip.api:227
static void send_ip6nd_proxy_details(unix_shared_memory_queue_t *q, u32 context, const ip46_address_t *addr, u32 sw_if_index)
Definition: ip_api.c:1673
Definition: fib_entry.h:246
struct api_ip6nd_proxy_fib_table_walk_ctx_t_ api_ip6nd_proxy_fib_table_walk_ctx_t
A path that result in received traffic being recieved/recirculated so that it appears to have arrived...
Definition: fib_types.h:318
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:225
static void vl_api_ip6nd_proxy_dump_t_handler(vl_api_ip6nd_proxy_dump_t *mp)
Definition: ip_api.c:1708
static void api_ip6_fib_table_put_entries(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip_api.c:406
Dump IP6 fib table.
Definition: ip.api:103
#define IP4_ARP_EVENT
Definition: ip_api.c:2100
int mfib_signal_send_one(struct _unix_shared_memory_queue *q, u32 context)
Definition: mfib_signal.c:94
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:532
static int nd_change_data_callback(u32 pool_index, u8 *new_mac, u32 sw_if_index, ip6_address_t *address)
Definition: ip_api.c:2250
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:322
ip6_neighbor_flags_t flags
Definition: ip6_neighbor.h:42
static void handle_ip4_arp_event(u32 pool_index)
Definition: ip_api.c:2108
format_function_t format_ip4_address
Definition: format.h:79
Proxy ARP add / del request.
Definition: ip.api:746
#define VNET_SW_INTERFACE_FLAG_PROXY_ARP
Definition: interface.h:581
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:438
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:412
Add / del table request A table can be added multiple times, but need be deleted only once...
Definition: ip.api:36
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:1282
Dump IP6 multicast fib table.
Definition: ip.api:485
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:390
clib_error_t * vnet_ip_container_proxy_add_del(vnet_ip_container_proxy_args_t *args)
Definition: lookup.c:1304
vl_api_fib_path_t path[count]
Definition: ip.api:507
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
static uword ip6_address_is_equal(ip6_address_t *a, ip6_address_t *b)
Definition: ip6_packet.h:208
Recursion constraint of via a host prefix.
Definition: fib_types.h:293
static void vl_api_ip6_mfib_dump_t_handler(vl_api_ip6_mfib_dump_t *mp)
Definition: ip_api.c:628
Set interface source and L4 port-range request.
Definition: ip.api:642
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:656
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:1278
Aggregrate type for a prefix.
Definition: fib_types.h:172
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:1520
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:1161
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:339
A path via a UDP encap object.
Definition: fib_types.h:330
enum fib_route_path_flags_t_ fib_route_path_flags_t
Path flags from the control plane.
static void send_ip_address_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, u8 *ip, u16 prefix_length, u32 sw_if_index, u8 is_ipv6, u32 context)
Definition: ip_api.c:1439
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:1028
fib_protocol_t dpo_proto_to_fib(dpo_proto_t dpo_proto)
Definition: fib_types.c:227
static void send_ip_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, u32 sw_if_index, u8 is_ipv6, u32 context)
Definition: ip_api.c:1421
u16 fp_len
The mask length.
Definition: fib_types.h:176
static void vl_api_set_arp_neighbor_limit_t_handler(vl_api_set_arp_neighbor_limit_t *mp)
Definition: ip_api.c:2799
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1885
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1498
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:1461
void * vl_msg_api_alloc(int nbytes)
u32 mfib_entry_get_fib_index(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1220
Definition: fib_entry.h:238
Configure IP source and L4 port-range check.
Definition: ip.api:621
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:166
#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:618
Definition: fib_entry.h:242
static void vl_api_want_ip6_nd_events_t_handler(vl_api_want_ip6_nd_events_t *mp)
Definition: ip_api.c:2519
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:459
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:53
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:195
index_t classify_dpo_create(dpo_proto_t proto, u32 classify_table_index)
Definition: classify_dpo.c:43
dpo_type_t dpoi_type
the type
Definition: dpo.h:170
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:793
void vl_api_ip_table_add_del_t_handler(vl_api_ip_table_add_del_t *mp)
Definition: ip_api.c:821
static void vl_api_proxy_arp_add_del_t_handler(vl_api_proxy_arp_add_del_t *mp)
Definition: ip_api.c:2602
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:1645
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:271
static int nd_change_delete_callback(u32 pool_index, u8 *notused)
Definition: ip_api.c:2284
IP6 Multicast FIB table response.
Definition: ip.api:499
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpath)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:583
vl_api_fib_path_t path[count]
Definition: ip.api:124
#define REPLY_MACRO(t)
static int api_ip6nd_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:1695
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:297
u32 index
Definition: ip6.h:73
fib_node_index_t * entries
Definition: ip_api.c:402
Tell client about an ip4 arp resolution event.
Definition: ip.api:678
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:1180
static void vl_api_sw_interface_ip6_enable_disable_t_handler(vl_api_sw_interface_ip6_enable_disable_t *mp)
Definition: ip_api.c:1767
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1600
IOAM enable : Enable in-band OAM.
Definition: ip.api:790
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:198
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1352
#define ip46_address_is_ip4(ip46)
Definition: ip6_packet.h:76
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:259
The IPv4 FIB.
Definition: ip4_fib.h:39
#define BAD_SW_IF_INDEX_LABEL
static void send_ip_mfib_details(unix_shared_memory_queue_t *q, u32 context, u32 table_id, fib_node_index_t mfei)
Definition: ip_api.c:469
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:55
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
Definition: fib_entry_src.c:99
api_main_t api_main
Definition: api_shared.c:35
Set the ip flow hash config for a fib request.
Definition: ip.api:196
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:329
void handle_ip6_nd_event(u32 pool_index)
Definition: ip_api.c:2157
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:50
format_function_t format_ip6_address
Definition: format.h:95
vlib_main_t * vm
Definition: buffer.c:283
static void vl_api_ip_punt_redirect_t_handler(vl_api_ip_punt_redirect_t *mp, vlib_main_t *vm)
Definition: ip_api.c:690
#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 copy_fib_next_hop(fib_route_path_encode_t *api_rpath, void *fp_arg)
Definition: ip_api.c:178
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:836
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:75
#define clib_warning(format, args...)
Definition: error.h:59
fib_node_index_t * entries
Definition: ip_api.c:614
static vlib_node_registration_t wc_arp_process_node
(constructor) VLIB_REGISTER_NODE (wc_arp_process_node)
Definition: ip_api.c:2295
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:1961
#define clib_memcpy(a, b, c)
Definition: string.h:75
unix_shared_memory_queue_t * vl_api_client_index_to_input_queue(u32 index)
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)
static void send_ip_neighbor_details(u32 sw_if_index, u8 is_ipv6, u8 is_static, u8 *mac_address, u8 *ip_address, unix_shared_memory_queue_t *q, u32 context)
Definition: ip_api.c:106
void wc_arp_set_publisher_node(uword node_index, uword event_type)
Definition: arp.c:1560
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:29
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:1561
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:268
void ip4_punt_policer_add_del(u8 is_add, u32 policer_index)
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:182
u32 sw_if_index
Definition: ip.api:70
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:1950
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 vl_api_ioam_disable_t_handler(vl_api_ioam_disable_t *mp)
Definition: ip_api.c:1943
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:356
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:73
#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:2785
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:2660
void vl_api_ip_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:1405
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:576
void vl_msg_api_send_shmem(unix_shared_memory_queue_t *q, u8 *elem)
IP neighbor add / del request.
Definition: ip.api:170
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:294
#define ASSERT(truth)
static uword ip6_address_is_zero(ip6_address_t *a)
Definition: ip6_packet.h:266
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:1356
IP Multicast FIB table response.
Definition: ip.api:469
ip6_address_t ip6_address
Definition: ip6_neighbor.h:26
ip6_main_t ip6_main
Definition: ip6_forward.c:3009
ip_lookup_main_t lookup_main
Definition: ip6.h:158
long ctx[MAX_CONNS]
Definition: main.c:122
index_t mfs_itf
Definition: mfib_signal.h:32
fib_node_index_t * entries
Definition: ip_api.c:518
static int vl_api_ip_mfib_table_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:522
static int ip4_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:1098
FIB path.
Definition: ip.api:68
u8 frp_preference
A path preference.
Definition: fib_types.h:465
IPv6 router advertisement prefix config request.
Definition: ip.api:276
IPv6 ND proxy details returned after request.
Definition: ip.api:313
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:1580
An interface associated with a particular MFIB entry.
Definition: mfib_itf.h:25
IPv6 ND proxy dump request.
Definition: ip.api:327
static uword wc_arp_process(vlib_main_t *vm, vlib_node_runtime_t *rt, vlib_frame_t *f)
Definition: ip_api.c:2301
A deag path using the packet&#39;s source not destination address.
Definition: fib_types.h:326
u32 fib_table_find_or_create_and_lock(fib_protocol_t proto, u32 table_id, fib_source_t src)
Get the index of the FIB for a Table-ID.
Definition: fib_table.c:1087
static void vl_api_ioam_enable_t_handler(vl_api_ioam_enable_t *mp)
Definition: ip_api.c:1923
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:469
struct mfib_table_t_ * mfibs
Vector of MFIBs.
Definition: ip6.h:167
#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:1017
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_l2_bridged, 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, mpls_label_t *next_hop_out_label_stack)
Definition: ip_api.c:841
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:211
u32 mft_table_id
Table ID (hash key) for this FIB.
Definition: mfib_table.h:61
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:346
static clib_error_t * ip_api_hookup(vlib_main_t *vm)
Definition: ip_api.c:2839
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:287
static vlib_node_registration_t ip_resolver_process_node
(constructor) VLIB_REGISTER_NODE (ip_resolver_process_node)
Definition: ip_api.c:2105
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:3171
ip6_fib_table_instance_t ip6_table[IP6_FIB_NUM_TABLES]
The two FIB tables; fwding and non-fwding.
Definition: ip6.h:156
IP neighboors dump response.
Definition: ip.api:147
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:1533
u64 uword
Definition: types.h:112
static void send_ip_fib_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, const fib_table_t *table, const fib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:204
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:400
Add / del route request.
Definition: ip.api:392
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:2831
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
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:182
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:675
ip6_neighbor_key_t key
Definition: ip6_neighbor.h:40
A for-us/local path.
Definition: fib_types.h:301
#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:2434
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:300
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:956
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:663
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:193
#define clib_error_get_code(err)
Definition: error.h:77
u32 next_hop_out_label_stack[next_hop_n_out_labels]
Definition: ip.api:422
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 void vl_api_sw_interface_ip6nd_ra_config_t_handler(vl_api_sw_interface_ip6nd_ra_config_t *mp)
Definition: ip_api.c:1610
Tell client about an ip6 nd resolution or mac/ip event.
Definition: ip.api:712
u32 client_index
Definition: ip.api:537
u32 mfi_sw_if_index
The SW IF index that this MFIB interface represents.
Definition: mfib_itf.h:35
#define VLIB_REGISTER_NODE(x,...)
Definition: node.h:143
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:1181
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:525
IP6 FIB table entry response.
Definition: ip.api:116
Register for ip4 arp resolution events.
Definition: ip.api:661
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:100
IP punt policer.
Definition: ip.api:568
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:228
#define vec_foreach(var, vec)
Vector iterator.
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:1308
fib_route_path_t rpath
Definition: fib_types.h:487
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:1242
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:1801
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:546
static void vl_api_ip_address_dump_t_handler(vl_api_ip_address_dump_t *mp)
Definition: ip_api.c:1468
ethernet_arp_ip4_entry_t * ip4_neighbor_entries(u32 sw_if_index)
Definition: arp.c:1302
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:1931
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:172
static void api_ip6_fib_table_get_all(unix_shared_memory_queue_t *q, vl_api_ip6_fib_dump_t *mp, fib_table_t *fib_table)
Definition: ip_api.c:417
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 vl_mfib_signal_send_one(unix_shared_memory_queue_t *q, u32 context, const mfib_signal_t *mfs)
Definition: ip_api.c:1832
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:433
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:459
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:449
void vl_api_ip_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:1223
#define ip46_address_is_zero(ip46)
Definition: ip6_packet.h:81
struct fib_table_t_ * fibs
Definition: ip6.h:161
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:423
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:717
Definition: dpo.h:96
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:2047
#define foreach_ip_api_msg
Definition: ip_api.c:65
const ip46_address_t zero_addr
Definition: lookup.c:359
ip46_address_t fp_grp_addr
The address type is not deriveable from the fp_addr member.
Definition: mfib_types.h:46
u8 is_prohibit
Definition: ip.api:77
static void vl_api_ip6_fib_dump_t_handler(vl_api_ip6_fib_dump_t *mp)
Definition: ip_api.c:450
#define VALIDATE_SW_IF_INDEX(mp)
A protocol Independent FIB table.
Definition: fib_table.h:35
Definition: arp_packet.h:150
fib_node_index_t * feis
Definition: ip_api.c:273
IPv6 Proxy ND.
Definition: fib_entry.h:94
struct _unix_shared_memory_queue unix_shared_memory_queue_t
static int ip6_reset_fib_t_handler(vl_api_reset_fib_t *mp)
Definition: ip_api.c:2727
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:129
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