FD.io VPP  v20.01-48-g3e0dafb74
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 management
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/dpo/l3_proxy_dpo.h>
53 
54 /**
55  * @file
56  * @brief IPv4 and IPv6 adjacency and lookup table management.
57  *
58  */
59 
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)
118  }
119 
120  if ((a->next_this_sw_interface == ~0)
121  && (a->prev_this_sw_interface == ~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  clib_memset (a, ~0, sizeof (a[0]));
140  ai = a - lm->if_address_pool;
141 
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;
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 
162  (hi != ~0) ? hi : ai;
163  if (result_if_address_index)
164  *result_if_address_index = ai;
165  }
166  else
167  {
168  if (sw_if_index != a->sw_if_index)
169  {
170  if (result_if_address_index)
171  *result_if_address_index = ~0;
172  vnm->api_errno = VNET_API_ERROR_DUPLICATE_IF_ADDRESS;
173  return clib_error_create
174  ("Prefix %U already found on interface %U",
175  lm->format_address_and_length, addr_fib, address_length,
177  }
178 
179  if (result_if_address_index)
180  *result_if_address_index = a - lm->if_address_pool;
181  }
182 
183  return /* no error */ 0;
184 }
185 
186 static clib_error_t *
188 {
190  lookup_main.if_address_pool_index_by_sw_if_index,
191  sw_if_index, ~0);
193  lookup_main.if_address_pool_index_by_sw_if_index,
194  sw_if_index, ~0);
195 
196  return (NULL);
197 }
198 
200 
201 void
203 {
204  if (!lm->fib_result_n_bytes)
205  lm->fib_result_n_bytes = sizeof (uword);
206 
207  lm->is_ip6 = is_ip6;
209  sizeof (ip_interface_prefix_key_t));
210  if (is_ip6)
211  {
214  sizeof (ip6_address_fib_t));
215  }
216  else
217  {
220  sizeof (ip4_address_fib_t));
221  }
222 
223  {
224  int i;
225 
226  /* Setup all IP protocols to be punted and builtin-unknown. */
227  for (i = 0; i < 256; i++)
228  {
231  }
232 
234  lm->local_next_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
235  IP_PROTOCOL_ICMP] = IP_LOCAL_NEXT_ICMP;
236  lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] =
238  lm->builtin_protocol_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
239  IP_PROTOCOL_ICMP] =
241  }
242 }
243 
244 u8 *
245 format_ip_flow_hash_config (u8 * s, va_list * args)
246 {
247  flow_hash_config_t flow_hash_config = va_arg (*args, u32);
248 
249 #define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n);
251 #undef _
252 
253  return s;
254 }
255 
256 u8 *
257 format_ip_adjacency_packet_data (u8 * s, va_list * args)
258 {
259  u8 *packet_data = va_arg (*args, u8 *);
260  u32 n_packet_data_bytes = va_arg (*args, u32);
261 
262  s = format (s, "%U", format_hex_bytes, packet_data, n_packet_data_bytes);
263 
264  return s;
265 }
266 
267 static uword
268 unformat_dpo (unformat_input_t * input, va_list * args)
269 {
270  dpo_id_t *dpo = va_arg (*args, dpo_id_t *);
271  fib_protocol_t fp = va_arg (*args, int);
273 
274  proto = fib_proto_to_dpo (fp);
275 
276  if (unformat (input, "drop"))
277  dpo_copy (dpo, drop_dpo_get (proto));
278  else if (unformat (input, "punt"))
279  dpo_copy (dpo, punt_dpo_get (proto));
280  else if (unformat (input, "local"))
281  receive_dpo_add_or_lock (proto, ~0, NULL, dpo);
282  else if (unformat (input, "null-send-unreach"))
284  else if (unformat (input, "null-send-prohibit"))
286  else if (unformat (input, "null"))
288  else if (unformat (input, "classify"))
289  {
291 
292  if (!unformat (input, "%d", &classify_table_index))
293  {
294  clib_warning ("classify adj must specify table index");
295  return 0;
296  }
297 
298  dpo_set (dpo, DPO_CLASSIFY, proto,
299  classify_dpo_create (proto, classify_table_index));
300  }
301  else
302  return 0;
303 
304  return 1;
305 }
306 
307 const ip46_address_t zero_addr = {
308  .as_u64 = {
309  0, 0},
310 };
311 
312 static clib_error_t *
314  unformat_input_t * main_input, vlib_cli_command_t * cmd)
315 {
316  unformat_input_t _line_input, *line_input = &_line_input;
317  u32 table_id, is_del, fib_index, payload_proto;
318  dpo_id_t dpo = DPO_INVALID, *dpos = NULL;
319  fib_route_path_t *rpaths = NULL, rpath;
320  fib_prefix_t *prefixs = NULL, pfx;
321  clib_error_t *error = NULL;
322  f64 count;
323  int i;
324 
325  is_del = 0;
326  table_id = 0;
327  count = 1;
328  clib_memset (&pfx, 0, sizeof (pfx));
329 
330  /* Get a line of input. */
331  if (!unformat_user (main_input, unformat_line_input, line_input))
332  return 0;
333 
334  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
335  {
336  clib_memset (&rpath, 0, sizeof (rpath));
337 
338  if (unformat (line_input, "table %d", &table_id))
339  ;
340  else if (unformat (line_input, "count %f", &count))
341  ;
342 
343  else if (unformat (line_input, "%U/%d",
344  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
345  {
346  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
347  vec_add1 (prefixs, pfx);
348  }
349  else if (unformat (line_input, "%U/%d",
350  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
351  {
352  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
353  vec_add1 (prefixs, pfx);
354  }
355  else if (unformat (line_input, "via %U",
356  unformat_fib_route_path, &rpath, &payload_proto))
357  {
358  vec_add1 (rpaths, rpath);
359  }
360  else if (vec_len (prefixs) > 0 &&
361  unformat (line_input, "via %U",
362  unformat_dpo, &dpo, prefixs[0].fp_proto))
363  {
364  vec_add1 (dpos, dpo);
365  }
366  else if (unformat (line_input, "del"))
367  is_del = 1;
368  else if (unformat (line_input, "add"))
369  is_del = 0;
370  else
371  {
372  error = unformat_parse_error (line_input);
373  goto done;
374  }
375  }
376 
377  if (vec_len (prefixs) == 0)
378  {
379  error =
380  clib_error_return (0, "expected ip4/ip6 destination address/length.");
381  goto done;
382  }
383 
384  if (!is_del && vec_len (rpaths) + vec_len (dpos) == 0)
385  {
386  error = clib_error_return (0, "expected paths.");
387  goto done;
388  }
389 
390  if (~0 == table_id)
391  {
392  /*
393  * if no table_id is passed we will manipulate the default
394  */
395  fib_index = 0;
396  }
397  else
398  {
399  fib_index = fib_table_find (prefixs[0].fp_proto, table_id);
400 
401  if (~0 == fib_index)
402  {
403  error = clib_error_return (0, "Nonexistent table id %d", table_id);
404  goto done;
405  }
406  }
407 
408  for (i = 0; i < vec_len (prefixs); i++)
409  {
410  if (is_del && 0 == vec_len (rpaths))
411  {
412  fib_table_entry_delete (fib_index, &prefixs[i], FIB_SOURCE_CLI);
413  }
414  else if (!is_del && 1 == vec_len (dpos))
415  {
417  &prefixs[i],
420  &dpos[0]);
421  dpo_reset (&dpos[0]);
422  }
423  else if (vec_len (dpos) > 0)
424  {
425  error =
427  "Load-balancing over multiple special adjacencies is unsupported");
428  goto done;
429  }
430  else if (0 < vec_len (rpaths))
431  {
432  u32 k, n, incr;
433  ip46_address_t dst = prefixs[i].fp_addr;
434  f64 t[2];
435  n = count;
436  t[0] = vlib_time_now (vm);
437  incr = 1 << ((FIB_PROTOCOL_IP4 == prefixs[0].fp_proto ? 32 : 128) -
438  prefixs[i].fp_len);
439 
440  for (k = 0; k < n; k++)
441  {
442  fib_prefix_t rpfx = {
443  .fp_len = prefixs[i].fp_len,
444  .fp_proto = prefixs[i].fp_proto,
445  .fp_addr = dst,
446  };
447 
448  if (is_del)
449  fib_table_entry_path_remove2 (fib_index,
450  &rpfx, FIB_SOURCE_CLI, rpaths);
451  else
452  fib_table_entry_path_add2 (fib_index,
453  &rpfx,
455  FIB_ENTRY_FLAG_NONE, rpaths);
456 
457  if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto)
458  {
459  dst.ip4.as_u32 =
460  clib_host_to_net_u32 (incr +
461  clib_net_to_host_u32 (dst.
462  ip4.as_u32));
463  }
464  else
465  {
466  int bucket = (incr < 64 ? 0 : 1);
467  dst.ip6.as_u64[bucket] =
468  clib_host_to_net_u64 (incr +
469  clib_net_to_host_u64 (dst.ip6.as_u64
470  [bucket]));
471  }
472  }
473 
474  t[1] = vlib_time_now (vm);
475  if (count > 1)
476  vlib_cli_output (vm, "%.6e routes/sec", count / (t[1] - t[0]));
477  }
478  else
479  {
480  error = clib_error_return (0, "Don't understand what you want...");
481  goto done;
482  }
483  }
484 
485 done:
486  vec_free (dpos);
487  vec_free (prefixs);
488  vec_free (rpaths);
489  unformat_free (line_input);
490  return error;
491 }
492 
493 clib_error_t *
495  unformat_input_t * main_input,
496  vlib_cli_command_t * cmd, fib_protocol_t fproto)
497 {
498  unformat_input_t _line_input, *line_input = &_line_input;
499  clib_error_t *error = NULL;
500  u32 table_id, is_add;
501  u8 *name = NULL;
502 
503  is_add = 1;
504  table_id = ~0;
505 
506  /* Get a line of input. */
507  if (!unformat_user (main_input, unformat_line_input, line_input))
508  return 0;
509 
510  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
511  {
512  if (unformat (line_input, "%d", &table_id))
513  ;
514  else if (unformat (line_input, "del"))
515  is_add = 0;
516  else if (unformat (line_input, "add"))
517  is_add = 1;
518  else if (unformat (line_input, "name %s", &name))
519  ;
520  else
521  {
522  error = unformat_parse_error (line_input);
523  goto done;
524  }
525  }
526 
527  if (~0 == table_id)
528  {
529  error = clib_error_return (0, "No table id");
530  goto done;
531  }
532  else if (0 == table_id)
533  {
534  error = clib_error_return (0, "Can't change the default table");
535  goto done;
536  }
537  else
538  {
539  if (is_add)
540  {
541  ip_table_create (fproto, table_id, 0, name);
542  }
543  else
544  {
545  ip_table_delete (fproto, table_id, 0);
546  }
547  }
548 
549 done:
550  unformat_free (line_input);
551  return error;
552 }
553 
554 clib_error_t *
556  unformat_input_t * main_input, vlib_cli_command_t * cmd)
557 {
558  return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP4));
559 }
560 
561 clib_error_t *
563  unformat_input_t * main_input, vlib_cli_command_t * cmd)
564 {
565  return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP6));
566 }
567 
568 /* *INDENT-OFF* */
569 VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = {
570  .path = "ip",
571  .short_help = "Internet protocol (IP) commands",
572 };
573 /* *INDENT-ON* */
574 
575 /* *INDENT-OFF* */
576 VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = {
577  .path = "ip6",
578  .short_help = "Internet protocol version 6 (IPv6) commands",
579 };
580 /* *INDENT-ON* */
581 
582 /* *INDENT-OFF* */
583 VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = {
584  .path = "show ip",
585  .short_help = "Internet protocol (IP) show commands",
586 };
587 /* *INDENT-ON* */
588 
589 /* *INDENT-OFF* */
590 VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
591  .path = "show ip6",
592  .short_help = "Internet protocol version 6 (IPv6) show commands",
593 };
594 /* *INDENT-ON* */
595 
596 /*?
597  * This command is used to add or delete IPv4 or IPv6 routes. All
598  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
599  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
600  * can be IPv4 or IPv6, but all must be of the same form in a single
601  * command. To display the current set of routes, use the commands
602  * '<em>show ip fib</em>' and '<em>show ip6 fib</em>'.
603  *
604  * @cliexpar
605  * Example of how to add a straight forward static route:
606  * @cliexcmd{ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
607  * Example of how to delete a straight forward static route:
608  * @cliexcmd{ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
609  * Mainly for route add/del performance testing, one can add or delete
610  * multiple routes by adding 'count N' to the previous item:
611  * @cliexcmd{ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0}
612  * Add multiple routes for the same destination to create equal-cost multipath:
613  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0}
614  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0}
615  * For unequal-cost multipath, specify the desired weights. This
616  * combination of weights results in 3/4 of the traffic following the
617  * second path, 1/4 following the first path:
618  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1}
619  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3}
620  * To add a route to a particular FIB table (VRF), use:
621  * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0}
622  ?*/
623 /* *INDENT-OFF* */
624 VLIB_CLI_COMMAND (ip_route_command, static) = {
625  .path = "ip route",
626  .short_help = "ip route [add|del] [count <n>] <dst-ip-addr>/<width> [table <table-id>] via [next-hop-address] [next-hop-interface] [next-hop-table <value>] [weight <value>] [preference <value>] [udp-encap-id <value>] [ip4-lookup-in-table <value>] [ip6-lookup-in-table <value>] [mpls-lookup-in-table <value>] [resolve-via-host] [resolve-via-connected] [rx-ip4 <interface>] [out-labels <value value value>]",
627  .function = vnet_ip_route_cmd,
628  .is_mp_safe = 1,
629 };
630 
631 /* *INDENT-ON* */
632 /*?
633  * This command is used to add or delete IPv4 Tables. All
634  * Tables must be explicitly added before that can be used. Creating a
635  * table will add both unicast and multicast FIBs
636  *
637  ?*/
638 /* *INDENT-OFF* */
639 VLIB_CLI_COMMAND (ip4_table_command, static) = {
640  .path = "ip table",
641  .short_help = "ip table [add|del] <table-id>",
642  .function = vnet_ip4_table_cmd,
643 };
644 /* *INDENT-ON* */
645 
646 /* *INDENT-ON* */
647 /*?
648  * This command is used to add or delete IPv4 Tables. All
649  * Tables must be explicitly added before that can be used. Creating a
650  * table will add both unicast and multicast FIBs
651  *
652  ?*/
653 /* *INDENT-OFF* */
654 VLIB_CLI_COMMAND (ip6_table_command, static) = {
655  .path = "ip6 table",
656  .short_help = "ip6 table [add|del] <table-id>",
657  .function = vnet_ip6_table_cmd,
658 };
659 
660 static clib_error_t *
662  unformat_input_t * input,
663  vlib_cli_command_t * cmd,
664  fib_protocol_t fproto)
665 {
666  vnet_main_t *vnm = vnet_get_main ();
667  clib_error_t *error = 0;
669  int rv;
670 
671  sw_if_index = ~0;
672 
673  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
674  {
675  error = clib_error_return (0, "unknown interface `%U'",
676  format_unformat_error, input);
677  goto done;
678  }
679 
680  if (unformat (input, "%d", &table_id))
681  ;
682  else
683  {
684  error = clib_error_return (0, "expected table id `%U'",
685  format_unformat_error, input);
686  goto done;
687  }
688 
689  rv = ip_table_bind (fproto, sw_if_index, table_id, 0);
690 
691  if (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE == rv)
692  {
693  error = clib_error_return (0, "IP addresses are still present on %U",
695  vnet_get_main(),
696  sw_if_index);
697  }
698  else if (VNET_API_ERROR_NO_SUCH_FIB == rv)
699  {
700  error = clib_error_return (0, "no such table %d", table_id);
701  }
702  else if (0 != rv)
703  {
704  error = clib_error_return (0, "unknown error");
705  }
706 
707  done:
708  return error;
709 }
710 
711 static clib_error_t *
713  unformat_input_t * input,
714  vlib_cli_command_t * cmd)
715 {
716  return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP4));
717 }
718 
719 static clib_error_t *
721  unformat_input_t * input,
722  vlib_cli_command_t * cmd)
723 {
724  return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP6));
725 }
726 
727 /*?
728  * Place the indicated interface into the supplied IPv4 FIB table (also known
729  * as a VRF). The FIB table must be created using "ip table add" already. To
730  * display the current IPv4 FIB table, use the command '<em>show ip fib</em>'.
731  * FIB table will only be displayed if a route has been added to the table, or
732  * an IP Address is assigned to an interface in the table (which adds a route
733  * automatically).
734  *
735  * @note IP addresses added after setting the interface IP table are added to
736  * the indicated FIB table. If an IP address is added prior to changing the
737  * table then this is an error. The control plane must remove these addresses
738  * first and then change the table. VPP will not automatically move the
739  * addresses from the old to the new table as it does not know the validity
740  * of such a change.
741  *
742  * @cliexpar
743  * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id):
744  * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2}
745  ?*/
746 /* *INDENT-OFF* */
747 VLIB_CLI_COMMAND (set_interface_ip_table_command, static) =
748 {
749  .path = "set interface ip table",
750  .function = ip4_table_bind_cmd,
751  .short_help = "set interface ip table <interface> <table-id>",
752 };
753 /* *INDENT-ON* */
754 
755 /*?
756  * Place the indicated interface into the supplied IPv6 FIB table (also known
757  * as a VRF). The FIB table must be created using "ip6 table add" already. To
758  * display the current IPv6 FIB table, use the command '<em>show ip6 fib</em>'.
759  * FIB table will only be displayed if a route has been added to the table, or
760  * an IP Address is assigned to an interface in the table (which adds a route
761  * automatically).
762  *
763  * @note IP addresses added after setting the interface IP table are added to
764  * the indicated FIB table. If an IP address is added prior to changing the
765  * table then this is an error. The control plane must remove these addresses
766  * first and then change the table. VPP will not automatically move the
767  * addresses from the old to the new table as it does not know the validity
768  * of such a change.
769  *
770  * @cliexpar
771  * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id):
772  * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2}
773  ?*/
774 /* *INDENT-OFF* */
775 VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) =
776 {
777  .path = "set interface ip6 table",
778  .function = ip6_table_bind_cmd,
779  .short_help = "set interface ip6 table <interface> <table-id>"
780 };
781 /* *INDENT-ON* */
782 
783 clib_error_t *
785  unformat_input_t * main_input, vlib_cli_command_t * cmd)
786 {
787  unformat_input_t _line_input, *line_input = &_line_input;
788  fib_route_path_t rpath, *rpaths = NULL;
789  clib_error_t *error = NULL;
790  u32 table_id, is_del, payload_proto;
791  mfib_prefix_t pfx;
792  u32 fib_index;
793  mfib_entry_flags_t eflags = 0;
794  u32 gcount, scount, ss, gg, incr;
795  f64 timet[2];
797 
798  gcount = scount = 1;
799  is_del = 0;
800  table_id = 0;
801  clib_memset (&pfx, 0, sizeof (pfx));
802  clib_memset (&rpath, 0, sizeof (rpath));
803  rpath.frp_sw_if_index = ~0;
804 
805  /* Get a line of input. */
806  if (!unformat_user (main_input, unformat_line_input, line_input))
807  return 0;
808 
809  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
810  {
811  if (unformat (line_input, "table %d", &table_id))
812  ;
813  else if (unformat (line_input, "del"))
814  is_del = 1;
815  else if (unformat (line_input, "add"))
816  is_del = 0;
817  else if (unformat (line_input, "rpf-id %d", &rpf_id))
818  ;
819  else if (unformat (line_input, "scount %d", &scount))
820  ;
821  else if (unformat (line_input, "gcount %d", &gcount))
822  ;
823  else if (unformat (line_input, "%U %U",
825  &pfx.fp_src_addr.ip4,
827  {
829  pfx.fp_len = 64;
830  }
831  else if (unformat (line_input, "%U %U",
833  &pfx.fp_src_addr.ip6,
835  {
837  pfx.fp_len = 256;
838  }
839  else if (unformat (line_input, "%U/%d",
841  &pfx.fp_grp_addr.ip4, &pfx.fp_len))
842  {
843  clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
845  }
846  else if (unformat (line_input, "%U/%d",
848  &pfx.fp_grp_addr.ip6, &pfx.fp_len))
849  {
850  clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
852  }
853  else if (unformat (line_input, "%U",
855  {
856  clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
858  pfx.fp_len = 32;
859  }
860  else if (unformat (line_input, "%U",
862  {
863  clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
865  pfx.fp_len = 128;
866  }
867  else if (unformat (line_input, "via local Forward"))
868  {
869  clib_memset (&rpath.frp_addr, 0, sizeof (rpath.frp_addr));
870  rpath.frp_sw_if_index = ~0;
871  rpath.frp_weight = 1;
873  /*
874  * set the path proto appropriately for the prefix
875  */
876  rpath.frp_proto = fib_proto_to_dpo (pfx.fp_proto);
878 
879  vec_add1 (rpaths, rpath);
880  }
881  else if (unformat (line_input, "via %U",
882  unformat_fib_route_path, &rpath, &payload_proto))
883  {
884  vec_add1 (rpaths, rpath);
885  }
886  else if (unformat (line_input, "%U",
887  unformat_mfib_entry_flags, &eflags))
888  ;
889  else
890  {
891  error = unformat_parse_error (line_input);
892  goto done;
893  }
894  }
895 
896  if (~0 == table_id)
897  {
898  /*
899  * if no table_id is passed we will manipulate the default
900  */
901  fib_index = 0;
902  }
903  else
904  {
905  fib_index = mfib_table_find (pfx.fp_proto, table_id);
906 
907  if (~0 == fib_index)
908  {
909  error = clib_error_return (0, "Nonexistent table id %d", table_id);
910  goto done;
911  }
912  }
913 
914  timet[0] = vlib_time_now (vm);
915 
916  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
917  {
918  incr = 1 << (32 - (pfx.fp_len % 32));
919  }
920  else
921  {
922  incr = 1 << (128 - (pfx.fp_len % 128));
923  }
924 
925  for (ss = 0; ss < scount; ss++)
926  {
927  for (gg = 0; gg < gcount; gg++)
928  {
929  if (is_del && 0 == vec_len (rpaths))
930  {
931  /* no path provided => route delete */
932  mfib_table_entry_delete (fib_index, &pfx, MFIB_SOURCE_CLI);
933  }
934  else if (eflags || (MFIB_RPF_ID_NONE != rpf_id))
935  {
936  mfib_table_entry_update (fib_index, &pfx, MFIB_SOURCE_CLI,
937  rpf_id, eflags);
938  }
939  else
940  {
941  if (is_del)
942  mfib_table_entry_path_remove (fib_index,
943  &pfx, MFIB_SOURCE_CLI, rpaths);
944  else
945  mfib_table_entry_path_update (fib_index,
946  &pfx, MFIB_SOURCE_CLI, rpaths);
947  }
948 
949  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
950  {
951  pfx.fp_grp_addr.ip4.as_u32 =
952  clib_host_to_net_u32 (incr +
953  clib_net_to_host_u32 (pfx.
954  fp_grp_addr.ip4.
955  as_u32));
956  }
957  else
958  {
959  int bucket = (incr < 64 ? 0 : 1);
960  pfx.fp_grp_addr.ip6.as_u64[bucket] =
961  clib_host_to_net_u64 (incr +
962  clib_net_to_host_u64 (pfx.
963  fp_grp_addr.ip6.as_u64
964  [bucket]));
965 
966  }
967  }
968  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
969  {
970  pfx.fp_src_addr.ip4.as_u32 =
971  clib_host_to_net_u32 (1 +
972  clib_net_to_host_u32 (pfx.fp_src_addr.
973  ip4.as_u32));
974  }
975  else
976  {
977  pfx.fp_src_addr.ip6.as_u64[1] =
978  clib_host_to_net_u64 (1 +
979  clib_net_to_host_u64 (pfx.fp_src_addr.
980  ip6.as_u64[1]));
981  }
982  }
983 
984  timet[1] = vlib_time_now (vm);
985 
986  if (scount > 1 || gcount > 1)
987  vlib_cli_output (vm, "%.6e routes/sec",
988  (scount * gcount) / (timet[1] - timet[0]));
989 
990 done:
991  vec_free (rpaths);
992  unformat_free (line_input);
993 
994  return error;
995 }
996 
997 /*?
998  * This command is used to add or delete IPv4 or IPv6 multicast routes. All
999  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
1000  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
1001  * can be IPv4 or IPv6, but all must be of the same form in a single
1002  * command. To display the current set of routes, use the commands
1003  * '<em>show ip mfib</em>' and '<em>show ip6 mfib</em>'.
1004  * The full set of support flags for interfaces and route is shown via;
1005  * '<em>show mfib route flags</em>' and '<em>show mfib itf flags</em>'
1006  * respectively.
1007  * @cliexpar
1008  * Example of how to add a forwarding interface to a route (and create the
1009  * route if it does not exist)
1010  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/0 Forward}
1011  * Example of how to add an accepting interface to a route (and create the
1012  * route if it does not exist)
1013  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/1 Accept}
1014  * Example of changing the route's flags to send signals via the API
1015  * @cliexcmd{ip mroute add 232.1.1.1 Signal}
1016 
1017  ?*/
1018 /* *INDENT-OFF* */
1019 VLIB_CLI_COMMAND (ip_mroute_command, static) =
1020 {
1021  .path = "ip mroute",
1022  .short_help = "ip mroute [add|del] <dst-ip-addr>/<width> [table <table-id>] [rpf-id <ID>] [via <next-hop-ip-addr> [<interface>],",
1023  .function = vnet_ip_mroute_cmd,
1024  .is_mp_safe = 1,
1025 };
1026 /* *INDENT-ON* */
1027 
1028 clib_error_t *
1030 {
1031  u32 fib_index;
1032 
1033  if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index))
1034  return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0,
1035  "invalid sw_if_index");
1036 
1037  fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto,
1038  args->sw_if_index);
1039  if (args->is_add)
1040  {
1041  dpo_id_t proxy_dpo = DPO_INVALID;
1042  l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto),
1043  args->sw_if_index, &proxy_dpo);
1045  &args->prefix,
1047  FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo);
1048  dpo_reset (&proxy_dpo);
1049  }
1050  else
1051  {
1052  fib_table_entry_special_remove (fib_index, &args->prefix,
1054  }
1055  return 0;
1056 }
1057 
1058 u8
1060 {
1061  u32 fib_index;
1062  fib_node_index_t fei;
1063  const dpo_id_t *dpo;
1064  l3_proxy_dpo_t *l3p;
1065  load_balance_t *lb0;
1066 
1068  sw_if_index);
1069  if (fib_index == ~0)
1070  return 0;
1071 
1072  fei = fib_table_lookup_exact_match (fib_index, pfx);
1073  if (fei == FIB_NODE_INDEX_INVALID)
1074  return 0;
1075 
1077  lb0 = load_balance_get (dpo->dpoi_index);
1078  dpo = load_balance_get_bucket_i (lb0, 0);
1079  if (dpo->dpoi_type != DPO_L3_PROXY)
1080  return 0;
1081 
1082  l3p = l3_proxy_dpo_get (dpo->dpoi_index);
1083  return (l3p->l3p_sw_if_index == sw_if_index);
1084 }
1085 
1086 typedef struct ip_container_proxy_walk_ctx_t_
1087 {
1089  void *ctx;
1091 
1092 static fib_table_walk_rc_t
1094 {
1096  const fib_prefix_t *pfx;
1097  const dpo_id_t *dpo;
1098  load_balance_t *lb;
1099  l3_proxy_dpo_t *l3p;
1100 
1101  pfx = fib_entry_get_prefix (fei);
1103  {
1105  lb = load_balance_get (dpo->dpoi_index);
1106  dpo = load_balance_get_bucket_i (lb, 0);
1107  l3p = l3_proxy_dpo_get (dpo->dpoi_index);
1108  ctx->cb (pfx, l3p->l3p_sw_if_index, ctx->ctx);
1109  }
1110 
1111  return FIB_TABLE_WALK_CONTINUE;
1112 }
1113 
1114 void
1116 {
1117  fib_table_t *fib_table;
1119  .cb = cb,
1120  .ctx = ctx,
1121  };
1122 
1123  /* *INDENT-OFF* */
1124  pool_foreach (fib_table, ip4_main.fibs,
1125  ({
1126  fib_table_walk(fib_table->ft_index,
1127  FIB_PROTOCOL_IP4,
1128  ip_container_proxy_fib_table_walk,
1129  &wctx);
1130  }));
1131  pool_foreach (fib_table, ip6_main.fibs,
1132  ({
1133  fib_table_walk(fib_table->ft_index,
1134  FIB_PROTOCOL_IP6,
1135  ip_container_proxy_fib_table_walk,
1136  &wctx);
1137  }));
1138  /* *INDENT-ON* */
1139 }
1140 
1141 clib_error_t *
1143  unformat_input_t * main_input, vlib_cli_command_t * cmd)
1144 {
1145  unformat_input_t _line_input, *line_input = &_line_input;
1146  fib_prefix_t pfx;
1147  u32 is_del, addr_set = 0;
1148  vnet_main_t *vnm;
1149  u32 sw_if_index;
1150 
1151  vnm = vnet_get_main ();
1152  is_del = 0;
1153  sw_if_index = ~0;
1154  clib_memset (&pfx, 0, sizeof (pfx));
1155 
1156  /* Get a line of input. */
1157  if (!unformat_user (main_input, unformat_line_input, line_input))
1158  return 0;
1159 
1160  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1161  {
1162  if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
1163  {
1164  pfx.fp_proto = FIB_PROTOCOL_IP4;
1165  pfx.fp_len = 32;
1166  addr_set = 1;
1167  }
1168  else if (unformat (line_input, "%U",
1169  unformat_ip6_address, &pfx.fp_addr.ip6))
1170  {
1171  pfx.fp_proto = FIB_PROTOCOL_IP6;
1172  pfx.fp_len = 128;
1173  addr_set = 1;
1174  }
1175  else if (unformat (line_input, "%U",
1176  unformat_vnet_sw_interface, vnm, &sw_if_index))
1177  ;
1178  else if (unformat (line_input, "del"))
1179  is_del = 1;
1180  else
1181  {
1182  unformat_free (line_input);
1183  return (clib_error_return (0, "unknown input '%U'",
1184  format_unformat_error, line_input));
1185  }
1186  }
1187 
1188  if (~0 == sw_if_index || !addr_set)
1189  {
1190  unformat_free (line_input);
1191  vlib_cli_output (vm, "interface and address must be set");
1192  return 0;
1193  }
1194 
1196  .prefix = pfx,
1197  .sw_if_index = sw_if_index,
1198  .is_add = !is_del,
1199  };
1201  unformat_free (line_input);
1202  return (NULL);
1203 }
1204 
1205 /* *INDENT-OFF* */
1206 VLIB_CLI_COMMAND (ip_container_command_node, static) = {
1207  .path = "ip container",
1208  .function = ip_container_cmd,
1209  .short_help = "ip container <address> <interface>",
1210  .is_mp_safe = 1,
1211 };
1212 /* *INDENT-ON* */
1213 
1214 clib_error_t *
1216  vlib_cli_command_t * cmd)
1217 {
1218  unformat_input_t _line_input, *line_input = &_line_input;
1219  vnet_main_t *vnm = vnet_get_main ();
1220  fib_prefix_t pfx;
1221  u32 sw_if_index = ~0;
1222  u8 has_proxy;
1223 
1224  if (!unformat_user (main_input, unformat_line_input, line_input))
1225  return 0;
1226  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1227  {
1228  if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
1229  {
1230  pfx.fp_proto = FIB_PROTOCOL_IP4;
1231  pfx.fp_len = 32;
1232  }
1233  else if (unformat (line_input, "%U",
1234  unformat_ip6_address, &pfx.fp_addr.ip6))
1235  {
1236  pfx.fp_proto = FIB_PROTOCOL_IP6;
1237  pfx.fp_len = 128;
1238  }
1239  else if (unformat (line_input, "%U",
1240  unformat_vnet_sw_interface, vnm, &sw_if_index))
1241  ;
1242  else
1243  {
1244  unformat_free (line_input);
1245  return (clib_error_return (0, "unknown input '%U'",
1246  format_unformat_error, line_input));
1247  }
1248  }
1249 
1250  if (~0 == sw_if_index)
1251  {
1252  unformat_free (line_input);
1253  vlib_cli_output (vm, "no interface");
1254  return (clib_error_return (0, "no interface"));
1255  }
1256 
1257  has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index);
1258  vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off");
1259 
1260  unformat_free (line_input);
1261  return 0;
1262 }
1263 
1264 /* *INDENT-OFF* */
1265 VLIB_CLI_COMMAND (show_ip_container_command, static) = {
1266  .path = "show ip container",
1267  .function = show_ip_container_cmd_fn,
1268  .short_help = "show ip container <address> <interface>",
1269  .is_mp_safe = 1,
1270 };
1271 /* *INDENT-ON* */
1272 
1273 /*
1274  * fd.io coding-style-patch-verification: ON
1275  *
1276  * Local Variables:
1277  * eval: (c-set-style "gnu")
1278  * End:
1279  */
fib_protocol_t fp_proto
protocol type
Definition: fib_types.h:212
u8 count
Definition: dhcp.api:208
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:493
clib_error_t * vnet_ip4_table_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:555
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:501
Continue on to the next entry.
Definition: fib_table.h:916
void ip_table_create(fib_protocol_t fproto, u32 table_id, u8 is_api, const u8 *name)
Definition: ip_api.c:579
ip46_address_t fp_src_addr
Definition: mfib_types.h:47
u8 proto
Definition: acl_types.api:47
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:62
fib_node_index_t fib_table_lookup_exact_match(u32 fib_index, const fib_prefix_t *prefix)
Perfom an exact match in the non-forwarding table.
Definition: fib_table.c:97
enum mfib_entry_flags_t_ mfib_entry_flags_t
a
Definition: bitmap.h:538
static uword unformat_dpo(unformat_input_t *input, va_list *args)
Definition: lookup.c:268
A representation of a path as described by a route producer.
Definition: fib_types.h:485
ip_interface_address_t * if_address_pool
Pool of addresses that are assigned to interfaces.
Definition: lookup.h:143
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
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)
Add n paths to an entry (aka route) in the FIB.
Definition: mfib_table.c:325
uword unformat_fib_route_path(unformat_input_t *input, va_list *args)
Unformat a fib_route_path_t from CLI input.
Definition: fib_types.c:457
u32 frp_mitf_flags
MFIB interface flags.
Definition: fib_types.h:554
#define NULL
Definition: clib.h:58
uword mhash_unset(mhash_t *h, void *key, uword *old_value)
Definition: mhash.c:346
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:279
ip_container_proxy_cb_t cb
Definition: lookup.c:1088
const dpo_id_t * fib_entry_contribute_ip_forwarding(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:506
A route the is being &#39;proxied&#39; on behalf of another device.
Definition: fib_source.h:50
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 *rpaths)
Add n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:591
void dpo_copy(dpo_id_t *dst, const dpo_id_t *src)
atomic copy a data-plane object.
Definition: dpo.c:262
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:523
int i
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
const fib_prefix_t * fib_entry_get_prefix(fib_node_index_t fib_entry_index)
Definition: fib_entry.c:1691
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:237
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
dpo_proto_t frp_proto
The protocol of the address below.
Definition: fib_types.h:490
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:237
The data-path object representing L3 proxy.
Definition: l3_proxy_dpo.h:27
static clib_error_t * vnet_ip_route_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:313
mhash_t address_to_if_address_index
Hash table mapping address to index in interface address pool.
Definition: lookup.h:146
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
static clib_error_t * ip_table_bind_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, fib_protocol_t fproto)
Definition: lookup.c:661
enum fib_protocol_t_ fib_protocol_t
Protocol Type.
double f64
Definition: types.h:142
int ip_table_bind(fib_protocol_t fproto, u32 sw_if_index, u32 table_id, u8 is_api)
const dpo_id_t * drop_dpo_get(dpo_proto_t proto)
Definition: drop_dpo.c:25
static clib_error_t * ip6_table_bind_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lookup.c:720
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:498
unformat_function_t unformat_ip4_address
Definition: format.h:68
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:525
vl_api_interface_index_t sw_if_index
Definition: gre.api:59
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:408
format_function_t format_ip6_address_and_length
Definition: format.h:92
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:424
clib_error_t * vnet_ip_container_proxy_add_del(vnet_ip_container_proxy_args_t *args)
Definition: lookup.c:1029
struct _vnet_ip_container_proxy_args vnet_ip_container_proxy_args_t
Aggregate type for a prefix.
Definition: fib_types.h:203
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
unsigned int u32
Definition: types.h:88
#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:1097
u16 fp_len
The mask length.
Definition: fib_types.h:207
bool is_ip6
Definition: ip.api:43
Definition: fib_entry.h:112
unformat_function_t unformat_line_input
Definition: format.h:283
u32 l3p_sw_if_index
The Software interface index on which traffic is l3_proxyd.
Definition: l3_proxy_dpo.h:38
vnet_api_error_t api_errno
Definition: vnet.h:78
u32 rpf_id
Definition: fib_types.api:119
The identity of a DPO is a combination of its type and its instance number/index of objects of that t...
Definition: dpo.h:170
int(* ip_container_proxy_cb_t)(const fib_prefix_t *pfx, u32 sw_if_index, void *ctx)
Definition: lookup.h:272
format_function_t format_vnet_sw_interface_name
Definition: fib_entry.h:116
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:519
ip46_address_t fp_addr
The address type is not deriveable from the fp_addr member.
Definition: fib_types.h:226
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:174
static const dpo_id_t * load_balance_get_bucket_i(const load_balance_t *lb, u32 bucket)
Definition: load_balance.h:229
struct _unformat_input_t unformat_input_t
#define pool_put(P, E)
Free an object E in pool P.
Definition: pool.h:287
The FIB DPO provieds;.
Definition: load_balance.h:106
u8 local_next_by_ip_protocol[256]
Table mapping ip protocol to ip[46]-local node next index.
Definition: lookup.h:177
ip6_main_t ip6_main
Definition: ip6_forward.c:2703
clib_error_t * ip_container_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:1142
static uword mhash_set(mhash_t *h, void *key, uword new_value, uword *old_value)
Definition: mhash.h:117
vl_api_address_t dst
Definition: gre.api:61
vlib_main_t * vm
Definition: in2out_ed.c:1810
clib_error_t * vnet_ip_table_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd, fib_protocol_t fproto)
Definition: lookup.c:494
clib_error_t * vnet_ip_mroute_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:784
unformat_function_t unformat_ip6_address
Definition: format.h:89
u32 classify_table_index
Definition: fib_types.api:68
u8 ip6[16]
Definition: one.api:477
int fib_entry_is_sourced(fib_node_index_t fib_entry_index, fib_source_t source)
uword unformat_mfib_entry_flags(unformat_input_t *input, va_list *args)
Definition: mfib_types.c:218
void fib_table_entry_path_remove2(u32 fib_index, const fib_prefix_t *prefix, fib_source_t source, fib_route_path_t *rpaths)
Remove n paths to an entry (aka route) in the FIB.
Definition: fib_table.c:640
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
void mhash_init(mhash_t *h, uword n_value_bytes, uword n_key_bytes)
Definition: mhash.c:168
From the CLI.
Definition: fib_source.h:76
enum fib_table_walk_rc_t_ fib_table_walk_rc_t
return code controlling how a table walk proceeds
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:342
struct ip_container_proxy_walk_ctx_t_ ip_container_proxy_walk_ctx_t
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:886
void ip_table_delete(fib_protocol_t fproto, u32 table_id, u8 is_api)
Definition: ip_api.c:457
#define clib_warning(format, args...)
Definition: error.h:59
static fib_table_walk_rc_t ip_container_proxy_fib_table_walk(fib_node_index_t fei, void *arg)
Definition: lookup.c:1093
u32 fib_node_index_t
A typedef of a node index.
Definition: fib_types.h:30
void ip_lookup_init(ip_lookup_main_t *lm, u32 is_ip6)
Definition: lookup.c:202
void ip_container_proxy_walk(ip_container_proxy_cb_t cb, void *ctx)
Definition: lookup.c:1115
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:186
string name[64]
Definition: ip.api:44
Aggregate 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:180
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:152
#define foreach_flow_hash_bit
Definition: lookup.h:72
u32 * if_address_pool_index_by_sw_if_index
Head of doubly linked list of interface addresses for each software interface.
Definition: lookup.h:150
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:324
u32 fib_table_get_table_id_for_sw_if_index(fib_protocol_t proto, u32 sw_if_index)
Get the Table-ID of the FIB bound to the interface.
Definition: fib_table.c:1073
static uword * mhash_get(mhash_t *h, const void *key)
Definition: mhash.h:110
static load_balance_t * load_balance_get(index_t lbi)
Definition: load_balance.h:220
fib_route_path_flags_t frp_flags
flags on the path
Definition: fib_types.h:595
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:260
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
vl_api_ip4_address_t hi
Definition: arp.api:37
static l3_proxy_dpo_t * l3_proxy_dpo_get(index_t index)
Definition: l3_proxy_dpo.h:58
#define unformat_parse_error(input)
Definition: format.h:269
static clib_error_t * ip4_table_bind_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
Definition: lookup.c:712
fib_protocol_t fp_proto
protocol type
Definition: mfib_types.h:33
static uword vnet_sw_interface_is_api_valid(vnet_main_t *vnm, u32 sw_if_index)
clib_error_t * vnet_ip6_table_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:562
index_t dpoi_index
the index of objects of that type
Definition: dpo.h:186
static clib_error_t * ip_sw_interface_add_del(vnet_main_t *vnm, u32 sw_if_index, u32 is_add)
Definition: lookup.c:187
#define FIB_NODE_INDEX_INVALID
Definition: fib_types.h:31
A for-us/local path.
Definition: fib_types.h:338
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
mhash_t prefix_to_if_prefix_index
Hash table mapping prefix to index in interface prefix pool.
Definition: lookup.h:156
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:555
u64 uword
Definition: types.h:112
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
u32 is_ip6
1 for ip6; 0 for ip4.
Definition: lookup.h:171
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
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
clib_error_t * show_ip_container_cmd_fn(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:1215
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:1079
#define clib_error_return_code(e, code, flags, args...)
Definition: error.h:93
u8 ip_container_proxy_is_set(fib_prefix_t *pfx, u32 sw_if_index)
Definition: lookup.c:1059
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:110
void dpo_reset(dpo_id_t *dpo)
reset a DPO ID The DPO will be unlocked.
Definition: dpo.c:232
u8 * format_ip_flow_hash_config(u8 *s, va_list *args)
Definition: lookup.c:245
u32 ip4
Definition: one.api:440
u8 * format_ip_adjacency_packet_data(u8 *s, va_list *args)
Definition: lookup.c:257
u16 fp_len
The mask length.
Definition: mfib_types.h:28
u32 table_id
Definition: fib_types.api:118
#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:487
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:407
u8 frp_weight
[un]equal cost path weight
Definition: fib_types.h:585
struct fib_table_t_ * fibs
Definition: ip6.h:183
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:689
VNET_SW_INTERFACE_ADD_DEL_FUNCTION(ip_sw_interface_add_del)
void l3_proxy_dpo_add_or_lock(dpo_proto_t proto, u32 sw_if_index, dpo_id_t *dpo)
Definition: l3_proxy_dpo.c:56
const ip46_address_t zero_addr
Definition: lookup.c:307
uword unformat(unformat_input_t *i, const char *fmt,...)
Definition: unformat.c:978
u32 fib_result_n_bytes
Number of bytes in a fib result.
Definition: lookup.h:168
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:171
A protocol Independent FIB table.
Definition: fib_table.h:71
format_function_t * format_address_and_length
Either format_ip4_address_and_length or format_ip6_address_and_length.
Definition: lookup.h:174
format_function_t format_ip4_address_and_length
Definition: format.h:74