FD.io VPP  v17.04-9-g99c0734
Vector Packet Processing
lookup.c
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2015 Cisco and/or its affiliates.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at:
6  *
7  * http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 /*
16  * ip/ip_lookup.c: ip4/6 adjacency and lookup table managment
17  *
18  * Copyright (c) 2008 Eliot Dresselhaus
19  *
20  * Permission is hereby granted, free of charge, to any person obtaining
21  * a copy of this software and associated documentation files (the
22  * "Software"), to deal in the Software without restriction, including
23  * without limitation the rights to use, copy, modify, merge, publish,
24  * distribute, sublicense, and/or sell copies of the Software, and to
25  * permit persons to whom the Software is furnished to do so, subject to
26  * the following conditions:
27  *
28  * The above copyright notice and this permission notice shall be
29  * included in all copies or substantial portions of the Software.
30  *
31  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
32  * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
33  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
34  * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
35  * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
36  * OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
37  * WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
38  */
39 
40 #include <vnet/ip/ip.h>
41 #include <vnet/adj/adj.h>
42 #include <vnet/fib/fib_table.h>
43 #include <vnet/fib/ip4_fib.h>
44 #include <vnet/fib/ip6_fib.h>
45 #include <vnet/mpls/mpls.h>
46 #include <vnet/mfib/mfib_table.h>
47 #include <vnet/dpo/drop_dpo.h>
48 #include <vnet/dpo/classify_dpo.h>
49 #include <vnet/dpo/punt_dpo.h>
50 #include <vnet/dpo/receive_dpo.h>
51 #include <vnet/dpo/ip_null_dpo.h>
52 #include <vnet/ip/ip6_neighbor.h>
53 
54 /**
55  * @file
56  * @brief IPv4 and IPv6 adjacency and lookup table managment.
57  *
58  */
59 
62  u32 sw_if_index,
63  void *addr_fib,
64  u32 address_length,
65  u32 is_del, u32 * result_if_address_index)
66 {
67  vnet_main_t *vnm = vnet_get_main ();
68  ip_interface_address_t *a, *prev, *next;
69  uword *p = mhash_get (&lm->address_to_if_address_index, addr_fib);
70 
72  sw_if_index, ~0);
73  a = p ? pool_elt_at_index (lm->if_address_pool, p[0]) : 0;
74 
75  /* Verify given length. */
76  if ((a && (address_length != a->address_length)) || (address_length == 0))
77  {
78  vnm->api_errno = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
79  return clib_error_create
80  ("%U wrong length (expected %d) for interface %U",
81  lm->format_address_and_length, addr_fib,
82  address_length, a ? a->address_length : -1,
83  format_vnet_sw_if_index_name, vnm, sw_if_index);
84  }
85 
86  if (is_del)
87  {
88  if (!a)
89  {
90  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
91  vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
92  return clib_error_create ("%U not found for interface %U",
94  addr_fib, address_length,
96  }
97 
98  if (a->prev_this_sw_interface != ~0)
99  {
100  prev =
104  }
105  if (a->next_this_sw_interface != ~0)
106  {
107  next =
111 
112  if (a->prev_this_sw_interface == ~0)
113  lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
115  }
116 
117  if ((a->next_this_sw_interface == ~0)
118  && (a->prev_this_sw_interface == ~0))
119  lm->if_address_pool_index_by_sw_if_index[sw_if_index] = ~0;
120 
122  /* old_value */ 0);
123  pool_put (lm->if_address_pool, a);
124 
125  if (result_if_address_index)
126  *result_if_address_index = ~0;
127  }
128 
129  else if (!a)
130  {
131  u32 pi; /* previous index */
132  u32 ai;
133  u32 hi; /* head index */
134 
135  pool_get (lm->if_address_pool, a);
136  memset (a, ~0, sizeof (a[0]));
137  ai = a - lm->if_address_pool;
138 
139  hi = pi = lm->if_address_pool_index_by_sw_if_index[sw_if_index];
140  prev = 0;
141  while (pi != (u32) ~ 0)
142  {
143  prev = pool_elt_at_index (lm->if_address_pool, pi);
144  pi = prev->next_this_sw_interface;
145  }
146  pi = prev ? prev - lm->if_address_pool : (u32) ~ 0;
147 
149  addr_fib, ai, /* old_value */ 0);
150  a->address_length = address_length;
151  a->sw_if_index = sw_if_index;
152  a->flags = 0;
153  a->prev_this_sw_interface = pi;
154  a->next_this_sw_interface = ~0;
155  if (prev)
156  prev->next_this_sw_interface = ai;
157 
158  lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
159  (hi != ~0) ? hi : ai;
160  if (result_if_address_index)
161  *result_if_address_index = ai;
162  }
163  else
164  {
165  if (result_if_address_index)
166  *result_if_address_index = a - lm->if_address_pool;
167  }
168 
169 
170  return /* no error */ 0;
171 }
172 
173 static clib_error_t *
174 ip_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
175 {
177  lookup_main.if_address_pool_index_by_sw_if_index,
178  sw_if_index, ~0);
180  lookup_main.if_address_pool_index_by_sw_if_index,
181  sw_if_index, ~0);
182 
183  return (NULL);
184 }
185 
187 
188 void
190 {
191  /* ensure that adjacency is cacheline aligned and sized */
192  STATIC_ASSERT (STRUCT_OFFSET_OF (ip_adjacency_t, cacheline0) == 0,
193  "Cache line marker must be 1st element in struct");
196  "Data in cache line 0 is bigger than cache line size");
197 
198  /* Preallocate three "special" adjacencies */
199  lm->adjacency_heap = adj_pool;
200 
201  if (!lm->fib_result_n_bytes)
202  lm->fib_result_n_bytes = sizeof (uword);
203 
204  lm->is_ip6 = is_ip6;
205  if (is_ip6)
206  {
209  sizeof (ip6_address_fib_t));
210  }
211  else
212  {
215  sizeof (ip4_address_fib_t));
216  }
217 
218  {
219  int i;
220 
221  /* Setup all IP protocols to be punted and builtin-unknown. */
222  for (i = 0; i < 256; i++)
223  {
226  }
227 
229  lm->local_next_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
230  IP_PROTOCOL_ICMP] = IP_LOCAL_NEXT_ICMP;
231  lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] =
233  lm->builtin_protocol_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
234  IP_PROTOCOL_ICMP] =
236  }
237 }
238 
239 u8 *
240 format_ip_flow_hash_config (u8 * s, va_list * args)
241 {
242  flow_hash_config_t flow_hash_config = va_arg (*args, u32);
243 
244 #define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n);
246 #undef _
247 
248  return s;
249 }
250 
251 u8 *
252 format_ip_lookup_next (u8 * s, va_list * args)
253 {
254  ip_lookup_next_t n = va_arg (*args, ip_lookup_next_t);
255  char *t = 0;
256 
257  switch (n)
258  {
259  default:
260  s = format (s, "unknown %d", n);
261  return s;
262 
263  case IP_LOOKUP_NEXT_DROP:
264  t = "drop";
265  break;
266  case IP_LOOKUP_NEXT_PUNT:
267  t = "punt";
268  break;
269  case IP_LOOKUP_NEXT_ARP:
270  t = "arp";
271  break;
273  t = "midchain";
274  break;
276  t = "glean";
277  break;
279  t = "mcast";
280  break;
282  break;
283  }
284 
285  if (t)
286  vec_add (s, t, strlen (t));
287 
288  return s;
289 }
290 
291 u8 *
292 format_ip_adjacency_packet_data (u8 * s, va_list * args)
293 {
294  u32 adj_index = va_arg (*args, u32);
295  u8 *packet_data = va_arg (*args, u8 *);
296  u32 n_packet_data_bytes = va_arg (*args, u32);
297  ip_adjacency_t *adj = adj_get (adj_index);
298 
299  switch (adj->lookup_next_index)
300  {
303  s =
304  format (s, "%U", format_hex_bytes, packet_data, n_packet_data_bytes);
305  break;
306 
307  default:
308  break;
309  }
310 
311  return s;
312 }
313 
314 static uword
315 unformat_dpo (unformat_input_t * input, va_list * args)
316 {
317  dpo_id_t *dpo = va_arg (*args, dpo_id_t *);
318  fib_protocol_t fp = va_arg (*args, int);
319  dpo_proto_t proto;
320 
321  proto = fib_proto_to_dpo (fp);
322 
323  if (unformat (input, "drop"))
324  dpo_copy (dpo, drop_dpo_get (proto));
325  else if (unformat (input, "punt"))
326  dpo_copy (dpo, punt_dpo_get (proto));
327  else if (unformat (input, "local"))
328  receive_dpo_add_or_lock (proto, ~0, NULL, dpo);
329  else if (unformat (input, "null-send-unreach"))
331  else if (unformat (input, "null-send-prohibit"))
333  else if (unformat (input, "null"))
335  else if (unformat (input, "classify"))
336  {
337  u32 classify_table_index;
338 
339  if (!unformat (input, "%d", &classify_table_index))
340  {
341  clib_warning ("classify adj must specify table index");
342  return 0;
343  }
344 
345  dpo_set (dpo, DPO_CLASSIFY, proto,
346  classify_dpo_create (proto, classify_table_index));
347  }
348  else
349  return 0;
350 
351  return 1;
352 }
353 
354 const ip46_address_t zero_addr = {
355  .as_u64 = {
356  0, 0},
357 };
358 
359 u32
361 {
362  ip4_main_t *im4 = &ip4_main;
363  ip6_main_t *im6 = &ip6_main;
364  uword *p;
365 
366  switch (proto)
367  {
368  case FIB_PROTOCOL_IP4:
369  p = hash_get (im4->fib_index_by_table_id, table_id);
370  break;
371  case FIB_PROTOCOL_IP6:
372  p = hash_get (im6->fib_index_by_table_id, table_id);
373  break;
374  default:
375  p = NULL;
376  break;
377  }
378  if (NULL != p)
379  {
380  return (p[0]);
381  }
382  return (~0);
383 }
384 
385 clib_error_t *
387  unformat_input_t * main_input, vlib_cli_command_t * cmd)
388 {
389  unformat_input_t _line_input, *line_input = &_line_input;
390  fib_route_path_t *rpaths = NULL, rpath;
391  dpo_id_t dpo = DPO_INVALID, *dpos = NULL;
392  fib_prefix_t *prefixs = NULL, pfx;
393  mpls_label_t out_label, via_label;
394  clib_error_t *error = NULL;
395  u32 table_id, is_del;
396  vnet_main_t *vnm;
397  u32 fib_index;
398  f64 count;
399  int i;
400 
401  vnm = vnet_get_main ();
402  is_del = 0;
403  table_id = 0;
404  count = 1;
405  memset (&pfx, 0, sizeof (pfx));
406  out_label = via_label = MPLS_LABEL_INVALID;
407 
408  /* Get a line of input. */
409  if (!unformat_user (main_input, unformat_line_input, line_input))
410  return 0;
411 
412  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
413  {
414  memset (&rpath, 0, sizeof (rpath));
415 
416  if (unformat (line_input, "table %d", &table_id))
417  ;
418  else if (unformat (line_input, "del"))
419  is_del = 1;
420  else if (unformat (line_input, "add"))
421  is_del = 0;
422  else if (unformat (line_input, "resolve-via-host"))
423  {
424  if (vec_len (rpaths) == 0)
425  {
426  error = clib_error_return (0, "Paths then flags");
427  goto done;
428  }
429  rpaths[vec_len (rpaths) - 1].frp_flags |=
431  }
432  else if (unformat (line_input, "resolve-via-attached"))
433  {
434  if (vec_len (rpaths) == 0)
435  {
436  error = clib_error_return (0, "Paths then flags");
437  goto done;
438  }
439  rpaths[vec_len (rpaths) - 1].frp_flags |=
441  }
442  else if (unformat (line_input, "out-label %U",
443  unformat_mpls_unicast_label, &out_label))
444  {
445  if (vec_len (rpaths) == 0)
446  {
447  error = clib_error_return (0, "Paths then labels");
448  goto done;
449  }
450  vec_add1 (rpaths[vec_len (rpaths) - 1].frp_label_stack, out_label);
451  }
452  else if (unformat (line_input, "via-label %U",
453  unformat_mpls_unicast_label, &rpath.frp_local_label))
454  {
455  rpath.frp_weight = 1;
456  rpath.frp_proto = FIB_PROTOCOL_MPLS;
457  rpath.frp_sw_if_index = ~0;
458  vec_add1 (rpaths, rpath);
459  }
460  else if (unformat (line_input, "count %f", &count))
461  ;
462 
463  else if (unformat (line_input, "%U/%d",
464  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
465  {
466  pfx.fp_proto = FIB_PROTOCOL_IP4;
467  vec_add1 (prefixs, pfx);
468  }
469  else if (unformat (line_input, "%U/%d",
470  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
471  {
472  pfx.fp_proto = FIB_PROTOCOL_IP6;
473  vec_add1 (prefixs, pfx);
474  }
475  else if (unformat (line_input, "via %U %U weight %u",
477  &rpath.frp_addr.ip4,
479  &rpath.frp_sw_if_index, &rpath.frp_weight))
480  {
481  rpath.frp_proto = FIB_PROTOCOL_IP4;
482  vec_add1 (rpaths, rpath);
483  }
484 
485  else if (unformat (line_input, "via %U %U weight %u",
487  &rpath.frp_addr.ip6,
489  &rpath.frp_sw_if_index, &rpath.frp_weight))
490  {
491  rpath.frp_proto = FIB_PROTOCOL_IP6;
492  vec_add1 (rpaths, rpath);
493  }
494 
495  else if (unformat (line_input, "via %U %U",
497  &rpath.frp_addr.ip4,
499  &rpath.frp_sw_if_index))
500  {
501  rpath.frp_weight = 1;
502  rpath.frp_proto = FIB_PROTOCOL_IP4;
503  vec_add1 (rpaths, rpath);
504  }
505 
506  else if (unformat (line_input, "via %U %U",
508  &rpath.frp_addr.ip6,
510  &rpath.frp_sw_if_index))
511  {
512  rpath.frp_weight = 1;
513  rpath.frp_proto = FIB_PROTOCOL_IP6;
514  vec_add1 (rpaths, rpath);
515  }
516  else if (unformat (line_input, "via %U next-hop-table %d",
518  &rpath.frp_addr.ip4, &rpath.frp_fib_index))
519  {
520  rpath.frp_weight = 1;
521  rpath.frp_sw_if_index = ~0;
522  rpath.frp_proto = FIB_PROTOCOL_IP4;
523  vec_add1 (rpaths, rpath);
524  }
525  else if (unformat (line_input, "via %U next-hop-table %d",
527  &rpath.frp_addr.ip6, &rpath.frp_fib_index))
528  {
529  rpath.frp_weight = 1;
530  rpath.frp_sw_if_index = ~0;
531  rpath.frp_proto = FIB_PROTOCOL_IP6;
532  vec_add1 (rpaths, rpath);
533  }
534  else if (unformat (line_input, "via %U",
535  unformat_ip4_address, &rpath.frp_addr.ip4))
536  {
537  /*
538  * the recursive next-hops are by default in the same table
539  * as the prefix
540  */
541  rpath.frp_fib_index = table_id;
542  rpath.frp_weight = 1;
543  rpath.frp_sw_if_index = ~0;
544  rpath.frp_proto = FIB_PROTOCOL_IP4;
545  vec_add1 (rpaths, rpath);
546  }
547  else if (unformat (line_input, "via %U",
548  unformat_ip6_address, &rpath.frp_addr.ip6))
549  {
550  rpath.frp_fib_index = table_id;
551  rpath.frp_weight = 1;
552  rpath.frp_sw_if_index = ~0;
553  rpath.frp_proto = FIB_PROTOCOL_IP6;
554  vec_add1 (rpaths, rpath);
555  }
556  else if (unformat (line_input,
557  "lookup in table %d", &rpath.frp_fib_index))
558  {
559  rpath.frp_proto = pfx.fp_proto;
560  rpath.frp_sw_if_index = ~0;
561  vec_add1 (rpaths, rpath);
562  }
563  else if (vec_len (prefixs) > 0 &&
564  unformat (line_input, "via %U",
566  &rpath.frp_sw_if_index))
567  {
568  rpath.frp_weight = 1;
569  rpath.frp_proto = prefixs[0].fp_proto;
570  vec_add1 (rpaths, rpath);
571  }
572  else if (vec_len (prefixs) > 0 &&
573  unformat (line_input, "via %U",
574  unformat_dpo, &dpo, prefixs[0].fp_proto))
575  {
576  vec_add1 (dpos, dpo);
577  }
578  else
579  {
580  error = unformat_parse_error (line_input);
581  goto done;
582  }
583  }
584 
585  if (vec_len (prefixs) == 0)
586  {
587  error =
588  clib_error_return (0, "expected ip4/ip6 destination address/length.");
589  goto done;
590  }
591 
592  if (!is_del && vec_len (rpaths) + vec_len (dpos) == 0)
593  {
594  error = clib_error_return (0, "expected paths.");
595  goto done;
596  }
597 
598  if (~0 == table_id)
599  {
600  /*
601  * if no table_id is passed we will manipulate the default
602  */
603  fib_index = 0;
604  }
605  else
606  {
607  fib_index = fib_table_id_find_fib_index (prefixs[0].fp_proto, table_id);
608 
609  if (~0 == fib_index)
610  {
611  error = clib_error_return (0, "Nonexistent table id %d", table_id);
612  goto done;
613  }
614  }
615 
616  for (i = 0; i < vec_len (prefixs); i++)
617  {
618  if (is_del && 0 == vec_len (rpaths))
619  {
620  fib_table_entry_delete (fib_index, &prefixs[i], FIB_SOURCE_CLI);
621  }
622  else if (!is_del && 1 == vec_len (dpos))
623  {
625  &prefixs[i],
628  &dpos[0]);
629  dpo_reset (&dpos[0]);
630  }
631  else if (vec_len (dpos) > 0)
632  {
633  error =
635  "Load-balancing over multiple special adjacencies is unsupported");
636  goto done;
637  }
638  else if (0 < vec_len (rpaths))
639  {
640  u32 k, j, n, incr;
641  ip46_address_t dst = prefixs[i].fp_addr;
642  f64 t[2];
643  n = count;
644  t[0] = vlib_time_now (vm);
645  incr = 1 << ((FIB_PROTOCOL_IP4 == prefixs[0].fp_proto ? 32 : 128) -
646  prefixs[i].fp_len);
647 
648  for (k = 0; k < n; k++)
649  {
650  for (j = 0; j < vec_len (rpaths); j++)
651  {
652  u32 fi;
653  /*
654  * the CLI parsing stored table Ids, swap to FIB indicies
655  */
656  fi = fib_table_id_find_fib_index (prefixs[i].fp_proto,
657  rpaths[i].frp_fib_index);
658 
659  if (~0 == fi)
660  {
661  error =
662  clib_error_return (0, "Via table %d does not exist",
663  rpaths[i].frp_fib_index);
664  goto done;
665  }
666  rpaths[i].frp_fib_index = fi;
667 
668  fib_prefix_t rpfx = {
669  .fp_len = prefixs[i].fp_len,
670  .fp_proto = prefixs[i].fp_proto,
671  .fp_addr = dst,
672  };
673 
674  if (is_del)
675  fib_table_entry_path_remove2 (fib_index,
676  &rpfx,
677  FIB_SOURCE_CLI, &rpaths[j]);
678  else
679  fib_table_entry_path_add2 (fib_index,
680  &rpfx,
683  &rpaths[j]);
684  }
685 
686  if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto)
687  {
688  dst.ip4.as_u32 =
689  clib_host_to_net_u32 (incr +
690  clib_net_to_host_u32 (dst.
691  ip4.as_u32));
692  }
693  else
694  {
695  int bucket = (incr < 64 ? 0 : 1);
696  dst.ip6.as_u64[bucket] =
697  clib_host_to_net_u64 (incr +
698  clib_net_to_host_u64 (dst.ip6.as_u64
699  [bucket]));
700 
701  }
702  }
703  t[1] = vlib_time_now (vm);
704  if (count > 1)
705  vlib_cli_output (vm, "%.6e routes/sec", count / (t[1] - t[0]));
706  }
707  else
708  {
709  error = clib_error_return (0, "Don't understand what you want...");
710  goto done;
711  }
712  }
713 
714 
715 done:
716  vec_free (dpos);
717  vec_free (prefixs);
718  vec_free (rpaths);
719  unformat_free (line_input);
720  return error;
721 }
722 
723 /* *INDENT-OFF* */
724 VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = {
725  .path = "ip",
726  .short_help = "Internet protocol (IP) commands",
727 };
728 /* *INDENT-ON* */
729 
730 /* *INDENT-OFF* */
731 VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = {
732  .path = "ip6",
733  .short_help = "Internet protocol version 6 (IPv6) commands",
734 };
735 /* *INDENT-ON* */
736 
737 /* *INDENT-OFF* */
738 VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = {
739  .path = "show ip",
740  .short_help = "Internet protocol (IP) show commands",
741 };
742 /* *INDENT-ON* */
743 
744 /* *INDENT-OFF* */
745 VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
746  .path = "show ip6",
747  .short_help = "Internet protocol version 6 (IPv6) show commands",
748 };
749 /* *INDENT-ON* */
750 
751 /*?
752  * This command is used to add or delete IPv4 or IPv6 routes. All
753  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
754  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
755  * can be IPv4 or IPv6, but all must be of the same form in a single
756  * command. To display the current set of routes, use the commands
757  * '<em>show ip fib</em>' and '<em>show ip6 fib</em>'.
758  *
759  * @cliexpar
760  * Example of how to add a straight forward static route:
761  * @cliexcmd{ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
762  * Example of how to delete a straight forward static route:
763  * @cliexcmd{ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
764  * Mainly for route add/del performance testing, one can add or delete
765  * multiple routes by adding 'count N' to the previous item:
766  * @cliexcmd{ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0}
767  * Add multiple routes for the same destination to create equal-cost multipath:
768  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0}
769  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0}
770  * For unequal-cost multipath, specify the desired weights. This
771  * combination of weights results in 3/4 of the traffic following the
772  * second path, 1/4 following the first path:
773  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1}
774  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3}
775  * To add a route to a particular FIB table (VRF), use:
776  * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0}
777  ?*/
778 /* *INDENT-OFF* */
779 VLIB_CLI_COMMAND (ip_route_command, static) = {
780  .path = "ip route",
781  .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table <table-id>] [via <next-hop-ip-addr> [<interface>] [weight <weight>]] | [via arp <interface> <adj-hop-ip-addr>] | [via drop|punt|local<id>|arp|classify <classify-idx>] [lookup in table <out-table-id>]",
782  .function = vnet_ip_route_cmd,
783  .is_mp_safe = 1,
784 };
785 /* *INDENT-ON* */
786 
787 clib_error_t *
789  unformat_input_t * main_input, vlib_cli_command_t * cmd)
790 {
791  unformat_input_t _line_input, *line_input = &_line_input;
792  clib_error_t *error = NULL;
793  fib_route_path_t rpath;
794  u32 table_id, is_del;
795  vnet_main_t *vnm;
796  mfib_prefix_t pfx;
797  u32 fib_index;
798  mfib_itf_flags_t iflags = 0;
799  mfib_entry_flags_t eflags = 0;
800  u32 gcount, scount, ss, gg, incr;
801  f64 timet[2];
802 
803  gcount = scount = 1;
804  vnm = vnet_get_main ();
805  is_del = 0;
806  table_id = 0;
807  memset (&pfx, 0, sizeof (pfx));
808  memset (&rpath, 0, sizeof (rpath));
809  rpath.frp_sw_if_index = ~0;
810 
811  /* Get a line of input. */
812  if (!unformat_user (main_input, unformat_line_input, line_input))
813  return 0;
814 
815  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
816  {
817  if (unformat (line_input, "table %d", &table_id))
818  ;
819  else if (unformat (line_input, "del"))
820  is_del = 1;
821  else if (unformat (line_input, "add"))
822  is_del = 0;
823  else if (unformat (line_input, "scount %d", &scount))
824  ;
825  else if (unformat (line_input, "gcount %d", &gcount))
826  ;
827  else if (unformat (line_input, "%U %U",
829  &pfx.fp_src_addr.ip4,
831  {
833  pfx.fp_len = 64;
834  }
835  else if (unformat (line_input, "%U %U",
837  &pfx.fp_src_addr.ip6,
839  {
841  pfx.fp_len = 256;
842  }
843  else if (unformat (line_input, "%U/%d",
845  &pfx.fp_grp_addr.ip4, &pfx.fp_len))
846  {
848  }
849  else if (unformat (line_input, "%U/%d",
851  &pfx.fp_grp_addr.ip6, &pfx.fp_len))
852  {
854  }
855  else if (unformat (line_input, "%U",
857  {
858  memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
860  pfx.fp_len = 32;
861  }
862  else if (unformat (line_input, "%U",
864  {
865  memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
867  pfx.fp_len = 128;
868  }
869  else if (unformat (line_input, "via %U",
871  &rpath.frp_sw_if_index))
872  {
873  rpath.frp_weight = 1;
874  rpath.frp_proto = FIB_PROTOCOL_IP4;
875  }
876  else if (unformat (line_input, "%U", unformat_mfib_itf_flags, &iflags))
877  ;
878  else if (unformat (line_input, "%U",
879  unformat_mfib_entry_flags, &eflags))
880  ;
881  else
882  {
883  error = unformat_parse_error (line_input);
884  goto done;
885  }
886  }
887 
888  if (~0 == table_id)
889  {
890  /*
891  * if no table_id is passed we will manipulate the default
892  */
893  fib_index = 0;
894  }
895  else
896  {
897  fib_index = mfib_table_find (pfx.fp_proto, table_id);
898 
899  if (~0 == fib_index)
900  {
901  error = clib_error_return (0, "Nonexistent table id %d", table_id);
902  goto done;
903  }
904  }
905 
906  timet[0] = vlib_time_now (vm);
907 
908  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
909  {
910  incr = 1 << (32 - (pfx.fp_len % 32));
911  }
912  else
913  {
914  incr = 1 << (128 - (pfx.fp_len % 128));
915  }
916 
917  for (ss = 0; ss < scount; ss++)
918  {
919  for (gg = 0; gg < gcount; gg++)
920  {
921  if (is_del && 0 == rpath.frp_weight)
922  {
923  /* no path provided => route delete */
924  mfib_table_entry_delete (fib_index, &pfx, MFIB_SOURCE_CLI);
925  }
926  else if (eflags)
927  {
928  mfib_table_entry_update (fib_index, &pfx, MFIB_SOURCE_CLI,
929  eflags);
930  }
931  else
932  {
933  if (is_del)
934  mfib_table_entry_path_remove (fib_index,
935  &pfx, MFIB_SOURCE_CLI, &rpath);
936  else
937  mfib_table_entry_path_update (fib_index,
938  &pfx, MFIB_SOURCE_CLI, &rpath,
939  iflags);
940  }
941 
942  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
943  {
944  pfx.fp_grp_addr.ip4.as_u32 =
945  clib_host_to_net_u32 (incr +
946  clib_net_to_host_u32 (pfx.
947  fp_grp_addr.ip4.
948  as_u32));
949  }
950  else
951  {
952  int bucket = (incr < 64 ? 0 : 1);
953  pfx.fp_grp_addr.ip6.as_u64[bucket] =
954  clib_host_to_net_u64 (incr +
955  clib_net_to_host_u64 (pfx.
956  fp_grp_addr.ip6.as_u64
957  [bucket]));
958 
959  }
960  }
961  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
962  {
963  pfx.fp_src_addr.ip4.as_u32 =
964  clib_host_to_net_u32 (1 +
965  clib_net_to_host_u32 (pfx.fp_src_addr.
966  ip4.as_u32));
967  }
968  else
969  {
970  pfx.fp_src_addr.ip6.as_u64[1] =
971  clib_host_to_net_u64 (1 +
972  clib_net_to_host_u64 (pfx.fp_src_addr.
973  ip6.as_u64[1]));
974  }
975  }
976 
977  timet[1] = vlib_time_now (vm);
978 
979  if (scount > 1 || gcount > 1)
980  vlib_cli_output (vm, "%.6e routes/sec",
981  (scount * gcount) / (timet[1] - timet[0]));
982 
983 done:
984  unformat_free (line_input);
985 
986  return error;
987 }
988 
989 /*?
990  * This command is used to add or delete IPv4 or IPv6 multicastroutes. All
991  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
992  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
993  * can be IPv4 or IPv6, but all must be of the same form in a single
994  * command. To display the current set of routes, use the commands
995  * '<em>show ip mfib</em>' and '<em>show ip6 mfib</em>'.
996  * The full set of support flags for interfaces and route is shown via;
997  * '<em>show mfib route flags</em>' and '<em>show mfib itf flags</em>'
998  * respectively.
999  * @cliexpar
1000  * Example of how to add a forwarding interface to a route (and create the
1001  * route if it does not exist)
1002  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/0 Forward}
1003  * Example of how to add an accepting interface to a route (and create the
1004  * route if it does not exist)
1005  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/1 Accept}
1006  * Example of changing the route's flags to send signals via the API
1007  * @cliexcmd{ip mroute add 232.1.1.1 Signal}
1008 
1009  ?*/
1010 /* *INDENT-OFF* */
1011 VLIB_CLI_COMMAND (ip_mroute_command, static) =
1012 {
1013  .path = "ip mroute",
1014  .short_help = "ip mroute [add|del] <dst-ip-addr>/<width> [table <table-id>] [via <next-hop-ip-addr> [<interface>],",
1015  .function = vnet_ip_mroute_cmd,
1016  .is_mp_safe = 1,
1017 };
1018 /* *INDENT-ON* */
1019 
1020 /*
1021  * The next two routines address a longstanding script hemorrhoid.
1022  * Probing a v4 or v6 neighbor needs to appear to be synchronous,
1023  * or dependent route-adds will simply fail.
1024  */
1025 static clib_error_t *
1027  int retry_count)
1028 {
1029  vnet_main_t *vnm = vnet_get_main ();
1030  clib_error_t *e;
1031  int i;
1032  int resolved = 0;
1033  uword event_type;
1034  uword *event_data = 0;
1035 
1037 
1038  if (retry_count > 0)
1040  (vnm, a, vlib_get_current_process (vm)->node_runtime.node_index,
1041  1 /* event */ , 0 /* data */ );
1042 
1043  for (i = 0; i < retry_count; i++)
1044  {
1045  /* The interface may be down, etc. */
1046  e = ip6_probe_neighbor (vm, a, sw_if_index);
1047 
1048  if (e)
1049  return e;
1050 
1052  event_type = vlib_process_get_events (vm, &event_data);
1053  switch (event_type)
1054  {
1055  case 1: /* resolved... */
1056  vlib_cli_output (vm, "Resolved %U", format_ip6_address, a);
1057  resolved = 1;
1058  goto done;
1059 
1060  case ~0: /* timeout */
1061  break;
1062 
1063  default:
1064  clib_warning ("unknown event_type %d", event_type);
1065  }
1066  vec_reset_length (event_data);
1067  }
1068 
1069 done:
1070 
1071  if (!resolved)
1072  return clib_error_return (0, "Resolution failed for %U",
1073  format_ip6_address, a);
1074  return 0;
1075 }
1076 
1077 static clib_error_t *
1079  int retry_count)
1080 {
1081  vnet_main_t *vnm = vnet_get_main ();
1082  clib_error_t *e;
1083  int i;
1084  int resolved = 0;
1085  uword event_type;
1086  uword *event_data = 0;
1087 
1089 
1090  if (retry_count > 0)
1092  (vnm, a, vlib_get_current_process (vm)->node_runtime.node_index,
1093  1 /* event */ , 0 /* data */ );
1094 
1095  for (i = 0; i < retry_count; i++)
1096  {
1097  /* The interface may be down, etc. */
1098  e = ip4_probe_neighbor (vm, a, sw_if_index);
1099 
1100  if (e)
1101  return e;
1102 
1104  event_type = vlib_process_get_events (vm, &event_data);
1105  switch (event_type)
1106  {
1107  case 1: /* resolved... */
1108  vlib_cli_output (vm, "Resolved %U", format_ip4_address, a);
1109  resolved = 1;
1110  goto done;
1111 
1112  case ~0: /* timeout */
1113  break;
1114 
1115  default:
1116  clib_warning ("unknown event_type %d", event_type);
1117  }
1118  vec_reset_length (event_data);
1119  }
1120 
1121 done:
1122 
1123  vec_reset_length (event_data);
1124 
1125  if (!resolved)
1126  return clib_error_return (0, "Resolution failed for %U",
1127  format_ip4_address, a);
1128  return 0;
1129 }
1130 
1131 static clib_error_t *
1133  unformat_input_t * input, vlib_cli_command_t * cmd)
1134 {
1135  vnet_main_t *vnm = vnet_get_main ();
1136  unformat_input_t _line_input, *line_input = &_line_input;
1137  ip4_address_t a4;
1138  ip6_address_t a6;
1139  clib_error_t *error = 0;
1140  u32 sw_if_index = ~0;
1141  int retry_count = 3;
1142  int is_ip4 = 1;
1143  int address_set = 0;
1144 
1145  /* Get a line of input. */
1146  if (!unformat_user (input, unformat_line_input, line_input))
1147  return 0;
1148 
1149  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1150  {
1151  if (unformat_user (line_input, unformat_vnet_sw_interface, vnm,
1152  &sw_if_index))
1153  ;
1154  else if (unformat (line_input, "retry %d", &retry_count))
1155  ;
1156 
1157  else if (unformat (line_input, "%U", unformat_ip4_address, &a4))
1158  address_set++;
1159  else if (unformat (line_input, "%U", unformat_ip6_address, &a6))
1160  {
1161  address_set++;
1162  is_ip4 = 0;
1163  }
1164  else
1165  {
1166  error = clib_error_return (0, "unknown input '%U'",
1167  format_unformat_error, line_input);
1168  goto done;
1169  }
1170  }
1171 
1172  if (sw_if_index == ~0)
1173  {
1174  error = clib_error_return (0, "Interface required, not set.");
1175  goto done;
1176  }
1177  if (address_set == 0)
1178  {
1179  error = clib_error_return (0, "ip address required, not set.");
1180  goto done;
1181  }
1182  if (address_set > 1)
1183  {
1184  error = clib_error_return (0, "Multiple ip addresses not supported.");
1185  goto done;
1186  }
1187 
1188  if (is_ip4)
1189  error = ip4_probe_neighbor_wait (vm, &a4, sw_if_index, retry_count);
1190  else
1191  error = ip6_probe_neighbor_wait (vm, &a6, sw_if_index, retry_count);
1192 
1193 done:
1194  unformat_free (line_input);
1195 
1196  return error;
1197 }
1198 
1199 /*?
1200  * The '<em>ip probe-neighbor</em>' command ARPs for IPv4 addresses or
1201  * attempts IPv6 neighbor discovery depending on the supplied IP address
1202  * format.
1203  *
1204  * @note This command will not immediately affect the indicated FIB; it
1205  * is not suitable for use in establishing a FIB entry prior to adding
1206  * recursive FIB entries. As in: don't use it in a script to probe a
1207  * gateway prior to adding a default route. It won't work. Instead,
1208  * configure a static ARP cache entry [see '<em>set ip arp</em>'], or
1209  * a static IPv6 neighbor [see '<em>set ip6 neighbor</em>'].
1210  *
1211  * @cliexpar
1212  * Example of probe for an IPv4 address:
1213  * @cliexcmd{ip probe-neighbor GigabitEthernet2/0/0 172.16.1.2}
1214 ?*/
1215 /* *INDENT-OFF* */
1216 VLIB_CLI_COMMAND (ip_probe_neighbor_command, static) = {
1217  .path = "ip probe-neighbor",
1218  .function = probe_neighbor_address,
1219  .short_help = "ip probe-neighbor <interface> <ip4-addr> | <ip6-addr> [retry nn]",
1220  .is_mp_safe = 1,
1221 };
1222 /* *INDENT-ON* */
1223 
1224 /*
1225  * fd.io coding-style-patch-verification: ON
1226  *
1227  * Local Variables:
1228  * eval: (c-set-style "gnu")
1229  * End:
1230  */
static clib_error_t * ip6_probe_neighbor_wait(vlib_main_t *vm, ip6_address_t *a, u32 sw_if_index, int retry_count)
Definition: lookup.c:1026
u32 fib_table_id_find_fib_index(fib_protocol_t proto, u32 table_id)
Definition: lookup.c:360
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:169
ip_lookup_next_t
Common (IP4/IP6) next index stored in adjacency.
Definition: lookup.h:60
void mfib_table_entry_delete(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source)
Delete a FIB entry.
Definition: mfib_table.c:350
vmrglw vmrglh hi
fib_protocol_t frp_proto
The protocol of the address below.
Definition: fib_types.h:313
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 fp_src_addr
Definition: mfib_types.h:47
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
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
ip_adjacency_t * adj_pool
The global adjacnecy pool.
Definition: adj.c:36
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:683
enum mfib_entry_flags_t_ mfib_entry_flags_t
ip_adjacency_t * adjacency_heap
Definition: lookup.h:331
a
Definition: bitmap.h:516
static uword unformat_dpo(unformat_input_t *input, va_list *args)
Definition: lookup.c:315
A representation of a path as described by a route producer.
Definition: fib_types.h:308
uword unformat_mfib_itf_flags(unformat_input_t *input, va_list *args)
Definition: mfib_types.c:122
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:337
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
static clib_error_t * ip4_probe_neighbor_wait(vlib_main_t *vm, ip4_address_t *a, u32 sw_if_index, int retry_count)
Definition: lookup.c:1078
#define NULL
Definition: clib.h:55
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:353
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:185
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:511
IP unicast adjacency.
Definition: lookup.h:193
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
From the CLI.
Definition: fib_entry.h:62
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:224
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:522
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:982
#define STRUCT_OFFSET_OF(t, f)
Definition: clib.h:62
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:418
unformat_function_t unformat_vnet_sw_interface
#define pool_get(P, E)
Allocate an object E from a pool P (unspecified alignment).
Definition: pool.h:200
Multicast Adjacency.
Definition: lookup.h:95
mhash_t address_to_if_address_index
Hash table mapping address to index in interface address pool.
Definition: lookup.h:340
format_function_t format_vnet_sw_if_index_name
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
clib_error_t * vnet_ip_route_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:386
unformat_function_t unformat_mpls_unicast_label
Definition: mpls.h:103
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
Adjacency to drop this packet.
Definition: lookup.h:63
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:599
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
u8 * format_ip_lookup_next(u8 *s, va_list *args)
Definition: lookup.c:252
format_function_t format_ip4_address
Definition: format.h:79
static ip_adjacency_t * adj_get(adj_index_t adj_index)
Get a pointer to an adjacency object from its index.
Definition: adj.h:128
unformat_function_t unformat_ip4_address
Definition: format.h:76
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:334
format_function_t format_ip6_address_and_length
Definition: format.h:96
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:526
Recursion constraint of via a host prefix.
Definition: fib_types.h:276
fib_node_index_t mfib_table_entry_update(u32 fib_index, const mfib_prefix_t *prefix, mfib_source_t source, mfib_entry_flags_t entry_flags)
Add a new (with no replication) or lock an existing entry.
Definition: mfib_table.c:165
Aggregrate type for a prefix.
Definition: fib_types.h:160
u8 * format_hex_bytes(u8 *s, va_list *va)
Definition: std-formats.c:84
const dpo_id_t * punt_dpo_get(dpo_proto_t proto)
Definition: punt_dpo.c:25
Adjacency to punt this packet.
Definition: lookup.h:65
#define clib_error_return(e, args...)
Definition: error.h:111
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:216
#define clib_error_create(args...)
Definition: error.h:108
enum dpo_proto_t_ dpo_proto_t
Data path protocol.
u16 fp_len
The mask length.
Definition: fib_types.h:164
This packet matches an "interface route" and packets need to be passed to ARP to find rewrite string ...
Definition: lookup.h:78
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index)
Definition: ip6_forward.c:1807
Definition: fib_entry.h:227
unformat_function_t unformat_line_input
Definition: format.h:281
clib_error_t * ip4_probe_neighbor(vlib_main_t *vm, ip4_address_t *dst, u32 sw_if_index)
Definition: ip4_forward.c:2246
vnet_api_error_t api_errno
Definition: vnet.h:77
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:146
#define hash_get(h, key)
Definition: hash.h:248
format_function_t format_vnet_sw_interface_name
Definition: fib_entry.h:231
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
uword * fib_index_by_table_id
Hash table mapping table id to fib index.
Definition: ip4.h:130
void vnet_register_ip6_neighbor_resolution_event(vnet_main_t *vnm, void *address_arg, uword node_index, uword type_opaque, uword data)
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
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:241
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:555
u8 local_next_by_ip_protocol[256]
Table mapping ip protocol to ip[46]-local node next index.
Definition: lookup.h:370
Recursion constraint of via an attahced prefix.
Definition: fib_types.h:280
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
uword * fib_index_by_table_id
Definition: ip6.h:173
clib_error_t * vnet_ip_mroute_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:788
unformat_function_t unformat_ip6_address
Definition: format.h:94
uword unformat_mfib_entry_flags(unformat_input_t *input, va_list *args)
Definition: mfib_types.c:142
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
format_function_t format_ip6_address
Definition: format.h:95
static vlib_process_t * vlib_get_current_process(vlib_main_t *vm)
Definition: node_funcs.h:397
vlib_main_t * vm
Definition: buffer.c:276
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:33
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:340
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:798
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:343
#define clib_warning(format, args...)
Definition: error.h:59
void ip_lookup_init(ip_lookup_main_t *lm, u32 is_ip6)
Definition: lookup.c:189
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: lookup.h:73
void vnet_register_ip4_arp_resolution_event(vnet_main_t *vnm, void *address_arg, uword node_index, uword type_opaque, uword data)
Definition: arp.c:663
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:157
Aggregrate type for a prefix.
Definition: mfib_types.h:24
u8 builtin_protocol_by_ip_protocol[256]
IP_BUILTIN_PROTOCOL_{TCP,UDP,ICMP,OTHER} by protocol in IP header.
Definition: lookup.h:373
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define foreach_flow_hash_bit
Definition: lookup.h:154
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:344
fib_node_index_t fib_table_entry_special_dpo_add(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_entry_flag_t flags, const dpo_id_t *dpo)
Add a &#39;special&#39; entry to the FIB that links to the DPO passed A special entry is an entry that the FI...
Definition: fib_table.c:288
#define ASSERT(truth)
unsigned int u32
Definition: types.h:88
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
ip6_main_t ip6_main
Definition: ip6_forward.c:2846
IPv4 main type.
Definition: ip4.h:107
This packets follow a mid-chain adjacency.
Definition: lookup.h:89
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:347
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:220
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:165
u64 uword
Definition: types.h:112
#define unformat_parse_error(input)
Definition: format.h:267
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
static clib_error_t * ip_sw_interface_add_del(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: lookup.c:174
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
double f64
Definition: types.h:142
unsigned char u8
Definition: types.h:56
ip_lookup_next_t lookup_next_index
Definition: lookup.h:204
#define STATIC_ASSERT(truth,...)
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:403
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
u32 is_ip6
1 for ip6; 0 for ip4.
Definition: lookup.h:361
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:173
clib_error_t * ip_interface_address_add_del(ip_lookup_main_t *lm, u32 sw_if_index, void *addr_fib, u32 address_length, u32 is_del, u32 *result_if_address_index)
Definition: lookup.c:61
enum mfib_itf_flags_t_ mfib_itf_flags_t
static uword vlib_in_process_context(vlib_main_t *vm)
Definition: node_funcs.h:404
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1117
This packet is to be rewritten and forwarded to the next processing node.
Definition: lookup.h:83
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:194
u8 * format_ip_flow_hash_config(u8 *s, va_list *args)
Definition: lookup.c:240
static clib_error_t * probe_neighbor_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lookup.c:1132
u8 * format_ip_adjacency_packet_data(u8 *s, va_list *args)
Definition: lookup.c:292
u16 fp_len
The mask length.
Definition: mfib_types.h:28
#define vec_validate_init_empty(V, I, INIT)
Make sure vector is long enough for given index and initialize empty space (no header, unspecified alignment)
Definition: vec.h:485
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:247
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:67
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:339
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:577
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(ip_sw_interface_add_del)
const ip46_address_t zero_addr
Definition: lookup.c:354
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:971
u32 fib_result_n_bytes
Number of bytes in a fib result.
Definition: lookup.h:356
ip46_address_t fp_grp_addr
The address type is not deriveable from the fp_addr member.
Definition: mfib_types.h:46
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
format_function_t * format_address_and_length
Either format_ip4_address_and_length or format_ip6_address_and_length.
Definition: lookup.h:364
format_function_t format_ip4_address_and_length
Definition: format.h:80