FD.io VPP  v17.10-9-gd594711
Vector Packet Processing
ip_api.c
Go to the documentation of this file.
1 /*
2  *------------------------------------------------------------------
3  * ip_api.c - vnet ip api
4  *
5  * Copyright (c) 2016 Cisco and/or its affiliates.
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at:
9  *
10  * http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  *------------------------------------------------------------------
18  */
19 
20 #include <vnet/vnet.h>
21 #include <vlibmemory/api.h>
22 
23 #include <vnet/interface.h>
24 #include <vnet/api_errno.h>
25 #include <vnet/ethernet/ethernet.h>
26 #include <vnet/ip/ip.h>
27 #include <vnet/ip/ip6_neighbor.h>
28 #include <vnet/fib/fib_table.h>
29 #include <vnet/fib/fib_api.h>
30 #include <vnet/dpo/drop_dpo.h>
31 #include <vnet/dpo/receive_dpo.h>
32 #include <vnet/dpo/lookup_dpo.h>
33 #include <vnet/dpo/classify_dpo.h>
34 #include <vnet/dpo/ip_null_dpo.h>
36 #include <vnet/mfib/ip6_mfib.h>
37 #include <vnet/mfib/ip4_mfib.h>
38 #include <vnet/mfib/mfib_signal.h>
39 #include <vnet/mfib/mfib_entry.h>
40 
41 #include <vnet/vnet_msg_enum.h>
42 
43 #define vl_typedefs /* define message structures */
44 #include <vnet/vnet_all_api_h.h>
45 #undef vl_typedefs
46 
47 #define vl_endianfun /* define message structures */
48 #include <vnet/vnet_all_api_h.h>
49 #undef vl_endianfun
50 
51 /* instantiate all the print functions we know about */
52 #define vl_print(handle, ...) vlib_cli_output (handle, __VA_ARGS__)
53 #define vl_printfun
54 #include <vnet/vnet_all_api_h.h>
55 #undef vl_printfun
56 
58 
59 
60 #define foreach_ip_api_msg \
61 _(IP_FIB_DUMP, ip_fib_dump) \
62 _(IP6_FIB_DUMP, ip6_fib_dump) \
63 _(IP_MFIB_DUMP, ip_mfib_dump) \
64 _(IP6_MFIB_DUMP, ip6_mfib_dump) \
65 _(IP_NEIGHBOR_DUMP, ip_neighbor_dump) \
66 _(IP_MROUTE_ADD_DEL, ip_mroute_add_del) \
67 _(MFIB_SIGNAL_DUMP, mfib_signal_dump) \
68 _(IP_ADDRESS_DUMP, ip_address_dump) \
69 _(IP_DUMP, ip_dump) \
70 _(IP_NEIGHBOR_ADD_DEL, ip_neighbor_add_del) \
71 _(IP_ADD_DEL_ROUTE, ip_add_del_route) \
72 _(IP_TABLE_ADD_DEL, ip_table_add_del) \
73 _(SET_IP_FLOW_HASH,set_ip_flow_hash) \
74 _(SW_INTERFACE_IP6ND_RA_CONFIG, sw_interface_ip6nd_ra_config) \
75 _(SW_INTERFACE_IP6ND_RA_PREFIX, sw_interface_ip6nd_ra_prefix) \
76 _(IP6ND_PROXY_ADD_DEL, ip6nd_proxy_add_del) \
77 _(IP6ND_PROXY_DUMP, ip6nd_proxy_dump) \
78 _(SW_INTERFACE_IP6_ENABLE_DISABLE, sw_interface_ip6_enable_disable ) \
79 _(SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS, \
80  sw_interface_ip6_set_link_local_address)
81 
82 extern void stats_dslock_with_hint (int hint, int tag);
83 extern void stats_dsunlock (void);
84 
85 static void
87  u8 is_static,
88  u8 * mac_address,
89  u8 * ip_address,
90  unix_shared_memory_queue_t * q, u32 context)
91 {
93 
94  mp = vl_msg_api_alloc (sizeof (*mp));
95  memset (mp, 0, sizeof (*mp));
96  mp->_vl_msg_id = ntohs (VL_API_IP_NEIGHBOR_DETAILS);
97  mp->context = context;
98  mp->is_ipv6 = is_ipv6;
99  mp->is_static = is_static;
100  memcpy (mp->mac_address, mac_address, 6);
101  memcpy (mp->ip_address, ip_address, (is_ipv6) ? 16 : 4);
102 
103  vl_msg_api_send_shmem (q, (u8 *) & mp);
104 }
105 
106 static void
108 {
110 
112  if (q == 0)
113  return;
114 
115  u32 sw_if_index = ntohl (mp->sw_if_index);
116 
117  if (mp->is_ipv6)
118  {
119  ip6_neighbor_t *n, *ns;
120 
121  ns = ip6_neighbors_entries (sw_if_index);
122  /* *INDENT-OFF* */
123  vec_foreach (n, ns)
124  {
126  (mp->is_ipv6, ((n->flags & IP6_NEIGHBOR_FLAG_STATIC) ? 1 : 0),
127  (u8 *) n->link_layer_address,
128  (u8 *) & (n->key.ip6_address.as_u8),
129  q, mp->context);
130  }
131  /* *INDENT-ON* */
132  vec_free (ns);
133  }
134  else
135  {
136  ethernet_arp_ip4_entry_t *n, *ns;
137 
138  ns = ip4_neighbor_entries (sw_if_index);
139  /* *INDENT-OFF* */
140  vec_foreach (n, ns)
141  {
143  ((n->flags & ETHERNET_ARP_IP4_ENTRY_FLAG_STATIC) ? 1 : 0),
144  (u8*) n->ethernet_address,
145  (u8*) & (n->ip4_address.as_u8),
146  q, mp->context);
147  }
148  /* *INDENT-ON* */
149  vec_free (ns);
150  }
151 }
152 
153 
154 void
155 copy_fib_next_hop (fib_route_path_encode_t * api_rpath, void *fp_arg)
156 {
157  int is_ip4;
158  vl_api_fib_path_t *fp = (vl_api_fib_path_t *) fp_arg;
159 
160  if (api_rpath->rpath.frp_proto == DPO_PROTO_IP4)
161  fp->afi = IP46_TYPE_IP4;
162  else if (api_rpath->rpath.frp_proto == DPO_PROTO_IP6)
163  fp->afi = IP46_TYPE_IP6;
164  else
165  {
166  is_ip4 = ip46_address_is_ip4 (&api_rpath->rpath.frp_addr);
167  if (is_ip4)
168  fp->afi = IP46_TYPE_IP4;
169  else
170  fp->afi = IP46_TYPE_IP6;
171  }
172  if (fp->afi == IP46_TYPE_IP4)
173  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip4,
174  sizeof (api_rpath->rpath.frp_addr.ip4));
175  else
176  memcpy (fp->next_hop, &api_rpath->rpath.frp_addr.ip6,
177  sizeof (api_rpath->rpath.frp_addr.ip6));
178 }
179 
180 static void
183  const fib_table_t * table,
184  const fib_prefix_t * pfx,
185  fib_route_path_encode_t * api_rpaths, u32 context)
186 {
188  fib_route_path_encode_t *api_rpath;
189  vl_api_fib_path_t *fp;
190  int path_count;
191 
192  path_count = vec_len (api_rpaths);
193  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
194  if (!mp)
195  return;
196  memset (mp, 0, sizeof (*mp));
197  mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
198  mp->context = context;
199 
200  mp->table_id = htonl (table->ft_table_id);
201  memcpy (mp->table_name, table->ft_desc,
202  clib_min (vec_len (table->ft_desc), sizeof (mp->table_name)));
203  mp->address_length = pfx->fp_len;
204  memcpy (mp->address, &pfx->fp_addr.ip4, sizeof (pfx->fp_addr.ip4));
205 
206  mp->count = htonl (path_count);
207  fp = mp->path;
208  vec_foreach (api_rpath, api_rpaths)
209  {
210  memset (fp, 0, sizeof (*fp));
211  switch (api_rpath->dpo.dpoi_type)
212  {
213  case DPO_RECEIVE:
214  fp->is_local = true;
215  break;
216  case DPO_DROP:
217  fp->is_drop = true;
218  break;
219  case DPO_IP_NULL:
220  switch (api_rpath->dpo.dpoi_index)
221  {
222  case IP_NULL_ACTION_NONE:
223  fp->is_drop = true;
224  break;
226  fp->is_unreach = true;
227  break;
229  fp->is_prohibit = true;
230  break;
231  default:
232  break;
233  }
234  break;
235  default:
236  break;
237  }
238  fp->weight = api_rpath->rpath.frp_weight;
239  fp->preference = api_rpath->rpath.frp_preference;
240  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
241  copy_fib_next_hop (api_rpath, fp);
242  fp++;
243  }
244 
245  vl_msg_api_send_shmem (q, (u8 *) & mp);
246 }
247 
249 {
252 
253 static int
255 {
257 
258  vec_add1 (ctx->feis, fei);
259 
260  return (1);
261 }
262 
263 static void
265 {
268  ip4_main_t *im = &ip4_main;
269  fib_table_t *fib_table;
270  fib_node_index_t *lfeip;
271  fib_prefix_t pfx;
272  u32 fib_index;
273  fib_route_path_encode_t *api_rpaths;
275  .feis = NULL,
276  };
277 
279  if (q == 0)
280  return;
281 
282  /* *INDENT-OFF* */
283  pool_foreach (fib_table, im->fibs,
284  ({
285  fib_table_walk(fib_table->ft_index,
286  FIB_PROTOCOL_IP4,
287  vl_api_ip_fib_dump_walk,
288  &ctx);
289  }));
290  /* *INDENT-ON* */
291 
293 
294  vec_foreach (lfeip, ctx.feis)
295  {
296  fib_entry_get_prefix (*lfeip, &pfx);
297  fib_index = fib_entry_get_fib_index (*lfeip);
298  fib_table = fib_table_get (fib_index, pfx.fp_proto);
299  api_rpaths = NULL;
300  fib_entry_encode (*lfeip, &api_rpaths);
301  send_ip_fib_details (am, q, fib_table, &pfx, api_rpaths, mp->context);
302  vec_free (api_rpaths);
303  }
304 
305  vec_free (ctx.feis);
306 }
307 
308 static void
311  u32 table_id, fib_prefix_t * pfx,
312  fib_route_path_encode_t * api_rpaths, u32 context)
313 {
315  fib_route_path_encode_t *api_rpath;
316  vl_api_fib_path_t *fp;
317  int path_count;
318 
319  path_count = vec_len (api_rpaths);
320  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
321  if (!mp)
322  return;
323  memset (mp, 0, sizeof (*mp));
324  mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
325  mp->context = context;
326 
327  mp->table_id = htonl (table_id);
328  mp->address_length = pfx->fp_len;
329  memcpy (mp->address, &pfx->fp_addr.ip6, sizeof (pfx->fp_addr.ip6));
330 
331  mp->count = htonl (path_count);
332  fp = mp->path;
333  vec_foreach (api_rpath, api_rpaths)
334  {
335  memset (fp, 0, sizeof (*fp));
336  switch (api_rpath->dpo.dpoi_type)
337  {
338  case DPO_RECEIVE:
339  fp->is_local = true;
340  break;
341  case DPO_DROP:
342  fp->is_drop = true;
343  break;
344  case DPO_IP_NULL:
345  switch (api_rpath->dpo.dpoi_index)
346  {
348  fp->is_drop = true;
349  break;
351  fp->is_unreach = true;
352  break;
354  fp->is_prohibit = true;
355  break;
356  default:
357  break;
358  }
359  break;
360  default:
361  break;
362  }
363  fp->weight = api_rpath->rpath.frp_weight;
364  fp->preference = api_rpath->rpath.frp_preference;
365  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
366  copy_fib_next_hop (api_rpath, fp);
367  fp++;
368  }
369 
370  vl_msg_api_send_shmem (q, (u8 *) & mp);
371 }
372 
374 {
378 
379 static void
381 {
383 
384  if ((kvp->key[2] >> 32) == ctx->fib_index)
385  {
386  vec_add1 (ctx->entries, kvp->value);
387  }
388 }
389 
390 static void
393  fib_table_t * fib_table)
394 {
396  ip6_main_t *im6 = &ip6_main;
397  fib_node_index_t *fib_entry_index;
399  .fib_index = fib_table->ft_index,
400  .entries = NULL,
401  };
402  fib_route_path_encode_t *api_rpaths;
403  fib_prefix_t pfx;
404 
406  ((BVT (clib_bihash) *) & im6->ip6_table[IP6_FIB_TABLE_NON_FWDING].
407  ip6_hash, api_ip6_fib_table_put_entries, &ctx);
408 
410 
411  vec_foreach (fib_entry_index, ctx.entries)
412  {
413  fib_entry_get_prefix (*fib_entry_index, &pfx);
414  api_rpaths = NULL;
415  fib_entry_encode (*fib_entry_index, &api_rpaths);
416  send_ip6_fib_details (am, q,
417  fib_table->ft_table_id,
418  &pfx, api_rpaths, mp->context);
419  vec_free (api_rpaths);
420  }
421 
422  vec_free (ctx.entries);
423 }
424 
425 static void
427 {
429  ip6_main_t *im6 = &ip6_main;
430  fib_table_t *fib_table;
431 
433  if (q == 0)
434  return;
435 
436  /* *INDENT-OFF* */
437  pool_foreach (fib_table, im6->fibs,
438  ({
439  api_ip6_fib_table_get_all(q, mp, fib_table);
440  }));
441  /* *INDENT-ON* */
442 }
443 
444 static void
446  u32 context, u32 table_id, fib_node_index_t mfei)
447 {
448  fib_route_path_encode_t *api_rpath, *api_rpaths = NULL;
450  mfib_entry_t *mfib_entry;
451  vl_api_fib_path_t *fp;
452  mfib_prefix_t pfx;
453  int path_count;
454 
455  mfib_entry = mfib_entry_get (mfei);
456  mfib_entry_get_prefix (mfei, &pfx);
457  mfib_entry_encode (mfei, &api_rpaths);
458 
459  path_count = vec_len (api_rpaths);
460  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
461  if (!mp)
462  return;
463  memset (mp, 0, sizeof (*mp));
464  mp->_vl_msg_id = ntohs (VL_API_IP_FIB_DETAILS);
465  mp->context = context;
466 
467  mp->rpf_id = mfib_entry->mfe_rpf_id;
468  mp->entry_flags = mfib_entry->mfe_flags;
469  mp->table_id = htonl (table_id);
470  mp->address_length = pfx.fp_len;
471  memcpy (mp->grp_address, &pfx.fp_grp_addr.ip4,
472  sizeof (pfx.fp_grp_addr.ip4));
473  memcpy (mp->src_address, &pfx.fp_src_addr.ip4,
474  sizeof (pfx.fp_src_addr.ip4));
475 
476  mp->count = htonl (path_count);
477  fp = mp->path;
478  vec_foreach (api_rpath, api_rpaths)
479  {
480  memset (fp, 0, sizeof (*fp));
481 
482  fp->weight = 0;
483  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
484  copy_fib_next_hop (api_rpath, fp);
485  fp++;
486  }
487  vec_free (api_rpaths);
488 
489  vl_msg_api_send_shmem (q, (u8 *) & mp);
490 }
491 
493 {
496 
497 static int
499 {
501 
502  vec_add1 (ctx->entries, fei);
503 
504  return (0);
505 }
506 
507 static void
509 {
511  ip4_main_t *im = &ip4_main;
512  mfib_table_t *mfib_table;
513  fib_node_index_t *mfeip;
515  .entries = NULL,
516  };
517 
519  if (q == 0)
520  return;
521 
522 
523  /* *INDENT-OFF* */
524  pool_foreach (mfib_table, im->mfibs,
525  ({
526  ip4_mfib_table_walk(&mfib_table->v4,
527  vl_api_ip_mfib_table_dump_walk,
528  &ctx);
529 
530  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
531 
532  vec_foreach (mfeip, ctx.entries)
533  {
534  send_ip_mfib_details (q, mp->context,
535  mfib_table->mft_table_id,
536  *mfeip);
537  }
539 
540  }));
541  /* *INDENT-ON* */
542 
543  vec_free (ctx.entries);
544 }
545 
546 static void
549  u32 table_id,
550  mfib_prefix_t * pfx,
551  fib_route_path_encode_t * api_rpaths, u32 context)
552 {
554  fib_route_path_encode_t *api_rpath;
555  vl_api_fib_path_t *fp;
556  int path_count;
557 
558  path_count = vec_len (api_rpaths);
559  mp = vl_msg_api_alloc (sizeof (*mp) + path_count * sizeof (*fp));
560  if (!mp)
561  return;
562  memset (mp, 0, sizeof (*mp));
563  mp->_vl_msg_id = ntohs (VL_API_IP6_FIB_DETAILS);
564  mp->context = context;
565 
566  mp->table_id = htonl (table_id);
567  mp->address_length = pfx->fp_len;
568  memcpy (mp->grp_address, &pfx->fp_grp_addr.ip6,
569  sizeof (pfx->fp_grp_addr.ip6));
570  memcpy (mp->src_address, &pfx->fp_src_addr.ip6,
571  sizeof (pfx->fp_src_addr.ip6));
572 
573  mp->count = htonl (path_count);
574  fp = mp->path;
575  vec_foreach (api_rpath, api_rpaths)
576  {
577  memset (fp, 0, sizeof (*fp));
578 
579  fp->weight = 0;
580  fp->sw_if_index = htonl (api_rpath->rpath.frp_sw_if_index);
581  copy_fib_next_hop (api_rpath, fp);
582  fp++;
583  }
584 
585  vl_msg_api_send_shmem (q, (u8 *) & mp);
586 }
587 
589 {
592 
593 static int
595 {
597 
598  vec_add1 (ctx->entries, fei);
599 
600  return (0);
601 }
602 
603 static void
605 {
608  ip6_main_t *im = &ip6_main;
609  mfib_table_t *mfib_table;
610  fib_node_index_t *mfeip;
611  mfib_prefix_t pfx;
612  fib_route_path_encode_t *api_rpaths = NULL;
614  .entries = NULL,
615  };
616 
618  if (q == 0)
619  return;
620 
621 
622  /* *INDENT-OFF* */
623  pool_foreach (mfib_table, im->mfibs,
624  ({
625  ip6_mfib_table_walk(&mfib_table->v6,
626  vl_api_ip6_mfib_table_dump_walk,
627  &ctx);
628 
629  vec_sort_with_function (ctx.entries, mfib_entry_cmp_for_sort);
630 
631  vec_foreach(mfeip, ctx.entries)
632  {
633  mfib_entry_get_prefix (*mfeip, &pfx);
634  mfib_entry_encode (*mfeip, &api_rpaths);
635  send_ip6_mfib_details (am, q,
636  mfib_table->mft_table_id,
637  &pfx, api_rpaths,
638  mp->context);
639  }
640  vec_reset_length (api_rpaths);
642 
643  }));
644  /* *INDENT-ON* */
645 
646  vec_free (ctx.entries);
647  vec_free (api_rpaths);
648 }
649 
650 static void
652  vlib_main_t * vm)
653 {
654  vl_api_ip_neighbor_add_del_reply_t *rmp;
655  vnet_main_t *vnm = vnet_get_main ();
656  int rv = 0;
657 
659 
660  stats_dslock_with_hint (1 /* release hint */ , 7 /* tag */ );
661 
662  /*
663  * there's no validation here of the ND/ARP entry being added.
664  * The expectation is that the FIB will ensure that nothing bad
665  * will come of adding bogus entries.
666  */
667  if (mp->is_ipv6)
668  {
669  if (mp->is_add)
671  (vm, ntohl (mp->sw_if_index),
672  (ip6_address_t *) (mp->dst_address),
673  mp->mac_address, sizeof (mp->mac_address), mp->is_static,
674  mp->is_no_adj_fib);
675  else
677  (vm, ntohl (mp->sw_if_index),
678  (ip6_address_t *) (mp->dst_address),
679  mp->mac_address, sizeof (mp->mac_address));
680  }
681  else
682  {
683  ethernet_arp_ip4_over_ethernet_address_t a;
684 
685  clib_memcpy (&a.ethernet, mp->mac_address, 6);
686  clib_memcpy (&a.ip4, mp->dst_address, 4);
687 
688  if (mp->is_add)
689  rv = vnet_arp_set_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index),
690  &a, mp->is_static,
691  mp->is_no_adj_fib);
692  else
693  rv =
694  vnet_arp_unset_ip4_over_ethernet (vnm, ntohl (mp->sw_if_index), &a);
695  }
696 
697  stats_dsunlock ();
698 
700  REPLY_MACRO (VL_API_IP_NEIGHBOR_ADD_DEL_REPLY);
701 }
702 
703 void
704 ip_table_delete (fib_protocol_t fproto, u32 table_id, u8 is_api)
705 {
706  u32 fib_index, mfib_index;
707 
708  /*
709  * ignore action on the default table - this is always present
710  * and cannot be added nor deleted from the API
711  */
712  if (0 != table_id)
713  {
714  /*
715  * The API holds only one lock on the table.
716  * i.e. it can be added many times via the API but needs to be
717  * deleted only once.
718  * The FIB index for unicast and multicast is not necessarily the
719  * same, since internal VPP systesm (like LISP and SR) create
720  * their own unicast tables.
721  */
722  fib_index = fib_table_find (fproto, table_id);
723  mfib_index = mfib_table_find (fproto, table_id);
724 
725  if (~0 != fib_index)
726  {
727  fib_table_unlock (fib_index, fproto,
728  (is_api ? FIB_SOURCE_API : FIB_SOURCE_CLI));
729  }
730  if (~0 != mfib_index)
731  {
732  mfib_table_unlock (mfib_index, fproto,
733  (is_api ? MFIB_SOURCE_API : MFIB_SOURCE_CLI));
734  }
735  }
736 }
737 
738 void
740 {
741  vl_api_ip_table_add_del_reply_t *rmp;
743  u32 table_id = ntohl (mp->table_id);
744  int rv = 0;
745 
746  if (mp->is_add)
747  {
748  ip_table_create (fproto, table_id, 1, mp->name);
749  }
750  else
751  {
752  ip_table_delete (fproto, table_id, 1);
753  }
754 
755  REPLY_MACRO (VL_API_IP_TABLE_ADD_DEL_REPLY);
756 }
757 
758 int
760  u8 is_add,
761  u8 is_drop,
762  u8 is_unreach,
763  u8 is_prohibit,
764  u8 is_local,
765  u8 is_multicast,
766  u8 is_classify,
767  u32 classify_table_index,
768  u8 is_resolve_host,
769  u8 is_resolve_attached,
770  u8 is_interface_rx,
771  u8 is_rpf_id,
772  u32 fib_index,
773  const fib_prefix_t * prefix,
774  dpo_proto_t next_hop_proto,
775  const ip46_address_t * next_hop,
776  u32 next_hop_sw_if_index,
777  u8 next_hop_fib_index,
778  u16 next_hop_weight,
779  u16 next_hop_preference,
780  mpls_label_t next_hop_via_label,
781  mpls_label_t * next_hop_out_label_stack)
782 {
785  fib_route_path_t path = {
786  .frp_proto = next_hop_proto,
787  .frp_addr = (NULL == next_hop ? zero_addr : *next_hop),
788  .frp_sw_if_index = next_hop_sw_if_index,
789  .frp_fib_index = next_hop_fib_index,
790  .frp_weight = next_hop_weight,
791  .frp_preference = next_hop_preference,
792  .frp_label_stack = next_hop_out_label_stack,
793  };
794  fib_route_path_t *paths = NULL;
796 
797  /*
798  * the special INVALID label meams we are not recursing via a
799  * label. Exp-null value is never a valid via-label so that
800  * also means it's not a via-label and means clients that set
801  * it to 0 by default get the expected behaviour
802  */
803  if ((MPLS_LABEL_INVALID != next_hop_via_label) && (0 != next_hop_via_label))
804  {
805  path.frp_proto = DPO_PROTO_MPLS;
806  path.frp_local_label = next_hop_via_label;
807  path.frp_eos = MPLS_NON_EOS;
808  }
809  if (is_resolve_host)
810  path_flags |= FIB_ROUTE_PATH_RESOLVE_VIA_HOST;
811  if (is_resolve_attached)
813  if (is_interface_rx)
814  path_flags |= FIB_ROUTE_PATH_INTF_RX;
815  if (is_rpf_id)
816  path_flags |= FIB_ROUTE_PATH_RPF_ID;
817  if (is_multicast)
818  entry_flags |= FIB_ENTRY_FLAG_MULTICAST;
819 
820  path.frp_flags = path_flags;
821 
822  if (is_multipath)
823  {
824  stats_dslock_with_hint (1 /* release hint */ , 10 /* tag */ );
825 
826 
827  vec_add1 (paths, path);
828 
829  if (is_add)
830  fib_table_entry_path_add2 (fib_index,
831  prefix,
832  FIB_SOURCE_API, entry_flags, paths);
833  else
834  fib_table_entry_path_remove2 (fib_index,
835  prefix, FIB_SOURCE_API, paths);
836 
837  vec_free (paths);
838  stats_dsunlock ();
839  return 0;
840  }
841 
842  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
843 
844  if (is_drop || is_local || is_classify || is_unreach || is_prohibit)
845  {
846  /*
847  * special route types that link directly to the adj
848  */
849  if (is_add)
850  {
851  dpo_id_t dpo = DPO_INVALID;
852  dpo_proto_t dproto;
853 
854  dproto = fib_proto_to_dpo (prefix->fp_proto);
855 
856  if (is_drop)
858  else if (is_local)
859  receive_dpo_add_or_lock (dproto, ~0, NULL, &dpo);
860  else if (is_unreach)
861  ip_null_dpo_add_and_lock (dproto,
863  else if (is_prohibit)
864  ip_null_dpo_add_and_lock (dproto,
866  &dpo);
867  else if (is_classify)
868  {
869  if (pool_is_free_index (cm->tables,
870  ntohl (classify_table_index)))
871  {
872  stats_dsunlock ();
873  return VNET_API_ERROR_NO_SUCH_TABLE;
874  }
875 
876  dpo_set (&dpo, DPO_CLASSIFY, dproto,
877  classify_dpo_create (dproto,
878  ntohl (classify_table_index)));
879  }
880  else
881  {
882  stats_dsunlock ();
883  return VNET_API_ERROR_NO_SUCH_TABLE;
884  }
885 
887  prefix,
890  dpo_reset (&dpo);
891  }
892  else
893  {
894  fib_table_entry_special_remove (fib_index, prefix, FIB_SOURCE_API);
895  }
896  }
897  else
898  {
899  if (is_add)
900  {
901  vec_add1 (paths, path);
902  fib_table_entry_update (fib_index,
903  prefix, FIB_SOURCE_API, entry_flags, paths);
904  vec_free (paths);
905  }
906  else
907  {
908  fib_table_entry_delete (fib_index, prefix, FIB_SOURCE_API);
909  }
910  }
911 
912  stats_dsunlock ();
913  return (0);
914 }
915 
916 int
918  u32 table_id,
919  u32 next_hop_sw_if_index,
920  dpo_proto_t next_hop_table_proto,
921  u32 next_hop_table_id,
922  u8 is_rpf_id, u32 * fib_index, u32 * next_hop_fib_index)
923 {
924  vnet_main_t *vnm = vnet_get_main ();
925 
926  /* Temporaray whilst I do the CSIT dance */
927  u8 create_missing_tables = 1;
928 
929  *fib_index = fib_table_find (table_proto, ntohl (table_id));
930  if (~0 == *fib_index)
931  {
932  if (create_missing_tables)
933  {
934  *fib_index = fib_table_find_or_create_and_lock (table_proto,
935  ntohl (table_id),
937  }
938  else
939  {
940  /* No such VRF, and we weren't asked to create one */
941  return VNET_API_ERROR_NO_SUCH_FIB;
942  }
943  }
944 
945  if (!is_rpf_id && ~0 != ntohl (next_hop_sw_if_index))
946  {
948  ntohl (next_hop_sw_if_index)))
949  {
950  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
951  }
952  }
953  else
954  {
955  fib_protocol_t fib_nh_proto;
956 
957  if (next_hop_table_proto > DPO_PROTO_MPLS)
958  return (0);
959 
960  fib_nh_proto = dpo_proto_to_fib (next_hop_table_proto);
961 
962  if (is_rpf_id)
963  *next_hop_fib_index = mfib_table_find (fib_nh_proto,
964  ntohl (next_hop_table_id));
965  else
966  *next_hop_fib_index = fib_table_find (fib_nh_proto,
967  ntohl (next_hop_table_id));
968 
969  if (~0 == *next_hop_fib_index)
970  {
971  if (create_missing_tables)
972  {
973  if (is_rpf_id)
974  *next_hop_fib_index =
976  ntohl
977  (next_hop_table_id),
979  else
980  *next_hop_fib_index =
981  fib_table_find_or_create_and_lock (fib_nh_proto,
982  ntohl
983  (next_hop_table_id),
985  }
986  else
987  {
988  /* No such VRF, and we weren't asked to create one */
989  return VNET_API_ERROR_NO_SUCH_FIB;
990  }
991  }
992  }
993 
994  return (0);
995 }
996 
997 static int
999 {
1000  u32 fib_index, next_hop_fib_index;
1001  mpls_label_t *label_stack = NULL;
1002  int rv, ii, n_labels;;
1003 
1005  mp->table_id,
1007  DPO_PROTO_IP4,
1008  mp->next_hop_table_id,
1009  0, &fib_index, &next_hop_fib_index);
1010 
1011  if (0 != rv)
1012  return (rv);
1013 
1014  fib_prefix_t pfx = {
1015  .fp_len = mp->dst_address_length,
1016  .fp_proto = FIB_PROTOCOL_IP4,
1017  };
1018  clib_memcpy (&pfx.fp_addr.ip4, mp->dst_address, sizeof (pfx.fp_addr.ip4));
1019 
1020  ip46_address_t nh;
1021  memset (&nh, 0, sizeof (nh));
1022  memcpy (&nh.ip4, mp->next_hop_address, sizeof (nh.ip4));
1023 
1024  n_labels = mp->next_hop_n_out_labels;
1025  if (n_labels == 0)
1026  ;
1027  else if (1 == n_labels)
1028  vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
1029  else
1030  {
1031  vec_validate (label_stack, n_labels - 1);
1032  for (ii = 0; ii < n_labels; ii++)
1033  label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
1034  }
1035 
1037  mp->is_add,
1038  mp->is_drop,
1039  mp->is_unreach,
1040  mp->is_prohibit,
1041  mp->is_local, 0,
1042  mp->is_classify,
1044  mp->is_resolve_host,
1045  mp->is_resolve_attached, 0, 0,
1046  fib_index, &pfx, DPO_PROTO_IP4,
1047  &nh,
1048  ntohl (mp->next_hop_sw_if_index),
1049  next_hop_fib_index,
1050  mp->next_hop_weight,
1051  mp->next_hop_preference,
1052  ntohl (mp->next_hop_via_label),
1053  label_stack));
1054 }
1055 
1056 static int
1058 {
1059  u32 fib_index, next_hop_fib_index;
1060  mpls_label_t *label_stack = NULL;
1061  int rv, ii, n_labels;;
1062 
1064  mp->table_id,
1066  DPO_PROTO_IP6,
1067  mp->next_hop_table_id,
1068  0, &fib_index, &next_hop_fib_index);
1069 
1070  if (0 != rv)
1071  return (rv);
1072 
1073  fib_prefix_t pfx = {
1074  .fp_len = mp->dst_address_length,
1075  .fp_proto = FIB_PROTOCOL_IP6,
1076  };
1077  clib_memcpy (&pfx.fp_addr.ip6, mp->dst_address, sizeof (pfx.fp_addr.ip6));
1078 
1079  ip46_address_t nh;
1080  memset (&nh, 0, sizeof (nh));
1081  memcpy (&nh.ip6, mp->next_hop_address, sizeof (nh.ip6));
1082 
1083  n_labels = mp->next_hop_n_out_labels;
1084  if (n_labels == 0)
1085  ;
1086  else if (1 == n_labels)
1087  vec_add1 (label_stack, ntohl (mp->next_hop_out_label_stack[0]));
1088  else
1089  {
1090  vec_validate (label_stack, n_labels - 1);
1091  for (ii = 0; ii < n_labels; ii++)
1092  label_stack[ii] = ntohl (mp->next_hop_out_label_stack[ii]);
1093  }
1094 
1096  mp->is_add,
1097  mp->is_drop,
1098  mp->is_unreach,
1099  mp->is_prohibit,
1100  mp->is_local, 0,
1101  mp->is_classify,
1103  mp->is_resolve_host,
1104  mp->is_resolve_attached, 0, 0,
1105  fib_index, &pfx, DPO_PROTO_IP6,
1106  &nh, ntohl (mp->next_hop_sw_if_index),
1107  next_hop_fib_index,
1108  mp->next_hop_weight,
1109  mp->next_hop_preference,
1110  ntohl (mp->next_hop_via_label),
1111  label_stack));
1112 }
1113 
1114 void
1116 {
1117  vl_api_ip_add_del_route_reply_t *rmp;
1118  int rv;
1119  vnet_main_t *vnm = vnet_get_main ();
1120 
1121  vnm->api_errno = 0;
1122 
1123  if (mp->is_ipv6)
1124  rv = ip6_add_del_route_t_handler (mp);
1125  else
1126  rv = ip4_add_del_route_t_handler (mp);
1127 
1128  rv = (rv == 0) ? vnm->api_errno : rv;
1129 
1130  REPLY_MACRO (VL_API_IP_ADD_DEL_ROUTE_REPLY);
1131 }
1132 
1133 void
1135  u32 table_id, u8 is_api, const u8 * name)
1136 {
1137  u32 fib_index, mfib_index;
1138 
1139  /*
1140  * ignore action on the default table - this is always present
1141  * and cannot be added nor deleted from the API
1142  */
1143  if (0 != table_id)
1144  {
1145  /*
1146  * The API holds only one lock on the table.
1147  * i.e. it can be added many times via the API but needs to be
1148  * deleted only once.
1149  * The FIB index for unicast and multicast is not necessarily the
1150  * same, since internal VPP systesm (like LISP and SR) create
1151  * their own unicast tables.
1152  */
1153  fib_index = fib_table_find (fproto, table_id);
1154  mfib_index = mfib_table_find (fproto, table_id);
1155 
1156  if (~0 == fib_index)
1157  {
1158  fib_table_find_or_create_and_lock_w_name (fproto, table_id,
1159  (is_api ?
1160  FIB_SOURCE_API :
1161  FIB_SOURCE_CLI), name);
1162  }
1163  if (~0 == mfib_index)
1164  {
1166  (is_api ?
1167  MFIB_SOURCE_API :
1168  MFIB_SOURCE_CLI), name);
1169  }
1170  }
1171 }
1172 
1173 static int
1175  u32 table_id,
1176  u32 next_hop_sw_if_index, u8 is_local, u32 * fib_index)
1177 {
1178  vnet_main_t *vnm = vnet_get_main ();
1179 
1180  *fib_index = mfib_table_find (table_proto, ntohl (table_id));
1181  if (~0 == *fib_index)
1182  {
1183  /* No such table */
1184  return VNET_API_ERROR_NO_SUCH_FIB;
1185  }
1186 
1187  if (~0 != ntohl (next_hop_sw_if_index))
1188  {
1190  ntohl (next_hop_sw_if_index)))
1191  {
1192  return VNET_API_ERROR_NO_MATCHING_INTERFACE;
1193  }
1194  }
1195 
1196  return (0);
1197 }
1198 
1199 static int
1201  u8 is_local,
1202  u32 fib_index,
1203  const mfib_prefix_t * prefix,
1204  u32 entry_flags,
1205  fib_rpf_id_t rpf_id,
1206  u32 next_hop_sw_if_index, u32 itf_flags)
1207 {
1208  stats_dslock_with_hint (1 /* release hint */ , 2 /* tag */ );
1209 
1210  fib_route_path_t path = {
1211  .frp_sw_if_index = next_hop_sw_if_index,
1212  .frp_proto = fib_proto_to_dpo (prefix->fp_proto),
1213  };
1214 
1215  if (is_local)
1217 
1218 
1219  if (!is_local && ~0 == next_hop_sw_if_index)
1220  {
1221  mfib_table_entry_update (fib_index, prefix,
1222  MFIB_SOURCE_API, rpf_id, entry_flags);
1223  }
1224  else
1225  {
1226  if (is_add)
1227  {
1228  mfib_table_entry_path_update (fib_index, prefix,
1229  MFIB_SOURCE_API, &path, itf_flags);
1230  }
1231  else
1232  {
1233  mfib_table_entry_path_remove (fib_index, prefix,
1234  MFIB_SOURCE_API, &path);
1235  }
1236  }
1237 
1238  stats_dsunlock ();
1239  return (0);
1240 }
1241 
1242 static int
1244 {
1245  fib_protocol_t fproto;
1246  u32 fib_index;
1247  int rv;
1248 
1249  fproto = (mp->is_ipv6 ? FIB_PROTOCOL_IP6 : FIB_PROTOCOL_IP4);
1250  rv = add_del_mroute_check (fproto,
1251  mp->table_id,
1253  mp->is_local, &fib_index);
1254 
1255  if (0 != rv)
1256  return (rv);
1257 
1258  mfib_prefix_t pfx = {
1259  .fp_len = ntohs (mp->grp_address_length),
1260  .fp_proto = fproto,
1261  };
1262 
1263  if (FIB_PROTOCOL_IP4 == fproto)
1264  {
1265  clib_memcpy (&pfx.fp_grp_addr.ip4, mp->grp_address,
1266  sizeof (pfx.fp_grp_addr.ip4));
1267  clib_memcpy (&pfx.fp_src_addr.ip4, mp->src_address,
1268  sizeof (pfx.fp_src_addr.ip4));
1269  }
1270  else
1271  {
1272  clib_memcpy (&pfx.fp_grp_addr.ip6, mp->grp_address,
1273  sizeof (pfx.fp_grp_addr.ip6));
1274  clib_memcpy (&pfx.fp_src_addr.ip6, mp->src_address,
1275  sizeof (pfx.fp_src_addr.ip6));
1276  }
1277 
1278  return (mroute_add_del_handler (mp->is_add,
1279  mp->is_local,
1280  fib_index, &pfx,
1281  ntohl (mp->entry_flags),
1282  ntohl (mp->rpf_id),
1283  ntohl (mp->next_hop_sw_if_index),
1284  ntohl (mp->itf_flags)));
1285 }
1286 
1287 void
1289 {
1290  vl_api_ip_mroute_add_del_reply_t *rmp;
1291  int rv;
1292  vnet_main_t *vnm = vnet_get_main ();
1293 
1294  vnm->api_errno = 0;
1295 
1296  rv = api_mroute_add_del_t_handler (mp);
1297 
1298  rv = (rv == 0) ? vnm->api_errno : rv;
1299 
1300  REPLY_MACRO (VL_API_IP_MROUTE_ADD_DEL_REPLY);
1301 }
1302 
1303 static void
1305  unix_shared_memory_queue_t * q, u32 sw_if_index,
1306  u8 is_ipv6, u32 context)
1307 {
1308  vl_api_ip_details_t *mp;
1309 
1310  mp = vl_msg_api_alloc (sizeof (*mp));
1311  memset (mp, 0, sizeof (*mp));
1312  mp->_vl_msg_id = ntohs (VL_API_IP_DETAILS);
1313 
1314  mp->sw_if_index = ntohl (sw_if_index);
1315  mp->is_ipv6 = is_ipv6;
1316  mp->context = context;
1317 
1318  vl_msg_api_send_shmem (q, (u8 *) & mp);
1319 }
1320 
1321 static void
1324  u8 * ip, u16 prefix_length,
1325  u32 sw_if_index, u8 is_ipv6, u32 context)
1326 {
1328 
1329  mp = vl_msg_api_alloc (sizeof (*mp));
1330  memset (mp, 0, sizeof (*mp));
1331  mp->_vl_msg_id = ntohs (VL_API_IP_ADDRESS_DETAILS);
1332 
1333  if (is_ipv6)
1334  {
1335  clib_memcpy (&mp->ip, ip, sizeof (mp->ip));
1336  }
1337  else
1338  {
1339  u32 *tp = (u32 *) mp->ip;
1340  *tp = *(u32 *) ip;
1341  }
1342  mp->prefix_length = prefix_length;
1343  mp->context = context;
1344  mp->sw_if_index = htonl (sw_if_index);
1345  mp->is_ipv6 = is_ipv6;
1346 
1347  vl_msg_api_send_shmem (q, (u8 *) & mp);
1348 }
1349 
1350 static void
1352 {
1355  ip6_address_t *r6;
1356  ip4_address_t *r4;
1357  ip6_main_t *im6 = &ip6_main;
1358  ip4_main_t *im4 = &ip4_main;
1359  ip_lookup_main_t *lm6 = &im6->lookup_main;
1360  ip_lookup_main_t *lm4 = &im4->lookup_main;
1361  ip_interface_address_t *ia = 0;
1362  u32 sw_if_index = ~0;
1363  int rv __attribute__ ((unused)) = 0;
1364 
1365  VALIDATE_SW_IF_INDEX (mp);
1366 
1367  sw_if_index = ntohl (mp->sw_if_index);
1368 
1370  if (q == 0)
1371  return;
1372 
1373  if (mp->is_ipv6)
1374  {
1375  /* *INDENT-OFF* */
1376  foreach_ip_interface_address (lm6, ia, sw_if_index,
1377  1 /* honor unnumbered */,
1378  ({
1379  r6 = ip_interface_address_get_address (lm6, ia);
1380  u16 prefix_length = ia->address_length;
1381  send_ip_address_details(am, q, (u8*)r6, prefix_length,
1382  sw_if_index, 1, mp->context);
1383  }));
1384  /* *INDENT-ON* */
1385  }
1386  else
1387  {
1388  /* *INDENT-OFF* */
1389  foreach_ip_interface_address (lm4, ia, sw_if_index,
1390  1 /* honor unnumbered */,
1391  ({
1392  r4 = ip_interface_address_get_address (lm4, ia);
1393  u16 prefix_length = ia->address_length;
1394  send_ip_address_details(am, q, (u8*)r4, prefix_length,
1395  sw_if_index, 0, mp->context);
1396  }));
1397  /* *INDENT-ON* */
1398  }
1400 }
1401 
1402 static void
1404 {
1406  vnet_main_t *vnm = vnet_get_main ();
1410  vnet_sw_interface_t *si, *sorted_sis;
1411  u32 sw_if_index = ~0;
1412 
1414  if (q == 0)
1415  {
1416  return;
1417  }
1418 
1419  /* Gather interfaces. */
1420  sorted_sis = vec_new (vnet_sw_interface_t, pool_elts (im->sw_interfaces));
1421  _vec_len (sorted_sis) = 0;
1422  /* *INDENT-OFF* */
1423  pool_foreach (si, im->sw_interfaces,
1424  ({
1425  vec_add1 (sorted_sis, si[0]);
1426  }));
1427  /* *INDENT-ON* */
1428 
1429  vec_foreach (si, sorted_sis)
1430  {
1432  {
1433  if (mp->is_ipv6 && !ip6_interface_enabled (vm, si->sw_if_index))
1434  {
1435  continue;
1436  }
1437  sw_if_index = si->sw_if_index;
1438  send_ip_details (am, q, sw_if_index, mp->is_ipv6, mp->context);
1439  }
1440  }
1441 }
1442 
1443 static void
1445 {
1446  vl_api_set_ip_flow_hash_reply_t *rmp;
1447  int rv;
1448  u32 table_id;
1449  flow_hash_config_t flow_hash_config = 0;
1450 
1451  table_id = ntohl (mp->vrf_id);
1452 
1453 #define _(a,b) if (mp->a) flow_hash_config |= b;
1455 #undef _
1456 
1457  rv = vnet_set_ip6_flow_hash (table_id, flow_hash_config);
1458 
1459  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1460 }
1461 
1462 static void
1464 {
1465  vl_api_set_ip_flow_hash_reply_t *rmp;
1466  int rv;
1467  u32 table_id;
1468  flow_hash_config_t flow_hash_config = 0;
1469 
1470  table_id = ntohl (mp->vrf_id);
1471 
1472 #define _(a,b) if (mp->a) flow_hash_config |= b;
1474 #undef _
1475 
1476  rv = vnet_set_ip4_flow_hash (table_id, flow_hash_config);
1477 
1478  REPLY_MACRO (VL_API_SET_IP_FLOW_HASH_REPLY);
1479 }
1480 
1481 
1482 static void
1484 {
1485  if (mp->is_ipv6 == 0)
1486  set_ip4_flow_hash (mp);
1487  else
1488  set_ip6_flow_hash (mp);
1489 }
1490 
1491 static void
1494 {
1495  vl_api_sw_interface_ip6nd_ra_config_reply_t *rmp;
1497  int rv = 0;
1498  u8 is_no, suppress, managed, other, ll_option, send_unicast, cease,
1499  default_router;
1500 
1501  is_no = mp->is_no == 1;
1502  suppress = mp->suppress == 1;
1503  managed = mp->managed == 1;
1504  other = mp->other == 1;
1505  ll_option = mp->ll_option == 1;
1506  send_unicast = mp->send_unicast == 1;
1507  cease = mp->cease == 1;
1508  default_router = mp->default_router == 1;
1509 
1510  VALIDATE_SW_IF_INDEX (mp);
1511 
1512  rv = ip6_neighbor_ra_config (vm, ntohl (mp->sw_if_index),
1513  suppress, managed, other,
1514  ll_option, send_unicast, cease,
1515  default_router, ntohl (mp->lifetime),
1516  ntohl (mp->initial_count),
1517  ntohl (mp->initial_interval),
1518  ntohl (mp->max_interval),
1519  ntohl (mp->min_interval), is_no);
1520 
1522 
1523  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_CONFIG_REPLY);
1524 }
1525 
1526 static void
1529 {
1531  vl_api_sw_interface_ip6nd_ra_prefix_reply_t *rmp;
1532  int rv = 0;
1533  u8 is_no, use_default, no_advertise, off_link, no_autoconfig, no_onlink;
1534 
1535  VALIDATE_SW_IF_INDEX (mp);
1536 
1537  is_no = mp->is_no == 1;
1538  use_default = mp->use_default == 1;
1539  no_advertise = mp->no_advertise == 1;
1540  off_link = mp->off_link == 1;
1541  no_autoconfig = mp->no_autoconfig == 1;
1542  no_onlink = mp->no_onlink == 1;
1543 
1544  rv = ip6_neighbor_ra_prefix (vm, ntohl (mp->sw_if_index),
1545  (ip6_address_t *) mp->address,
1546  mp->address_length, use_default,
1547  ntohl (mp->val_lifetime),
1548  ntohl (mp->pref_lifetime), no_advertise,
1549  off_link, no_autoconfig, no_onlink, is_no);
1550 
1552  REPLY_MACRO (VL_API_SW_INTERFACE_IP6ND_RA_PREFIX_REPLY);
1553 }
1554 
1555 static void
1557  u32 context,
1558  const ip46_address_t * addr, u32 sw_if_index)
1559 {
1561 
1562  mp = vl_msg_api_alloc (sizeof (*mp));
1563  memset (mp, 0, sizeof (*mp));
1564  mp->_vl_msg_id = ntohs (VL_API_IP6ND_PROXY_DETAILS);
1565  mp->context = context;
1566  mp->sw_if_index = htonl (sw_if_index);
1567  memcpy (mp->address, addr, 16);
1568 
1569  vl_msg_api_send_shmem (q, (u8 *) & mp);
1570 }
1571 
1573 {
1576 
1577 static int
1579 {
1581 
1583  {
1584  vec_add1 (ctx->indices, fei);
1585  }
1586 
1587  return (1);
1588 }
1589 
1590 static void
1592 {
1593  ip6_main_t *im6 = &ip6_main;
1594  fib_table_t *fib_table;
1596  .indices = NULL,
1597  };
1598  fib_node_index_t *feip;
1599  fib_prefix_t pfx;
1601 
1603  if (q == 0)
1604  {
1605  return;
1606  }
1607 
1608  /* *INDENT-OFF* */
1609  pool_foreach (fib_table, im6->fibs,
1610  ({
1611  fib_table_walk(fib_table->ft_index,
1612  FIB_PROTOCOL_IP6,
1613  api_ip6nd_proxy_fib_table_walk,
1614  &ctx);
1615  }));
1616  /* *INDENT-ON* */
1617 
1619 
1620  vec_foreach (feip, ctx.indices)
1621  {
1622  fib_entry_get_prefix (*feip, &pfx);
1623 
1625  mp->context,
1626  &pfx.fp_addr,
1628  }
1629 
1630  vec_free (ctx.indices);
1631 }
1632 
1633 static void
1635 {
1636  vl_api_ip6nd_proxy_add_del_reply_t *rmp;
1637  int rv = 0;
1638 
1639  VALIDATE_SW_IF_INDEX (mp);
1640 
1641  rv = ip6_neighbor_proxy_add_del (ntohl (mp->sw_if_index),
1642  (ip6_address_t *) mp->address, mp->is_del);
1643 
1645  REPLY_MACRO (VL_API_IP6ND_PROXY_ADD_DEL_REPLY);
1646 }
1647 
1648 static void
1651 {
1653  vl_api_sw_interface_ip6_enable_disable_reply_t *rmp;
1654  vnet_main_t *vnm = vnet_get_main ();
1655  int rv = 0;
1656  clib_error_t *error;
1657 
1658  vnm->api_errno = 0;
1659 
1660  VALIDATE_SW_IF_INDEX (mp);
1661 
1662  error =
1663  (mp->enable == 1) ? enable_ip6_interface (vm,
1664  ntohl (mp->sw_if_index)) :
1665  disable_ip6_interface (vm, ntohl (mp->sw_if_index));
1666 
1667  if (error)
1668  {
1669  clib_error_report (error);
1670  rv = VNET_API_ERROR_UNSPECIFIED;
1671  }
1672  else
1673  {
1674  rv = vnm->api_errno;
1675  }
1676 
1678 
1679  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_ENABLE_DISABLE_REPLY);
1680 }
1681 
1682 static void
1685 {
1687  vl_api_sw_interface_ip6_set_link_local_address_reply_t *rmp;
1688  int rv = 0;
1689  clib_error_t *error;
1690  vnet_main_t *vnm = vnet_get_main ();
1691 
1692  vnm->api_errno = 0;
1693 
1694  VALIDATE_SW_IF_INDEX (mp);
1695 
1696  error = set_ip6_link_local_address (vm,
1697  ntohl (mp->sw_if_index),
1698  (ip6_address_t *) mp->address);
1699  if (error)
1700  {
1701  clib_error_report (error);
1702  rv = VNET_API_ERROR_UNSPECIFIED;
1703  }
1704  else
1705  {
1706  rv = vnm->api_errno;
1707  }
1708 
1710 
1711  REPLY_MACRO (VL_API_SW_INTERFACE_IP6_SET_LINK_LOCAL_ADDRESS_REPLY);
1712 }
1713 
1714 void
1716  u32 context, const mfib_signal_t * mfs)
1717 {
1719  mfib_prefix_t prefix;
1720  mfib_table_t *mfib;
1721  mfib_itf_t *mfi;
1722 
1723  mp = vl_msg_api_alloc (sizeof (*mp));
1724 
1725  memset (mp, 0, sizeof (*mp));
1726  mp->_vl_msg_id = ntohs (VL_API_MFIB_SIGNAL_DETAILS);
1727  mp->context = context;
1728 
1729  mfi = mfib_itf_get (mfs->mfs_itf);
1730  mfib_entry_get_prefix (mfs->mfs_entry, &prefix);
1732  prefix.fp_proto);
1733  mp->table_id = ntohl (mfib->mft_table_id);
1734  mp->sw_if_index = ntohl (mfi->mfi_sw_if_index);
1735 
1736  if (FIB_PROTOCOL_IP4 == prefix.fp_proto)
1737  {
1738  mp->grp_address_len = ntohs (prefix.fp_len);
1739 
1740  memcpy (mp->grp_address, &prefix.fp_grp_addr.ip4, 4);
1741  if (prefix.fp_len > 32)
1742  {
1743  memcpy (mp->src_address, &prefix.fp_src_addr.ip4, 4);
1744  }
1745  }
1746  else
1747  {
1748  mp->grp_address_len = ntohs (prefix.fp_len);
1749 
1750  ASSERT (0);
1751  }
1752 
1753  if (0 != mfs->mfs_buffer_len)
1754  {
1755  mp->ip_packet_len = ntohs (mfs->mfs_buffer_len);
1756 
1757  memcpy (mp->ip_packet_data, mfs->mfs_buffer, mfs->mfs_buffer_len);
1758  }
1759  else
1760  {
1761  mp->ip_packet_len = 0;
1762  }
1763 
1764  vl_msg_api_send_shmem (q, (u8 *) & mp);
1765 }
1766 
1767 static void
1769 {
1771 
1773  if (q == 0)
1774  {
1775  return;
1776  }
1777 
1778  while (q->cursize < q->maxsize && mfib_signal_send_one (q, mp->context))
1779  ;
1780 }
1781 
1782 #define vl_msg_name_crc_list
1783 #include <vnet/ip/ip.api.h>
1784 #undef vl_msg_name_crc_list
1785 
1786 static void
1788 {
1789 #define _(id,n,crc) vl_msg_api_add_msg_name_crc (am, #n "_" #crc, id);
1790  foreach_vl_msg_name_crc_ip;
1791 #undef _
1792 }
1793 
1794 static clib_error_t *
1796 {
1797  api_main_t *am = &api_main;
1798 
1799 #define _(N,n) \
1800  vl_msg_api_set_handlers(VL_API_##N, #n, \
1801  vl_api_##n##_t_handler, \
1802  vl_noop_handler, \
1803  vl_api_##n##_t_endian, \
1804  vl_api_##n##_t_print, \
1805  sizeof(vl_api_##n##_t), 1);
1807 #undef _
1808 
1809  /*
1810  * Set up the (msg_name, crc, message-id) table
1811  */
1813 
1814  return 0;
1815 }
1816 
1818 
1819 /*
1820  * fd.io coding-style-patch-verification: ON
1821  *
1822  * Local Variables:
1823  * eval: (c-set-style "gnu")
1824  * End:
1825  */
#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:169
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:579
u32 fib_entry_get_fib_index(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1557
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:350
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
static void vl_api_ip6nd_proxy_add_del_t_handler(vl_api_ip6nd_proxy_add_del_t *mp)
Definition: ip_api.c:1634
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:332
static int vl_api_ip_fib_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:254
A representation of a fib path for fib_path_encode to convey the information to the caller...
Definition: fib_types.h:404
mpls_eos_bit_t frp_eos
EOS bit for the resolving label.
Definition: fib_types.h:361
int vnet_set_ip4_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip4_forward.c:2917
u8 next_hop[16]
Definition: ip.api:76
Dump IP neighboors.
Definition: ip.api:130
Dump IP fib table.
Definition: ip.api:47
a
Definition: bitmap.h:516
vl_api_fib_path_t path[count]
Definition: ip.api:465
vl_api_fib_path_t path[count]
Definition: ip.api:94
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)
A representation of a path as described by a route producer.
Definition: fib_types.h:336
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:651
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:547
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
vnet_interface_main_t interface_main
Definition: vnet.h:56
IP FIB table response.
Definition: ip.api:86
The table that stores ALL routes learned by the DP.
Definition: ip6.h:132
static int mroute_add_del_handler(u8 is_add, u8 is_local, u32 fib_index, const mfib_prefix_t *prefix, u32 entry_flags, fib_rpf_id_t rpf_id, u32 next_hop_sw_if_index, u32 itf_flags)
Definition: ip_api.c:1200
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:1547
Dump IP multicast fib table.
Definition: ip.api:441
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:1093
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:705
#define NULL
Definition: clib.h:55
An entry in a FIB table.
Definition: mfib_entry.h:31
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:538
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
From the CLI.
Definition: fib_entry.h:66
#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
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:704
ip_lookup_main_t lookup_main
Definition: ip4.h:97
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:341
IPv6 router advertisement config request.
Definition: ip.api:222
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:1556
Definition: fib_entry.h:236
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:301
static void vl_api_ip6nd_proxy_dump_t_handler(vl_api_ip6nd_proxy_dump_t *mp)
Definition: ip_api.c:1591
static void api_ip6_fib_table_put_entries(clib_bihash_kv_24_8_t *kvp, void *arg)
Definition: ip_api.c:380
Dump IP6 fib table.
Definition: ip.api:100
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:508
A local path with a RPF-ID => multicast traffic.
Definition: fib_types.h:305
ip6_neighbor_flags_t flags
Definition: ip6_neighbor.h:42
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:437
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:369
Add / del table request A table can be added multiple times, but need be deleted only once...
Definition: ip.api:34
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:1174
Dump IP6 multicast fib table.
Definition: ip.api:471
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
vl_api_fib_path_t path[count]
Definition: ip.api:493
#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
Recursion constraint of via a host prefix.
Definition: fib_types.h:276
static void vl_api_ip6_mfib_dump_t_handler(vl_api_ip6_mfib_dump_t *mp)
Definition: ip_api.c:604
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
Aggregrate type for a prefix.
Definition: fib_types.h:160
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:1403
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:1057
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:334
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:1322
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:1025
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:1304
u16 fp_len
The mask length.
Definition: fib_types.h:164
static void vl_api_mfib_signal_dump_t_handler(vl_api_mfib_signal_dump_t *mp)
Definition: ip_api.c:1768
int fib_entry_cmp_for_sort(void *i1, void *i2)
Definition: fib_entry.c:1499
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:1455
void * vl_msg_api_alloc(int nbytes)
u32 mfib_entry_get_fib_index(fib_node_index_t mfib_entry_index)
Definition: mfib_entry.c:1221
Definition: fib_entry.h:228
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:150
static int vl_api_ip6_mfib_table_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:594
Definition: fib_entry.h:232
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:183
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:154
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:739
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:1528
IP6 Multicast FIB table response.
Definition: ip.api:485
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:582
vl_api_fib_path_t path[count]
Definition: ip.api:121
#define REPLY_MACRO(t)
static int api_ip6nd_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:1578
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:280
fib_node_index_t * entries
Definition: ip_api.c:376
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:1177
static void vl_api_sw_interface_ip6_enable_disable_t_handler(vl_api_sw_interface_ip6_enable_disable_t *mp)
Definition: ip_api.c:1650
static void vl_api_set_ip_flow_hash_t_handler(vl_api_set_ip_flow_hash_t *mp)
Definition: ip_api.c:1483
static mfib_entry_t * mfib_entry_get(fib_node_index_t index)
Definition: mfib_entry.h:150
void stats_dsunlock(void)
API main structure, used by both vpp and binary API clients.
Definition: api_common.h:182
u32 fib_entry_get_resolving_interface(fib_node_index_t entry_index)
Definition: fib_entry.c:1353
#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.
#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:445
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:191
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
u32 ft_table_id
Table ID (hash key) for this FIB.
Definition: fib_table.h:50
vlib_main_t * vm
Definition: buffer.c:283
#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:155
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:835
struct vl_api_ip_fib_dump_walk_ctx_t_ vl_api_ip_fib_dump_walk_ctx_t
u8 * ft_desc
Table description.
Definition: fib_table.h:75
fib_node_index_t * entries
Definition: ip_api.c:590
#define clib_memcpy(a, b, c)
Definition: string.h:69
unix_shared_memory_queue_t * vl_api_client_index_to_input_queue(u32 index)
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:28
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:1444
#define pool_is_free_index(P, I)
Use free bitmap to query whether given index is free.
Definition: pool.h:267
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:179
u32 sw_if_index
Definition: ip.api:68
clib_error_t * enable_ip6_interface(vlib_main_t *vm, u32 sw_if_index)
Aggregrate type for a prefix.
Definition: mfib_types.h:24
enum fib_entry_flag_t_ fib_entry_flag_t
u32 fib_rpf_id_t
An RPF-ID is numerical value that is used RPF validate.
Definition: fib_types.h:315
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:72
#define foreach_flow_hash_bit
Definition: lookup.h:71
void vl_api_ip_mroute_add_del_t_handler(vl_api_ip_mroute_add_del_t *mp)
Definition: ip_api.c:1288
void vl_msg_api_send_shmem(unix_shared_memory_queue_t *q, u8 *elem)
IP neighbor add / del request.
Definition: ip.api:165
void mfib_entry_get_prefix(fib_node_index_t mfib_entry_index, mfib_prefix_t *pfx)
Definition: mfib_entry.c:1211
#define ASSERT(truth)
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:1243
IP Multicast FIB table response.
Definition: ip.api:455
ip6_address_t ip6_address
Definition: ip6_neighbor.h:26
ip6_main_t ip6_main
Definition: ip6_forward.c:3043
ip_lookup_main_t lookup_main
Definition: ip6.h:158
long ctx[MAX_CONNS]
Definition: main.c:95
index_t mfs_itf
Definition: mfib_signal.h:32
fib_node_index_t * entries
Definition: ip_api.c:494
static int vl_api_ip_mfib_table_dump_walk(fib_node_index_t fei, void *arg)
Definition: ip_api.c:498
static int ip4_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:998
FIB path.
Definition: ip.api:66
u8 frp_preference
A path preference.
Definition: fib_types.h:389
IPv6 router advertisement prefix config request.
Definition: ip.api:271
IPv6 ND proxy details returned after request.
Definition: ip.api:308
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:1463
An interface associated with a particular MFIB entry.
Definition: mfib_itf.h:25
IPv6 ND proxy dump request.
Definition: ip.api:322
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:1084
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:393
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:917
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:62
static void send_ip6_fib_details(vpe_api_main_t *am, unix_shared_memory_queue_t *q, u32 table_id, fib_prefix_t *pfx, fib_route_path_encode_t *api_rpaths, u32 context)
Definition: ip_api.c:309
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
static clib_error_t * ip_api_hookup(vlib_main_t *vm)
Definition: ip_api.c:1795
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:264
int vnet_set_ip6_flow_hash(u32 table_id, flow_hash_config_t flow_hash_config)
Definition: ip6_forward.c:3205
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:143
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:1534
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:181
void mfib_entry_encode(fib_node_index_t mfib_entry_index, fib_route_path_encode_t **api_rpaths)
Definition: mfib_entry.c:1192
mpls_label_t frp_local_label
The MPLS local Label to reursively resolve through.
Definition: fib_types.h:357
Add / del route request.
Definition: ip.api:381
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:1787
unsigned short u16
Definition: types.h:57
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:166
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
ip6_neighbor_key_t key
Definition: ip6_neighbor.h:40
A for-us/local path.
Definition: fib_types.h:284
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
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:295
#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:659
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:177
u32 next_hop_out_label_stack[next_hop_n_out_labels]
Definition: ip.api:409
u8 mfs_buffer[MFIB_SIGNAL_BUFFER_SIZE]
A buffer copied from the DP plane that triggered the signal.
Definition: mfib_signal.h:37
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:1493
u32 client_index
Definition: ip.api:523
u32 mfi_sw_if_index
The SW IF index that this MFIB interface represents.
Definition: mfib_itf.h:35
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, u32 fib_index, const fib_prefix_t *prefix, dpo_proto_t next_hop_proto, const ip46_address_t *next_hop, 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:759
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:1175
IP6 FIB table entry response.
Definition: ip.api:113
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:100
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:225
#define vec_foreach(var, vec)
Vector iterator.
fib_route_path_t rpath
Definition: fib_types.h:405
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:1134
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:1684
static void vl_api_ip_address_dump_t_handler(vl_api_ip_address_dump_t *mp)
Definition: ip_api.c:1351
ethernet_arp_ip4_entry_t * ip4_neighbor_entries(u32 sw_if_index)
Definition: arp.c:1296
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:1925
static void * ip_interface_address_get_address(ip_lookup_main_t *lm, ip_interface_address_t *a)
Definition: lookup.h:172
static void send_ip_neighbor_details(u8 is_ipv6, u8 is_static, u8 *mac_address, u8 *ip_address, unix_shared_memory_queue_t *q, u32 context)
Definition: ip_api.c:86
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:391
struct apt_ip6_fib_show_ctx_t_ api_ip6_fib_show_ctx_t
u16 fp_len
The mask length.
Definition: mfib_types.h:28
void vl_mfib_signal_send_one(unix_shared_memory_queue_t *q, u32 context, const mfib_signal_t *mfs)
Definition: ip_api.c:1715
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
Add / del route request.
Definition: ip.api:420
vpe_api_main_t vpe_api_main
Definition: interface_api.c:49
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:383
void vl_api_ip_add_del_route_t_handler(vl_api_ip_add_del_route_t *mp)
Definition: ip_api.c:1115
struct fib_table_t_ * fibs
Definition: ip6.h:161
Definition: dpo.h:94
u8 link_layer_address[8]
Definition: ip6_neighbor.h:41
#define foreach_ip_api_msg
Definition: ip_api.c:60
const ip46_address_t zero_addr
Definition: lookup.c:358
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:74
static void vl_api_ip6_fib_dump_t_handler(vl_api_ip6_fib_dump_t *mp)
Definition: ip_api.c:426
#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:250
IPv6 Proxy ND.
Definition: fib_entry.h:86
struct _unix_shared_memory_queue unix_shared_memory_queue_t
static void vl_api_ip_neighbor_dump_t_handler(vl_api_ip_neighbor_dump_t *mp)
Definition: ip_api.c:107
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128