FD.io VPP  v17.07-30-g839fa73
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)) ||
77  (address_length == 0) ||
78  (lm->is_ip6 && address_length > 128) ||
79  (!lm->is_ip6 && address_length > 32))
80  {
81  vnm->api_errno = VNET_API_ERROR_ADDRESS_LENGTH_MISMATCH;
82  return clib_error_create
83  ("%U wrong length (expected %d) for interface %U",
84  lm->format_address_and_length, addr_fib,
85  address_length, a ? a->address_length : -1,
86  format_vnet_sw_if_index_name, vnm, sw_if_index);
87  }
88 
89  if (is_del)
90  {
91  if (!a)
92  {
93  vnet_sw_interface_t *si = vnet_get_sw_interface (vnm, sw_if_index);
94  vnm->api_errno = VNET_API_ERROR_ADDRESS_NOT_FOUND_FOR_INTERFACE;
95  return clib_error_create ("%U not found for interface %U",
97  addr_fib, address_length,
99  }
100 
101  if (a->prev_this_sw_interface != ~0)
102  {
103  prev =
107  }
108  if (a->next_this_sw_interface != ~0)
109  {
110  next =
114 
115  if (a->prev_this_sw_interface == ~0)
116  lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
118  }
119 
120  if ((a->next_this_sw_interface == ~0)
121  && (a->prev_this_sw_interface == ~0))
122  lm->if_address_pool_index_by_sw_if_index[sw_if_index] = ~0;
123 
125  /* old_value */ 0);
126  pool_put (lm->if_address_pool, a);
127 
128  if (result_if_address_index)
129  *result_if_address_index = ~0;
130  }
131 
132  else if (!a)
133  {
134  u32 pi; /* previous index */
135  u32 ai;
136  u32 hi; /* head index */
137 
138  pool_get (lm->if_address_pool, a);
139  memset (a, ~0, sizeof (a[0]));
140  ai = a - lm->if_address_pool;
141 
142  hi = pi = lm->if_address_pool_index_by_sw_if_index[sw_if_index];
143  prev = 0;
144  while (pi != (u32) ~ 0)
145  {
146  prev = pool_elt_at_index (lm->if_address_pool, pi);
147  pi = prev->next_this_sw_interface;
148  }
149  pi = prev ? prev - lm->if_address_pool : (u32) ~ 0;
150 
152  addr_fib, ai, /* old_value */ 0);
153  a->address_length = address_length;
154  a->sw_if_index = sw_if_index;
155  a->flags = 0;
156  a->prev_this_sw_interface = pi;
157  a->next_this_sw_interface = ~0;
158  if (prev)
159  prev->next_this_sw_interface = ai;
160 
161  lm->if_address_pool_index_by_sw_if_index[sw_if_index] =
162  (hi != ~0) ? hi : ai;
163  if (result_if_address_index)
164  *result_if_address_index = ai;
165  }
166  else
167  {
168  if (result_if_address_index)
169  *result_if_address_index = a - lm->if_address_pool;
170  }
171 
172 
173  return /* no error */ 0;
174 }
175 
176 static clib_error_t *
177 ip_sw_interface_add_del (vnet_main_t * vnm, u32 sw_if_index, u32 is_add)
178 {
180  lookup_main.if_address_pool_index_by_sw_if_index,
181  sw_if_index, ~0);
183  lookup_main.if_address_pool_index_by_sw_if_index,
184  sw_if_index, ~0);
185 
186  return (NULL);
187 }
188 
190 
191 void
193 {
194  if (!lm->fib_result_n_bytes)
195  lm->fib_result_n_bytes = sizeof (uword);
196 
197  lm->is_ip6 = is_ip6;
198  if (is_ip6)
199  {
202  sizeof (ip6_address_fib_t));
203  }
204  else
205  {
208  sizeof (ip4_address_fib_t));
209  }
210 
211  {
212  int i;
213 
214  /* Setup all IP protocols to be punted and builtin-unknown. */
215  for (i = 0; i < 256; i++)
216  {
219  }
220 
222  lm->local_next_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
223  IP_PROTOCOL_ICMP] = IP_LOCAL_NEXT_ICMP;
224  lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] =
226  lm->builtin_protocol_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
227  IP_PROTOCOL_ICMP] =
229  }
230 }
231 
232 u8 *
233 format_ip_flow_hash_config (u8 * s, va_list * args)
234 {
235  flow_hash_config_t flow_hash_config = va_arg (*args, u32);
236 
237 #define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n);
239 #undef _
240 
241  return s;
242 }
243 
244 u8 *
245 format_ip_lookup_next (u8 * s, va_list * args)
246 {
247  /* int promotion of ip_lookup_next_t */
248  ip_lookup_next_t n = va_arg (*args, int);
249  char *t = 0;
250 
251  switch (n)
252  {
253  default:
254  s = format (s, "unknown %d", n);
255  return s;
256 
257  case IP_LOOKUP_NEXT_DROP:
258  t = "drop";
259  break;
260  case IP_LOOKUP_NEXT_PUNT:
261  t = "punt";
262  break;
263  case IP_LOOKUP_NEXT_ARP:
264  t = "arp";
265  break;
267  t = "midchain";
268  break;
270  t = "glean";
271  break;
273  t = "mcast";
274  break;
276  break;
277  }
278 
279  if (t)
280  vec_add (s, t, strlen (t));
281 
282  return s;
283 }
284 
285 u8 *
286 format_ip_adjacency_packet_data (u8 * s, va_list * args)
287 {
288  u32 adj_index = va_arg (*args, u32);
289  u8 *packet_data = va_arg (*args, u8 *);
290  u32 n_packet_data_bytes = va_arg (*args, u32);
291  ip_adjacency_t *adj = adj_get (adj_index);
292 
293  switch (adj->lookup_next_index)
294  {
297  s =
298  format (s, "%U", format_hex_bytes, packet_data, n_packet_data_bytes);
299  break;
300 
301  default:
302  break;
303  }
304 
305  return s;
306 }
307 
308 static uword
309 unformat_dpo (unformat_input_t * input, va_list * args)
310 {
311  dpo_id_t *dpo = va_arg (*args, dpo_id_t *);
312  fib_protocol_t fp = va_arg (*args, int);
313  dpo_proto_t proto;
314 
315  proto = fib_proto_to_dpo (fp);
316 
317  if (unformat (input, "drop"))
318  dpo_copy (dpo, drop_dpo_get (proto));
319  else if (unformat (input, "punt"))
320  dpo_copy (dpo, punt_dpo_get (proto));
321  else if (unformat (input, "local"))
322  receive_dpo_add_or_lock (proto, ~0, NULL, dpo);
323  else if (unformat (input, "null-send-unreach"))
325  else if (unformat (input, "null-send-prohibit"))
327  else if (unformat (input, "null"))
329  else if (unformat (input, "classify"))
330  {
331  u32 classify_table_index;
332 
333  if (!unformat (input, "%d", &classify_table_index))
334  {
335  clib_warning ("classify adj must specify table index");
336  return 0;
337  }
338 
339  dpo_set (dpo, DPO_CLASSIFY, proto,
340  classify_dpo_create (proto, classify_table_index));
341  }
342  else
343  return 0;
344 
345  return 1;
346 }
347 
348 const ip46_address_t zero_addr = {
349  .as_u64 = {
350  0, 0},
351 };
352 
353 clib_error_t *
355  unformat_input_t * main_input, vlib_cli_command_t * cmd)
356 {
357  unformat_input_t _line_input, *line_input = &_line_input;
358  fib_route_path_t *rpaths = NULL, rpath;
359  dpo_id_t dpo = DPO_INVALID, *dpos = NULL;
360  fib_prefix_t *prefixs = NULL, pfx;
361  mpls_label_t out_label, via_label;
362  clib_error_t *error = NULL;
363  u32 table_id, is_del;
364  vnet_main_t *vnm;
365  u32 fib_index;
366  f64 count;
367  int i;
368 
369  vnm = vnet_get_main ();
370  is_del = 0;
371  table_id = 0;
372  count = 1;
373  memset (&pfx, 0, sizeof (pfx));
374  out_label = via_label = MPLS_LABEL_INVALID;
375 
376  /* Get a line of input. */
377  if (!unformat_user (main_input, unformat_line_input, line_input))
378  return 0;
379 
380  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
381  {
382  memset (&rpath, 0, sizeof (rpath));
383 
384  if (unformat (line_input, "table %d", &table_id))
385  ;
386  else if (unformat (line_input, "del"))
387  is_del = 1;
388  else if (unformat (line_input, "add"))
389  is_del = 0;
390  else if (unformat (line_input, "resolve-via-host"))
391  {
392  if (vec_len (rpaths) == 0)
393  {
394  error = clib_error_return (0, "Paths then flags");
395  goto done;
396  }
397  rpaths[vec_len (rpaths) - 1].frp_flags |=
399  }
400  else if (unformat (line_input, "resolve-via-attached"))
401  {
402  if (vec_len (rpaths) == 0)
403  {
404  error = clib_error_return (0, "Paths then flags");
405  goto done;
406  }
407  rpaths[vec_len (rpaths) - 1].frp_flags |=
409  }
410  else if (unformat (line_input, "out-label %U",
411  unformat_mpls_unicast_label, &out_label))
412  {
413  if (vec_len (rpaths) == 0)
414  {
415  error = clib_error_return (0, "Paths then labels");
416  goto done;
417  }
418  vec_add1 (rpaths[vec_len (rpaths) - 1].frp_label_stack, out_label);
419  }
420  else if (unformat (line_input, "via-label %U",
421  unformat_mpls_unicast_label, &rpath.frp_local_label))
422  {
423  rpath.frp_weight = 1;
424  rpath.frp_eos = MPLS_NON_EOS;
425  rpath.frp_proto = FIB_PROTOCOL_MPLS;
426  rpath.frp_sw_if_index = ~0;
427  vec_add1 (rpaths, rpath);
428  }
429  else if (unformat (line_input, "count %f", &count))
430  ;
431 
432  else if (unformat (line_input, "%U/%d",
433  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
434  {
435  pfx.fp_proto = FIB_PROTOCOL_IP4;
436  vec_add1 (prefixs, pfx);
437  }
438  else if (unformat (line_input, "%U/%d",
439  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
440  {
441  pfx.fp_proto = FIB_PROTOCOL_IP6;
442  vec_add1 (prefixs, pfx);
443  }
444  else if (unformat (line_input, "via %U %U weight %u",
446  &rpath.frp_addr.ip4,
448  &rpath.frp_sw_if_index, &rpath.frp_weight))
449  {
450  rpath.frp_proto = FIB_PROTOCOL_IP4;
451  vec_add1 (rpaths, rpath);
452  }
453 
454  else if (unformat (line_input, "via %U %U weight %u",
456  &rpath.frp_addr.ip6,
458  &rpath.frp_sw_if_index, &rpath.frp_weight))
459  {
460  rpath.frp_proto = FIB_PROTOCOL_IP6;
461  vec_add1 (rpaths, rpath);
462  }
463 
464  else if (unformat (line_input, "via %U %U",
466  &rpath.frp_addr.ip4,
468  &rpath.frp_sw_if_index))
469  {
470  rpath.frp_weight = 1;
471  rpath.frp_proto = FIB_PROTOCOL_IP4;
472  vec_add1 (rpaths, rpath);
473  }
474 
475  else if (unformat (line_input, "via %U %U",
477  &rpath.frp_addr.ip6,
479  &rpath.frp_sw_if_index))
480  {
481  rpath.frp_weight = 1;
482  rpath.frp_proto = FIB_PROTOCOL_IP6;
483  vec_add1 (rpaths, rpath);
484  }
485  else if (unformat (line_input, "via %U next-hop-table %d",
487  &rpath.frp_addr.ip4, &rpath.frp_fib_index))
488  {
489  rpath.frp_weight = 1;
490  rpath.frp_sw_if_index = ~0;
491  rpath.frp_proto = FIB_PROTOCOL_IP4;
492  vec_add1 (rpaths, rpath);
493  }
494  else if (unformat (line_input, "via %U next-hop-table %d",
496  &rpath.frp_addr.ip6, &rpath.frp_fib_index))
497  {
498  rpath.frp_weight = 1;
499  rpath.frp_sw_if_index = ~0;
500  rpath.frp_proto = FIB_PROTOCOL_IP6;
501  vec_add1 (rpaths, rpath);
502  }
503  else if (unformat (line_input, "via %U",
504  unformat_ip4_address, &rpath.frp_addr.ip4))
505  {
506  /*
507  * the recursive next-hops are by default in the same table
508  * as the prefix
509  */
510  rpath.frp_fib_index = table_id;
511  rpath.frp_weight = 1;
512  rpath.frp_sw_if_index = ~0;
513  rpath.frp_proto = FIB_PROTOCOL_IP4;
514  vec_add1 (rpaths, rpath);
515  }
516  else if (unformat (line_input, "via %U",
517  unformat_ip6_address, &rpath.frp_addr.ip6))
518  {
519  rpath.frp_fib_index = table_id;
520  rpath.frp_weight = 1;
521  rpath.frp_sw_if_index = ~0;
522  rpath.frp_proto = FIB_PROTOCOL_IP6;
523  vec_add1 (rpaths, rpath);
524  }
525  else if (unformat (line_input,
526  "lookup in table %d", &rpath.frp_fib_index))
527  {
528  rpath.frp_proto = pfx.fp_proto;
529  rpath.frp_sw_if_index = ~0;
530  vec_add1 (rpaths, rpath);
531  }
532  else if (vec_len (prefixs) > 0 &&
533  unformat (line_input, "via %U",
535  &rpath.frp_sw_if_index))
536  {
537  rpath.frp_weight = 1;
538  rpath.frp_proto = prefixs[0].fp_proto;
539  vec_add1 (rpaths, rpath);
540  }
541  else if (vec_len (prefixs) > 0 &&
542  unformat (line_input, "via %U",
543  unformat_dpo, &dpo, prefixs[0].fp_proto))
544  {
545  vec_add1 (dpos, dpo);
546  }
547  else
548  {
549  error = unformat_parse_error (line_input);
550  goto done;
551  }
552  }
553 
554  if (vec_len (prefixs) == 0)
555  {
556  error =
557  clib_error_return (0, "expected ip4/ip6 destination address/length.");
558  goto done;
559  }
560 
561  if (!is_del && vec_len (rpaths) + vec_len (dpos) == 0)
562  {
563  error = clib_error_return (0, "expected paths.");
564  goto done;
565  }
566 
567  if (~0 == table_id)
568  {
569  /*
570  * if no table_id is passed we will manipulate the default
571  */
572  fib_index = 0;
573  }
574  else
575  {
576  fib_index = fib_table_find (prefixs[0].fp_proto, table_id);
577 
578  if (~0 == fib_index)
579  {
580  error = clib_error_return (0, "Nonexistent table id %d", table_id);
581  goto done;
582  }
583  }
584 
585  for (i = 0; i < vec_len (prefixs); i++)
586  {
587  if (is_del && 0 == vec_len (rpaths))
588  {
589  fib_table_entry_delete (fib_index, &prefixs[i], FIB_SOURCE_CLI);
590  }
591  else if (!is_del && 1 == vec_len (dpos))
592  {
594  &prefixs[i],
597  &dpos[0]);
598  dpo_reset (&dpos[0]);
599  }
600  else if (vec_len (dpos) > 0)
601  {
602  error =
604  "Load-balancing over multiple special adjacencies is unsupported");
605  goto done;
606  }
607  else if (0 < vec_len (rpaths))
608  {
609  u32 k, j, n, incr;
610  ip46_address_t dst = prefixs[i].fp_addr;
611  f64 t[2];
612  n = count;
613  t[0] = vlib_time_now (vm);
614  incr = 1 << ((FIB_PROTOCOL_IP4 == prefixs[0].fp_proto ? 32 : 128) -
615  prefixs[i].fp_len);
616 
617  for (k = 0; k < n; k++)
618  {
619  for (j = 0; j < vec_len (rpaths); j++)
620  {
621  u32 fi;
622  /*
623  * the CLI parsing stored table Ids, swap to FIB indicies
624  */
625  fi = fib_table_find (prefixs[i].fp_proto,
626  rpaths[i].frp_fib_index);
627 
628  if (~0 == fi)
629  {
630  error =
631  clib_error_return (0, "Via table %d does not exist",
632  rpaths[i].frp_fib_index);
633  goto done;
634  }
635  rpaths[i].frp_fib_index = fi;
636 
637  fib_prefix_t rpfx = {
638  .fp_len = prefixs[i].fp_len,
639  .fp_proto = prefixs[i].fp_proto,
640  .fp_addr = dst,
641  };
642 
643  if (is_del)
644  fib_table_entry_path_remove2 (fib_index,
645  &rpfx,
646  FIB_SOURCE_CLI, &rpaths[j]);
647  else
648  fib_table_entry_path_add2 (fib_index,
649  &rpfx,
652  &rpaths[j]);
653  }
654 
655  if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto)
656  {
657  dst.ip4.as_u32 =
658  clib_host_to_net_u32 (incr +
659  clib_net_to_host_u32 (dst.
660  ip4.as_u32));
661  }
662  else
663  {
664  int bucket = (incr < 64 ? 0 : 1);
665  dst.ip6.as_u64[bucket] =
666  clib_host_to_net_u64 (incr +
667  clib_net_to_host_u64 (dst.ip6.as_u64
668  [bucket]));
669 
670  }
671  }
672  t[1] = vlib_time_now (vm);
673  if (count > 1)
674  vlib_cli_output (vm, "%.6e routes/sec", count / (t[1] - t[0]));
675  }
676  else
677  {
678  error = clib_error_return (0, "Don't understand what you want...");
679  goto done;
680  }
681  }
682 
683 
684 done:
685  vec_free (dpos);
686  vec_free (prefixs);
687  vec_free (rpaths);
688  unformat_free (line_input);
689  return error;
690 }
691 
692 /* *INDENT-OFF* */
693 VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = {
694  .path = "ip",
695  .short_help = "Internet protocol (IP) commands",
696 };
697 /* *INDENT-ON* */
698 
699 /* *INDENT-OFF* */
700 VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = {
701  .path = "ip6",
702  .short_help = "Internet protocol version 6 (IPv6) commands",
703 };
704 /* *INDENT-ON* */
705 
706 /* *INDENT-OFF* */
707 VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = {
708  .path = "show ip",
709  .short_help = "Internet protocol (IP) show commands",
710 };
711 /* *INDENT-ON* */
712 
713 /* *INDENT-OFF* */
714 VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
715  .path = "show ip6",
716  .short_help = "Internet protocol version 6 (IPv6) show commands",
717 };
718 /* *INDENT-ON* */
719 
720 /*?
721  * This command is used to add or delete IPv4 or IPv6 routes. All
722  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
723  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
724  * can be IPv4 or IPv6, but all must be of the same form in a single
725  * command. To display the current set of routes, use the commands
726  * '<em>show ip fib</em>' and '<em>show ip6 fib</em>'.
727  *
728  * @cliexpar
729  * Example of how to add a straight forward static route:
730  * @cliexcmd{ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
731  * Example of how to delete a straight forward static route:
732  * @cliexcmd{ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
733  * Mainly for route add/del performance testing, one can add or delete
734  * multiple routes by adding 'count N' to the previous item:
735  * @cliexcmd{ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0}
736  * Add multiple routes for the same destination to create equal-cost multipath:
737  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0}
738  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0}
739  * For unequal-cost multipath, specify the desired weights. This
740  * combination of weights results in 3/4 of the traffic following the
741  * second path, 1/4 following the first path:
742  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1}
743  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3}
744  * To add a route to a particular FIB table (VRF), use:
745  * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0}
746  ?*/
747 /* *INDENT-OFF* */
748 VLIB_CLI_COMMAND (ip_route_command, static) = {
749  .path = "ip route",
750  .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>]",
751  .function = vnet_ip_route_cmd,
752  .is_mp_safe = 1,
753 };
754 /* *INDENT-ON* */
755 
756 clib_error_t *
758  unformat_input_t * main_input, vlib_cli_command_t * cmd)
759 {
760  unformat_input_t _line_input, *line_input = &_line_input;
761  clib_error_t *error = NULL;
762  fib_route_path_t rpath;
763  u32 table_id, is_del;
764  vnet_main_t *vnm;
765  mfib_prefix_t pfx;
766  u32 fib_index;
767  mfib_itf_flags_t iflags = 0;
768  mfib_entry_flags_t eflags = 0;
769  u32 gcount, scount, ss, gg, incr;
770  f64 timet[2];
771 
772  gcount = scount = 1;
773  vnm = vnet_get_main ();
774  is_del = 0;
775  table_id = 0;
776  memset (&pfx, 0, sizeof (pfx));
777  memset (&rpath, 0, sizeof (rpath));
778  rpath.frp_sw_if_index = ~0;
779 
780  /* Get a line of input. */
781  if (!unformat_user (main_input, unformat_line_input, line_input))
782  return 0;
783 
784  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
785  {
786  if (unformat (line_input, "table %d", &table_id))
787  ;
788  else if (unformat (line_input, "del"))
789  is_del = 1;
790  else if (unformat (line_input, "add"))
791  is_del = 0;
792  else if (unformat (line_input, "scount %d", &scount))
793  ;
794  else if (unformat (line_input, "gcount %d", &gcount))
795  ;
796  else if (unformat (line_input, "%U %U",
798  &pfx.fp_src_addr.ip4,
800  {
802  pfx.fp_len = 64;
803  }
804  else if (unformat (line_input, "%U %U",
806  &pfx.fp_src_addr.ip6,
808  {
810  pfx.fp_len = 256;
811  }
812  else if (unformat (line_input, "%U/%d",
814  &pfx.fp_grp_addr.ip4, &pfx.fp_len))
815  {
816  memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
818  }
819  else if (unformat (line_input, "%U/%d",
821  &pfx.fp_grp_addr.ip6, &pfx.fp_len))
822  {
823  memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
825  }
826  else if (unformat (line_input, "%U",
828  {
829  memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
831  pfx.fp_len = 32;
832  }
833  else if (unformat (line_input, "%U",
835  {
836  memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
838  pfx.fp_len = 128;
839  }
840  else if (unformat (line_input, "via %U",
842  &rpath.frp_sw_if_index))
843  {
844  rpath.frp_weight = 1;
845  }
846  else if (unformat (line_input, "via local"))
847  {
848  rpath.frp_sw_if_index = ~0;
849  rpath.frp_weight = 1;
851  }
852  else if (unformat (line_input, "%U", unformat_mfib_itf_flags, &iflags))
853  ;
854  else if (unformat (line_input, "%U",
855  unformat_mfib_entry_flags, &eflags))
856  ;
857  else
858  {
859  error = unformat_parse_error (line_input);
860  goto done;
861  }
862  }
863 
864  if (~0 == table_id)
865  {
866  /*
867  * if no table_id is passed we will manipulate the default
868  */
869  fib_index = 0;
870  }
871  else
872  {
873  fib_index = mfib_table_find (pfx.fp_proto, table_id);
874 
875  if (~0 == fib_index)
876  {
877  error = clib_error_return (0, "Nonexistent table id %d", table_id);
878  goto done;
879  }
880  }
881 
882  timet[0] = vlib_time_now (vm);
883 
884  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
885  {
886  incr = 1 << (32 - (pfx.fp_len % 32));
887  }
888  else
889  {
890  incr = 1 << (128 - (pfx.fp_len % 128));
891  }
892 
893  for (ss = 0; ss < scount; ss++)
894  {
895  for (gg = 0; gg < gcount; gg++)
896  {
897  if (is_del && 0 == rpath.frp_weight)
898  {
899  /* no path provided => route delete */
900  mfib_table_entry_delete (fib_index, &pfx, MFIB_SOURCE_CLI);
901  }
902  else if (eflags)
903  {
904  mfib_table_entry_update (fib_index, &pfx, MFIB_SOURCE_CLI,
905  MFIB_RPF_ID_NONE, eflags);
906  }
907  else
908  {
909  if (is_del)
910  mfib_table_entry_path_remove (fib_index,
911  &pfx, MFIB_SOURCE_CLI, &rpath);
912  else
913  mfib_table_entry_path_update (fib_index,
914  &pfx, MFIB_SOURCE_CLI, &rpath,
915  iflags);
916  }
917 
918  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
919  {
920  pfx.fp_grp_addr.ip4.as_u32 =
921  clib_host_to_net_u32 (incr +
922  clib_net_to_host_u32 (pfx.
923  fp_grp_addr.ip4.
924  as_u32));
925  }
926  else
927  {
928  int bucket = (incr < 64 ? 0 : 1);
929  pfx.fp_grp_addr.ip6.as_u64[bucket] =
930  clib_host_to_net_u64 (incr +
931  clib_net_to_host_u64 (pfx.
932  fp_grp_addr.ip6.as_u64
933  [bucket]));
934 
935  }
936  }
937  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
938  {
939  pfx.fp_src_addr.ip4.as_u32 =
940  clib_host_to_net_u32 (1 +
941  clib_net_to_host_u32 (pfx.fp_src_addr.
942  ip4.as_u32));
943  }
944  else
945  {
946  pfx.fp_src_addr.ip6.as_u64[1] =
947  clib_host_to_net_u64 (1 +
948  clib_net_to_host_u64 (pfx.fp_src_addr.
949  ip6.as_u64[1]));
950  }
951  }
952 
953  timet[1] = vlib_time_now (vm);
954 
955  if (scount > 1 || gcount > 1)
956  vlib_cli_output (vm, "%.6e routes/sec",
957  (scount * gcount) / (timet[1] - timet[0]));
958 
959 done:
960  unformat_free (line_input);
961 
962  return error;
963 }
964 
965 /*?
966  * This command is used to add or delete IPv4 or IPv6 multicastroutes. All
967  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
968  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
969  * can be IPv4 or IPv6, but all must be of the same form in a single
970  * command. To display the current set of routes, use the commands
971  * '<em>show ip mfib</em>' and '<em>show ip6 mfib</em>'.
972  * The full set of support flags for interfaces and route is shown via;
973  * '<em>show mfib route flags</em>' and '<em>show mfib itf flags</em>'
974  * respectively.
975  * @cliexpar
976  * Example of how to add a forwarding interface to a route (and create the
977  * route if it does not exist)
978  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/0 Forward}
979  * Example of how to add an accepting interface to a route (and create the
980  * route if it does not exist)
981  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/1 Accept}
982  * Example of changing the route's flags to send signals via the API
983  * @cliexcmd{ip mroute add 232.1.1.1 Signal}
984 
985  ?*/
986 /* *INDENT-OFF* */
987 VLIB_CLI_COMMAND (ip_mroute_command, static) =
988 {
989  .path = "ip mroute",
990  .short_help = "ip mroute [add|del] <dst-ip-addr>/<width> [table <table-id>] [via <next-hop-ip-addr> [<interface>],",
991  .function = vnet_ip_mroute_cmd,
992  .is_mp_safe = 1,
993 };
994 /* *INDENT-ON* */
995 
996 /*
997  * The next two routines address a longstanding script hemorrhoid.
998  * Probing a v4 or v6 neighbor needs to appear to be synchronous,
999  * or dependent route-adds will simply fail.
1000  */
1001 static clib_error_t *
1003  int retry_count)
1004 {
1005  vnet_main_t *vnm = vnet_get_main ();
1006  clib_error_t *e;
1007  int i;
1008  int resolved = 0;
1009  uword event_type;
1010  uword *event_data = 0;
1011 
1013 
1014  if (retry_count > 0)
1016  (vnm, a, vlib_get_current_process (vm)->node_runtime.node_index,
1017  1 /* event */ , 0 /* data */ );
1018 
1019  for (i = 0; i < retry_count; i++)
1020  {
1021  /* The interface may be down, etc. */
1022  e = ip6_probe_neighbor (vm, a, sw_if_index);
1023 
1024  if (e)
1025  return e;
1026 
1028  event_type = vlib_process_get_events (vm, &event_data);
1029  switch (event_type)
1030  {
1031  case 1: /* resolved... */
1032  vlib_cli_output (vm, "Resolved %U", format_ip6_address, a);
1033  resolved = 1;
1034  goto done;
1035 
1036  case ~0: /* timeout */
1037  break;
1038 
1039  default:
1040  clib_warning ("unknown event_type %d", event_type);
1041  }
1042  vec_reset_length (event_data);
1043  }
1044 
1045 done:
1046 
1047  if (!resolved)
1048  return clib_error_return (0, "Resolution failed for %U",
1049  format_ip6_address, a);
1050  return 0;
1051 }
1052 
1053 static clib_error_t *
1055  int retry_count)
1056 {
1057  vnet_main_t *vnm = vnet_get_main ();
1058  clib_error_t *e;
1059  int i;
1060  int resolved = 0;
1061  uword event_type;
1062  uword *event_data = 0;
1063 
1065 
1066  if (retry_count > 0)
1068  (vnm, a, vlib_get_current_process (vm)->node_runtime.node_index,
1069  1 /* event */ , 0 /* data */ );
1070 
1071  for (i = 0; i < retry_count; i++)
1072  {
1073  /* The interface may be down, etc. */
1074  e = ip4_probe_neighbor (vm, a, sw_if_index);
1075 
1076  if (e)
1077  return e;
1078 
1080  event_type = vlib_process_get_events (vm, &event_data);
1081  switch (event_type)
1082  {
1083  case 1: /* resolved... */
1084  vlib_cli_output (vm, "Resolved %U", format_ip4_address, a);
1085  resolved = 1;
1086  goto done;
1087 
1088  case ~0: /* timeout */
1089  break;
1090 
1091  default:
1092  clib_warning ("unknown event_type %d", event_type);
1093  }
1094  vec_reset_length (event_data);
1095  }
1096 
1097 done:
1098 
1099  vec_reset_length (event_data);
1100 
1101  if (!resolved)
1102  return clib_error_return (0, "Resolution failed for %U",
1103  format_ip4_address, a);
1104  return 0;
1105 }
1106 
1107 static clib_error_t *
1109  unformat_input_t * input, vlib_cli_command_t * cmd)
1110 {
1111  vnet_main_t *vnm = vnet_get_main ();
1112  unformat_input_t _line_input, *line_input = &_line_input;
1113  ip4_address_t a4;
1114  ip6_address_t a6;
1115  clib_error_t *error = 0;
1116  u32 sw_if_index = ~0;
1117  int retry_count = 3;
1118  int is_ip4 = 1;
1119  int address_set = 0;
1120 
1121  /* Get a line of input. */
1122  if (!unformat_user (input, unformat_line_input, line_input))
1123  return 0;
1124 
1125  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1126  {
1127  if (unformat_user (line_input, unformat_vnet_sw_interface, vnm,
1128  &sw_if_index))
1129  ;
1130  else if (unformat (line_input, "retry %d", &retry_count))
1131  ;
1132 
1133  else if (unformat (line_input, "%U", unformat_ip4_address, &a4))
1134  address_set++;
1135  else if (unformat (line_input, "%U", unformat_ip6_address, &a6))
1136  {
1137  address_set++;
1138  is_ip4 = 0;
1139  }
1140  else
1141  {
1142  error = clib_error_return (0, "unknown input '%U'",
1143  format_unformat_error, line_input);
1144  goto done;
1145  }
1146  }
1147 
1148  if (sw_if_index == ~0)
1149  {
1150  error = clib_error_return (0, "Interface required, not set.");
1151  goto done;
1152  }
1153  if (address_set == 0)
1154  {
1155  error = clib_error_return (0, "ip address required, not set.");
1156  goto done;
1157  }
1158  if (address_set > 1)
1159  {
1160  error = clib_error_return (0, "Multiple ip addresses not supported.");
1161  goto done;
1162  }
1163 
1164  if (is_ip4)
1165  error = ip4_probe_neighbor_wait (vm, &a4, sw_if_index, retry_count);
1166  else
1167  error = ip6_probe_neighbor_wait (vm, &a6, sw_if_index, retry_count);
1168 
1169 done:
1170  unformat_free (line_input);
1171 
1172  return error;
1173 }
1174 
1175 /*?
1176  * The '<em>ip probe-neighbor</em>' command ARPs for IPv4 addresses or
1177  * attempts IPv6 neighbor discovery depending on the supplied IP address
1178  * format.
1179  *
1180  * @note This command will not immediately affect the indicated FIB; it
1181  * is not suitable for use in establishing a FIB entry prior to adding
1182  * recursive FIB entries. As in: don't use it in a script to probe a
1183  * gateway prior to adding a default route. It won't work. Instead,
1184  * configure a static ARP cache entry [see '<em>set ip arp</em>'], or
1185  * a static IPv6 neighbor [see '<em>set ip6 neighbor</em>'].
1186  *
1187  * @cliexpar
1188  * Example of probe for an IPv4 address:
1189  * @cliexcmd{ip probe-neighbor GigabitEthernet2/0/0 172.16.1.2}
1190 ?*/
1191 /* *INDENT-OFF* */
1192 VLIB_CLI_COMMAND (ip_probe_neighbor_command, static) = {
1193  .path = "ip probe-neighbor",
1194  .function = probe_neighbor_address,
1195  .short_help = "ip probe-neighbor <interface> <ip4-addr> | <ip6-addr> [retry nn]",
1196  .is_mp_safe = 1,
1197 };
1198 /* *INDENT-ON* */
1199 
1200 /*
1201  * fd.io coding-style-patch-verification: ON
1202  *
1203  * Local Variables:
1204  * eval: (c-set-style "gnu")
1205  * End:
1206  */
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:1002
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:169
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:356
vmrglw vmrglh hi
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:337
void receive_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, const ip46_address_t *nh_addr, dpo_id_t *dpo)
Definition: receive_dpo.c:56
static f64 vlib_process_wait_for_event_or_clock(vlib_main_t *vm, f64 dt)
Suspend a cooperative multi-tasking thread Waits for an event, or for the indicated number of seconds...
Definition: node_funcs.h:699
enum mfib_entry_flags_t_ mfib_entry_flags_t
a
Definition: bitmap.h:516
static uword unformat_dpo(unformat_input_t *input, va_list *args)
Definition: lookup.c:309
A representation of a path as described by a route producer.
Definition: fib_types.h:336
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:122
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:1054
Multicast Adjacency.
Definition: adj.h:82
#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:192
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
IP unicast adjacency.
Definition: adj.h:174
u32 mpls_label_t
A label value only, i.e.
Definition: packet.h:24
This packet is to be rewritten and forwarded to the next processing node.
Definition: adj.h:73
From the CLI.
Definition: fib_entry.h:66
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:235
#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:983
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
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
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:419
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
mhash_t address_to_if_address_index
Hash table mapping address to index in interface address pool.
Definition: lookup.h:125
format_function_t format_vnet_sw_if_index_name
ip_lookup_next_t
An adjacency is a representation of an attached L3 peer.
Definition: adj.h:50
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:354
unformat_function_t unformat_mpls_unicast_label
Definition: mpls.h:83
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
#define vec_add(V, E, N)
Add N elements to end of vector V (no header, unspecified alignment)
Definition: vec.h:599
Adjacency to punt this packet.
Definition: adj.h:55
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:245
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:365
unformat_function_t unformat_ip4_address
Definition: format.h:76
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:369
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:317
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:542
Recursion constraint of via a host prefix.
Definition: fib_types.h:276
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
#define clib_error_return(e, args...)
Definition: error.h:99
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
#define clib_error_create(args...)
Definition: error.h:96
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
u16 fp_len
The mask length.
Definition: fib_types.h:164
clib_error_t * ip6_probe_neighbor(vlib_main_t *vm, ip6_address_t *dst, u32 sw_if_index)
Definition: ip6_forward.c:1863
Definition: fib_entry.h:233
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:2273
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:152
format_function_t format_vnet_sw_interface_name
Definition: fib_entry.h:237
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:397
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:582
u8 local_next_by_ip_protocol[256]
Table mapping ip protocol to ip[46]-local node next index.
Definition: lookup.h:150
This packet matches an "interface route" and packets need to be passed to ARP to find rewrite string ...
Definition: adj.h:68
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
clib_error_t * vnet_ip_mroute_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:757
unformat_function_t unformat_ip6_address
Definition: format.h:94
This packet matches an "incomplete adjacency" and packets need to be passed to ARP to find rewrite st...
Definition: adj.h:63
uword unformat_mfib_entry_flags(unformat_input_t *input, va_list *args)
Definition: mfib_types.c:142
Adjacency to drop this packet.
Definition: adj.h:53
#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:413
#define MPLS_LABEL_INVALID
Definition: mpls_types.h:48
#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:835
u32 frp_weight
[un]equal cost path weight
Definition: fib_types.h:383
#define clib_warning(format, args...)
Definition: error.h:59
void ip_lookup_init(ip_lookup_main_t *lm, u32 is_ip6)
Definition: lookup.c:192
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:675
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:159
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:153
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define foreach_flow_hash_bit
Definition: lookup.h:71
This packets follow a mid-chain adjacency.
Definition: adj.h:76
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:129
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:290
#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:2926
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:387
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:211
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:82
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:177
A for-us/local path.
Definition: fib_types.h:284
#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
Next hop after ip4-lookup.
Definition: adj.h:189
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
static void unformat_free(unformat_input_t *i)
Definition: format.h:161
u32 is_ip6
1 for ip6; 0 for ip4.
Definition: lookup.h:144
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:179
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:420
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:1168
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:205
u8 * format_ip_flow_hash_config(u8 *s, va_list *args)
Definition: lookup.c:233
static clib_error_t * probe_neighbor_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lookup.c:1108
u8 * format_ip_adjacency_packet_data(u8 *s, va_list *args)
Definition: lookup.c:286
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:251
u32 frp_fib_index
The FIB index to lookup the nexthop Only valid for recursive paths.
Definition: fib_types.h:379
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:680
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(ip_sw_interface_add_del)
const ip46_address_t zero_addr
Definition: lookup.c:348
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:972
u32 fib_result_n_bytes
Number of bytes in a fib result.
Definition: lookup.h:141
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:147
format_function_t format_ip4_address_and_length
Definition: format.h:80