FD.io VPP  v20.09-64-g4f7b92f0a
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 
60 static clib_error_t *
62 {
64  lookup_main.if_address_pool_index_by_sw_if_index,
65  sw_if_index, ~0);
67  lookup_main.if_address_pool_index_by_sw_if_index,
68  sw_if_index, ~0);
69 
70  return (NULL);
71 }
72 
74 
75 void
77 {
78  if (!lm->fib_result_n_bytes)
79  lm->fib_result_n_bytes = sizeof (uword);
80 
81  lm->is_ip6 = is_ip6;
83  sizeof (ip_interface_prefix_key_t));
84  if (is_ip6)
85  {
88  sizeof (ip6_address_fib_t));
89  }
90  else
91  {
94  sizeof (ip4_address_fib_t));
95  }
96 
97  {
98  int i;
99 
100  /* Setup all IP protocols to be punted and builtin-unknown. */
101  for (i = 0; i < 256; i++)
102  {
105  }
106 
108  lm->local_next_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
109  IP_PROTOCOL_ICMP] = IP_LOCAL_NEXT_ICMP;
110  lm->builtin_protocol_by_ip_protocol[IP_PROTOCOL_UDP] =
112  lm->builtin_protocol_by_ip_protocol[is_ip6 ? IP_PROTOCOL_ICMP6 :
113  IP_PROTOCOL_ICMP] =
115  }
116 }
117 
118 u8 *
119 format_ip_flow_hash_config (u8 * s, va_list * args)
120 {
121  flow_hash_config_t flow_hash_config = va_arg (*args, u32);
122 
123 #define _(n,v) if (flow_hash_config & v) s = format (s, "%s ", #n);
125 #undef _
126 
127  return s;
128 }
129 
130 u8 *
131 format_ip_adjacency_packet_data (u8 * s, va_list * args)
132 {
133  u8 *packet_data = va_arg (*args, u8 *);
134  u32 n_packet_data_bytes = va_arg (*args, u32);
135 
136  s = format (s, "%U", format_hex_bytes, packet_data, n_packet_data_bytes);
137 
138  return s;
139 }
140 
141 static uword
142 unformat_dpo (unformat_input_t * input, va_list * args)
143 {
144  dpo_id_t *dpo = va_arg (*args, dpo_id_t *);
145  fib_protocol_t fp = va_arg (*args, int);
147 
148  proto = fib_proto_to_dpo (fp);
149 
150  if (unformat (input, "drop"))
151  dpo_copy (dpo, drop_dpo_get (proto));
152  else if (unformat (input, "punt"))
153  dpo_copy (dpo, punt_dpo_get (proto));
154  else if (unformat (input, "local"))
155  receive_dpo_add_or_lock (proto, ~0, NULL, dpo);
156  else if (unformat (input, "null-send-unreach"))
158  else if (unformat (input, "null-send-prohibit"))
160  else if (unformat (input, "null"))
162  else if (unformat (input, "classify"))
163  {
165 
166  if (!unformat (input, "%d", &classify_table_index))
167  {
168  clib_warning ("classify adj must specify table index");
169  return 0;
170  }
171 
172  dpo_set (dpo, DPO_CLASSIFY, proto,
173  classify_dpo_create (proto, classify_table_index));
174  }
175  else
176  return 0;
177 
178  return 1;
179 }
180 
181 const ip46_address_t zero_addr = {
182  .as_u64 = {
183  0, 0},
184 };
185 
186 static clib_error_t *
188  unformat_input_t * main_input, vlib_cli_command_t * cmd)
189 {
190  unformat_input_t _line_input, *line_input = &_line_input;
191  u32 table_id, is_del, fib_index, payload_proto;
192  dpo_id_t dpo = DPO_INVALID, *dpos = NULL;
193  fib_route_path_t *rpaths = NULL, rpath;
194  fib_prefix_t *prefixs = NULL, pfx;
195  clib_error_t *error = NULL;
196  f64 count;
197  int i;
198 
199  is_del = 0;
200  table_id = 0;
201  count = 1;
202  clib_memset (&pfx, 0, sizeof (pfx));
203 
204  /* Get a line of input. */
205  if (!unformat_user (main_input, unformat_line_input, line_input))
206  return 0;
207 
208  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
209  {
210  clib_memset (&rpath, 0, sizeof (rpath));
211 
212  if (unformat (line_input, "table %d", &table_id))
213  ;
214  else if (unformat (line_input, "count %f", &count))
215  ;
216 
217  else if (unformat (line_input, "%U/%d",
218  unformat_ip4_address, &pfx.fp_addr.ip4, &pfx.fp_len))
219  {
220  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
221  vec_add1 (prefixs, pfx);
222  }
223  else if (unformat (line_input, "%U/%d",
224  unformat_ip6_address, &pfx.fp_addr.ip6, &pfx.fp_len))
225  {
226  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
227  vec_add1 (prefixs, pfx);
228  }
229  else if (unformat (line_input, "via %U",
230  unformat_fib_route_path, &rpath, &payload_proto))
231  {
232  vec_add1 (rpaths, rpath);
233  }
234  else if (vec_len (prefixs) > 0 &&
235  unformat (line_input, "via %U",
236  unformat_dpo, &dpo, prefixs[0].fp_proto))
237  {
238  vec_add1 (dpos, dpo);
239  }
240  else if (unformat (line_input, "del"))
241  is_del = 1;
242  else if (unformat (line_input, "add"))
243  is_del = 0;
244  else
245  {
246  error = unformat_parse_error (line_input);
247  goto done;
248  }
249  }
250 
251  if (vec_len (prefixs) == 0)
252  {
253  error =
254  clib_error_return (0, "expected ip4/ip6 destination address/length.");
255  goto done;
256  }
257 
258  if (!is_del && vec_len (rpaths) + vec_len (dpos) == 0)
259  {
260  error = clib_error_return (0, "expected paths.");
261  goto done;
262  }
263 
264  if (~0 == table_id)
265  {
266  /*
267  * if no table_id is passed we will manipulate the default
268  */
269  fib_index = 0;
270  }
271  else
272  {
273  fib_index = fib_table_find (prefixs[0].fp_proto, table_id);
274 
275  if (~0 == fib_index)
276  {
277  error = clib_error_return (0, "Nonexistent table id %d", table_id);
278  goto done;
279  }
280  }
281 
282  for (i = 0; i < vec_len (prefixs); i++)
283  {
284  if (is_del && 0 == vec_len (rpaths))
285  {
286  fib_table_entry_delete (fib_index, &prefixs[i], FIB_SOURCE_CLI);
287  }
288  else if (!is_del && 1 == vec_len (dpos))
289  {
291  &prefixs[i],
294  &dpos[0]);
295  dpo_reset (&dpos[0]);
296  }
297  else if (vec_len (dpos) > 0)
298  {
299  error =
301  "Load-balancing over multiple special adjacencies is unsupported");
302  goto done;
303  }
304  else if (0 < vec_len (rpaths))
305  {
306  u32 k, n, incr;
307  ip46_address_t dst = prefixs[i].fp_addr;
308  f64 t[2];
309  n = count;
310  t[0] = vlib_time_now (vm);
311  incr = 1 << ((FIB_PROTOCOL_IP4 == prefixs[0].fp_proto ? 32 : 128) -
312  prefixs[i].fp_len);
313 
314  for (k = 0; k < n; k++)
315  {
316  fib_prefix_t rpfx = {
317  .fp_len = prefixs[i].fp_len,
318  .fp_proto = prefixs[i].fp_proto,
319  .fp_addr = dst,
320  };
321 
322  if (is_del)
323  fib_table_entry_path_remove2 (fib_index,
324  &rpfx, FIB_SOURCE_CLI, rpaths);
325  else
326  fib_table_entry_path_add2 (fib_index,
327  &rpfx,
329  FIB_ENTRY_FLAG_NONE, rpaths);
330 
331  if (FIB_PROTOCOL_IP4 == prefixs[0].fp_proto)
332  {
333  dst.ip4.as_u32 =
334  clib_host_to_net_u32 (incr +
335  clib_net_to_host_u32 (dst.
336  ip4.as_u32));
337  }
338  else
339  {
340  int bucket = (incr < 64 ? 0 : 1);
341  dst.ip6.as_u64[bucket] =
342  clib_host_to_net_u64 (incr +
343  clib_net_to_host_u64 (dst.ip6.as_u64
344  [bucket]));
345  }
346  }
347 
348  t[1] = vlib_time_now (vm);
349  if (count > 1)
350  vlib_cli_output (vm, "%.6e routes/sec", count / (t[1] - t[0]));
351  }
352  else
353  {
354  error = clib_error_return (0, "Don't understand what you want...");
355  goto done;
356  }
357  }
358 
359 done:
360  vec_free (dpos);
361  vec_free (prefixs);
362  vec_free (rpaths);
363  unformat_free (line_input);
364  return error;
365 }
366 
367 clib_error_t *
369  unformat_input_t * main_input,
370  vlib_cli_command_t * cmd, fib_protocol_t fproto)
371 {
372  unformat_input_t _line_input, *line_input = &_line_input;
373  clib_error_t *error = NULL;
374  u32 table_id, is_add;
375  u8 *name = NULL;
376 
377  is_add = 1;
378  table_id = ~0;
379 
380  /* Get a line of input. */
381  if (!unformat_user (main_input, unformat_line_input, line_input))
382  return 0;
383 
384  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
385  {
386  if (unformat (line_input, "%d", &table_id))
387  ;
388  else if (unformat (line_input, "del"))
389  is_add = 0;
390  else if (unformat (line_input, "add"))
391  is_add = 1;
392  else if (unformat (line_input, "name %s", &name))
393  ;
394  else
395  {
396  error = unformat_parse_error (line_input);
397  goto done;
398  }
399  }
400 
401  if (~0 == table_id)
402  {
403  error = clib_error_return (0, "No table id");
404  goto done;
405  }
406  else if (0 == table_id)
407  {
408  error = clib_error_return (0, "Can't change the default table");
409  goto done;
410  }
411  else
412  {
413  if (is_add)
414  {
415  ip_table_create (fproto, table_id, 0, name);
416  }
417  else
418  {
419  ip_table_delete (fproto, table_id, 0);
420  }
421  }
422 
423 done:
424  unformat_free (line_input);
425  return error;
426 }
427 
428 clib_error_t *
430  unformat_input_t * main_input, vlib_cli_command_t * cmd)
431 {
432  return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP4));
433 }
434 
435 clib_error_t *
437  unformat_input_t * main_input, vlib_cli_command_t * cmd)
438 {
439  return (vnet_ip_table_cmd (vm, main_input, cmd, FIB_PROTOCOL_IP6));
440 }
441 
442 /* *INDENT-OFF* */
443 VLIB_CLI_COMMAND (vlib_cli_ip_command, static) = {
444  .path = "ip",
445  .short_help = "Internet protocol (IP) commands",
446 };
447 /* *INDENT-ON* */
448 
449 /* *INDENT-OFF* */
450 VLIB_CLI_COMMAND (vlib_cli_ip6_command, static) = {
451  .path = "ip6",
452  .short_help = "Internet protocol version 6 (IPv6) commands",
453 };
454 /* *INDENT-ON* */
455 
456 /* *INDENT-OFF* */
457 VLIB_CLI_COMMAND (vlib_cli_show_ip_command, static) = {
458  .path = "show ip",
459  .short_help = "Internet protocol (IP) show commands",
460 };
461 /* *INDENT-ON* */
462 
463 /* *INDENT-OFF* */
464 VLIB_CLI_COMMAND (vlib_cli_show_ip6_command, static) = {
465  .path = "show ip6",
466  .short_help = "Internet protocol version 6 (IPv6) show commands",
467 };
468 /* *INDENT-ON* */
469 
470 /*?
471  * This command is used to add or delete IPv4 or IPv6 routes. All
472  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
473  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
474  * can be IPv4 or IPv6, but all must be of the same form in a single
475  * command. To display the current set of routes, use the commands
476  * '<em>show ip fib</em>' and '<em>show ip6 fib</em>'.
477  *
478  * @cliexpar
479  * Example of how to add a straight forward static route:
480  * @cliexcmd{ip route add 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
481  * Example of how to delete a straight forward static route:
482  * @cliexcmd{ip route del 6.0.1.2/32 via 6.0.0.1 GigabitEthernet2/0/0}
483  * Mainly for route add/del performance testing, one can add or delete
484  * multiple routes by adding 'count N' to the previous item:
485  * @cliexcmd{ip route add count 10 7.0.0.0/24 via 6.0.0.1 GigabitEthernet2/0/0}
486  * Add multiple routes for the same destination to create equal-cost multipath:
487  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0}
488  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0}
489  * For unequal-cost multipath, specify the desired weights. This
490  * combination of weights results in 3/4 of the traffic following the
491  * second path, 1/4 following the first path:
492  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.1 GigabitEthernet2/0/0 weight 1}
493  * @cliexcmd{ip route add 7.0.0.1/32 via 6.0.0.2 GigabitEthernet2/0/0 weight 3}
494  * To add a route to a particular FIB table (VRF), use:
495  * @cliexcmd{ip route add 172.16.24.0/24 table 7 via GigabitEthernet2/0/0}
496  ?*/
497 /* *INDENT-OFF* */
498 VLIB_CLI_COMMAND (ip_route_command, static) = {
499  .path = "ip route",
500  .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>]",
501  .function = vnet_ip_route_cmd,
502  .is_mp_safe = 1,
503 };
504 
505 /* *INDENT-ON* */
506 /*?
507  * This command is used to add or delete IPv4 Tables. All
508  * Tables must be explicitly added before that can be used. Creating a
509  * table will add both unicast and multicast FIBs
510  *
511  ?*/
512 /* *INDENT-OFF* */
513 VLIB_CLI_COMMAND (ip4_table_command, static) = {
514  .path = "ip table",
515  .short_help = "ip table [add|del] <table-id>",
516  .function = vnet_ip4_table_cmd,
517 };
518 /* *INDENT-ON* */
519 
520 /* *INDENT-ON* */
521 /*?
522  * This command is used to add or delete IPv4 Tables. All
523  * Tables must be explicitly added before that can be used. Creating a
524  * table will add both unicast and multicast FIBs
525  *
526  ?*/
527 /* *INDENT-OFF* */
528 VLIB_CLI_COMMAND (ip6_table_command, static) = {
529  .path = "ip6 table",
530  .short_help = "ip6 table [add|del] <table-id>",
531  .function = vnet_ip6_table_cmd,
532 };
533 
534 static clib_error_t *
536  unformat_input_t * input,
537  vlib_cli_command_t * cmd,
538  fib_protocol_t fproto)
539 {
540  vnet_main_t *vnm = vnet_get_main ();
541  clib_error_t *error = 0;
543  int rv;
544 
545  sw_if_index = ~0;
546 
547  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
548  {
549  error = clib_error_return (0, "unknown interface `%U'",
550  format_unformat_error, input);
551  goto done;
552  }
553 
554  if (unformat (input, "%d", &table_id))
555  ;
556  else
557  {
558  error = clib_error_return (0, "expected table id `%U'",
559  format_unformat_error, input);
560  goto done;
561  }
562 
563  rv = ip_table_bind (fproto, sw_if_index, table_id, 0);
564 
565  if (VNET_API_ERROR_ADDRESS_FOUND_FOR_INTERFACE == rv)
566  {
567  error = clib_error_return (0, "IP addresses are still present on %U",
569  vnet_get_main(),
570  sw_if_index);
571  }
572  else if (VNET_API_ERROR_NO_SUCH_FIB == rv)
573  {
574  error = clib_error_return (0, "no such table %d", table_id);
575  }
576  else if (0 != rv)
577  {
578  error = clib_error_return (0, "unknown error");
579  }
580 
581  done:
582  return error;
583 }
584 
585 static clib_error_t *
587  unformat_input_t * input,
588  vlib_cli_command_t * cmd)
589 {
590  return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP4));
591 }
592 
593 static clib_error_t *
595  unformat_input_t * input,
596  vlib_cli_command_t * cmd)
597 {
598  return (ip_table_bind_cmd (vm , input, cmd, FIB_PROTOCOL_IP6));
599 }
600 
601 /*?
602  * Place the indicated interface into the supplied IPv4 FIB table (also known
603  * as a VRF). The FIB table must be created using "ip table add" already. To
604  * display the current IPv4 FIB table, use the command '<em>show ip fib</em>'.
605  * FIB table will only be displayed if a route has been added to the table, or
606  * an IP Address is assigned to an interface in the table (which adds a route
607  * automatically).
608  *
609  * @note IP addresses added after setting the interface IP table are added to
610  * the indicated FIB table. If an IP address is added prior to changing the
611  * table then this is an error. The control plane must remove these addresses
612  * first and then change the table. VPP will not automatically move the
613  * addresses from the old to the new table as it does not know the validity
614  * of such a change.
615  *
616  * @cliexpar
617  * Example of how to add an interface to an IPv4 FIB table (where 2 is the table-id):
618  * @cliexcmd{set interface ip table GigabitEthernet2/0/0 2}
619  ?*/
620 /* *INDENT-OFF* */
621 VLIB_CLI_COMMAND (set_interface_ip_table_command, static) =
622 {
623  .path = "set interface ip table",
624  .function = ip4_table_bind_cmd,
625  .short_help = "set interface ip table <interface> <table-id>",
626 };
627 /* *INDENT-ON* */
628 
629 /*?
630  * Place the indicated interface into the supplied IPv6 FIB table (also known
631  * as a VRF). The FIB table must be created using "ip6 table add" already. To
632  * display the current IPv6 FIB table, use the command '<em>show ip6 fib</em>'.
633  * FIB table will only be displayed if a route has been added to the table, or
634  * an IP Address is assigned to an interface in the table (which adds a route
635  * automatically).
636  *
637  * @note IP addresses added after setting the interface IP table are added to
638  * the indicated FIB table. If an IP address is added prior to changing the
639  * table then this is an error. The control plane must remove these addresses
640  * first and then change the table. VPP will not automatically move the
641  * addresses from the old to the new table as it does not know the validity
642  * of such a change.
643  *
644  * @cliexpar
645  * Example of how to add an interface to an IPv6 FIB table (where 2 is the table-id):
646  * @cliexcmd{set interface ip6 table GigabitEthernet2/0/0 2}
647  ?*/
648 /* *INDENT-OFF* */
649 VLIB_CLI_COMMAND (set_interface_ip6_table_command, static) =
650 {
651  .path = "set interface ip6 table",
652  .function = ip6_table_bind_cmd,
653  .short_help = "set interface ip6 table <interface> <table-id>"
654 };
655 /* *INDENT-ON* */
656 
657 clib_error_t *
659  unformat_input_t * main_input, vlib_cli_command_t * cmd)
660 {
661  unformat_input_t _line_input, *line_input = &_line_input;
662  fib_route_path_t rpath, *rpaths = NULL;
663  clib_error_t *error = NULL;
664  u32 table_id, is_del, payload_proto;
665  mfib_prefix_t pfx;
666  u32 fib_index;
667  mfib_entry_flags_t eflags = 0;
668  u32 gcount, scount, ss, gg, incr;
669  f64 timet[2];
671 
672  gcount = scount = 1;
673  is_del = 0;
674  table_id = 0;
675  clib_memset (&pfx, 0, sizeof (pfx));
676  clib_memset (&rpath, 0, sizeof (rpath));
677  rpath.frp_sw_if_index = ~0;
678 
679  /* Get a line of input. */
680  if (!unformat_user (main_input, unformat_line_input, line_input))
681  return 0;
682 
683  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
684  {
685  if (unformat (line_input, "table %d", &table_id))
686  ;
687  else if (unformat (line_input, "del"))
688  is_del = 1;
689  else if (unformat (line_input, "add"))
690  is_del = 0;
691  else if (unformat (line_input, "rpf-id %d", &rpf_id))
692  ;
693  else if (unformat (line_input, "scount %d", &scount))
694  ;
695  else if (unformat (line_input, "gcount %d", &gcount))
696  ;
697  else if (unformat (line_input, "%U %U",
699  &pfx.fp_src_addr.ip4,
701  {
702  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
703  pfx.fp_len = 64;
704  }
705  else if (unformat (line_input, "%U %U",
707  &pfx.fp_src_addr.ip6,
709  {
710  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
711  pfx.fp_len = 256;
712  }
713  else if (unformat (line_input, "%U/%d",
715  &pfx.fp_grp_addr.ip4, &pfx.fp_len))
716  {
717  clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
718  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
719  }
720  else if (unformat (line_input, "%U/%d",
722  &pfx.fp_grp_addr.ip6, &pfx.fp_len))
723  {
724  clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
725  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
726  }
727  else if (unformat (line_input, "%U",
729  {
730  clib_memset (&pfx.fp_src_addr.ip4, 0, sizeof (pfx.fp_src_addr.ip4));
731  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP4;
732  pfx.fp_len = 32;
733  }
734  else if (unformat (line_input, "%U",
736  {
737  clib_memset (&pfx.fp_src_addr.ip6, 0, sizeof (pfx.fp_src_addr.ip6));
738  payload_proto = pfx.fp_proto = FIB_PROTOCOL_IP6;
739  pfx.fp_len = 128;
740  }
741  else if (unformat (line_input, "via local Forward"))
742  {
743  clib_memset (&rpath.frp_addr, 0, sizeof (rpath.frp_addr));
744  rpath.frp_sw_if_index = ~0;
745  rpath.frp_weight = 1;
747  /*
748  * set the path proto appropriately for the prefix
749  */
750  rpath.frp_proto = fib_proto_to_dpo (pfx.fp_proto);
752 
753  vec_add1 (rpaths, rpath);
754  }
755  else if (unformat (line_input, "via %U",
756  unformat_fib_route_path, &rpath, &payload_proto))
757  {
758  vec_add1 (rpaths, rpath);
759  }
760  else if (unformat (line_input, "%U",
761  unformat_mfib_entry_flags, &eflags))
762  ;
763  else
764  {
765  error = unformat_parse_error (line_input);
766  goto done;
767  }
768  }
769 
770  if (~0 == table_id)
771  {
772  /*
773  * if no table_id is passed we will manipulate the default
774  */
775  fib_index = 0;
776  }
777  else
778  {
779  fib_index = mfib_table_find (pfx.fp_proto, table_id);
780 
781  if (~0 == fib_index)
782  {
783  error = clib_error_return (0, "Nonexistent table id %d", table_id);
784  goto done;
785  }
786  }
787 
788  timet[0] = vlib_time_now (vm);
789 
790  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
791  {
792  incr = 1 << (32 - (pfx.fp_len % 32));
793  }
794  else
795  {
796  incr = 1 << (128 - (pfx.fp_len % 128));
797  }
798 
799  for (ss = 0; ss < scount; ss++)
800  {
801  for (gg = 0; gg < gcount; gg++)
802  {
803  if (is_del && 0 == vec_len (rpaths))
804  {
805  /* no path provided => route delete */
806  mfib_table_entry_delete (fib_index, &pfx, MFIB_SOURCE_CLI);
807  }
808  else if (eflags || (MFIB_RPF_ID_NONE != rpf_id))
809  {
810  mfib_table_entry_update (fib_index, &pfx, MFIB_SOURCE_CLI,
811  rpf_id, eflags);
812  }
813  else
814  {
815  if (is_del)
816  mfib_table_entry_path_remove (fib_index,
817  &pfx, MFIB_SOURCE_CLI, rpaths);
818  else
819  mfib_table_entry_path_update (fib_index,
820  &pfx, MFIB_SOURCE_CLI, rpaths);
821  }
822 
823  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
824  {
825  pfx.fp_grp_addr.ip4.as_u32 =
826  clib_host_to_net_u32 (incr +
827  clib_net_to_host_u32 (pfx.
828  fp_grp_addr.ip4.
829  as_u32));
830  }
831  else
832  {
833  int bucket = (incr < 64 ? 0 : 1);
834  pfx.fp_grp_addr.ip6.as_u64[bucket] =
835  clib_host_to_net_u64 (incr +
836  clib_net_to_host_u64 (pfx.
837  fp_grp_addr.ip6.as_u64
838  [bucket]));
839 
840  }
841  }
842  if (FIB_PROTOCOL_IP4 == pfx.fp_proto)
843  {
844  pfx.fp_src_addr.ip4.as_u32 =
845  clib_host_to_net_u32 (1 +
846  clib_net_to_host_u32 (pfx.fp_src_addr.
847  ip4.as_u32));
848  }
849  else
850  {
851  pfx.fp_src_addr.ip6.as_u64[1] =
852  clib_host_to_net_u64 (1 +
853  clib_net_to_host_u64 (pfx.fp_src_addr.
854  ip6.as_u64[1]));
855  }
856  }
857 
858  timet[1] = vlib_time_now (vm);
859 
860  if (scount > 1 || gcount > 1)
861  vlib_cli_output (vm, "%.6e routes/sec",
862  (scount * gcount) / (timet[1] - timet[0]));
863 
864 done:
865  vec_free (rpaths);
866  unformat_free (line_input);
867 
868  return error;
869 }
870 
871 /*?
872  * This command is used to add or delete IPv4 or IPv6 multicast routes. All
873  * IP Addresses ('<em><dst-ip-addr>/<width></em>',
874  * '<em><next-hop-ip-addr></em>' and '<em><adj-hop-ip-addr></em>')
875  * can be IPv4 or IPv6, but all must be of the same form in a single
876  * command. To display the current set of routes, use the commands
877  * '<em>show ip mfib</em>' and '<em>show ip6 mfib</em>'.
878  * The full set of support flags for interfaces and route is shown via;
879  * '<em>show mfib route flags</em>' and '<em>show mfib itf flags</em>'
880  * respectively.
881  * @cliexpar
882  * Example of how to add a forwarding interface to a route (and create the
883  * route if it does not exist)
884  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/0 Forward}
885  * Example of how to add an accepting interface to a route (and create the
886  * route if it does not exist)
887  * @cliexcmd{ip mroute add 232.1.1.1 via GigabitEthernet2/0/1 Accept}
888  * Example of changing the route's flags to send signals via the API
889  * @cliexcmd{ip mroute add 232.1.1.1 Signal}
890 
891  ?*/
892 /* *INDENT-OFF* */
893 VLIB_CLI_COMMAND (ip_mroute_command, static) =
894 {
895  .path = "ip mroute",
896  .short_help = "ip mroute [add|del] <dst-ip-addr>/<width> [table <table-id>] [rpf-id <ID>] [via <next-hop-ip-addr> [<interface>],",
897  .function = vnet_ip_mroute_cmd,
898  .is_mp_safe = 1,
899 };
900 /* *INDENT-ON* */
901 
902 clib_error_t *
904 {
905  u32 fib_index;
906 
907  if (!vnet_sw_interface_is_api_valid (vnet_get_main (), args->sw_if_index))
908  return clib_error_return_code (0, VNET_API_ERROR_INVALID_INTERFACE, 0,
909  "invalid sw_if_index");
910 
911  fib_index = fib_table_get_table_id_for_sw_if_index (args->prefix.fp_proto,
912  args->sw_if_index);
913  if (args->is_add)
914  {
915  dpo_id_t proxy_dpo = DPO_INVALID;
916  l3_proxy_dpo_add_or_lock (fib_proto_to_dpo (args->prefix.fp_proto),
917  args->sw_if_index, &proxy_dpo);
919  &args->prefix,
921  FIB_ENTRY_FLAG_EXCLUSIVE, &proxy_dpo);
922  dpo_reset (&proxy_dpo);
923  }
924  else
925  {
926  fib_table_entry_special_remove (fib_index, &args->prefix,
928  }
929  return 0;
930 }
931 
932 u8
934 {
935  u32 fib_index;
936  fib_node_index_t fei;
937  const dpo_id_t *dpo;
938  l3_proxy_dpo_t *l3p;
939  load_balance_t *lb0;
940 
942  sw_if_index);
943  if (fib_index == ~0)
944  return 0;
945 
946  fei = fib_table_lookup_exact_match (fib_index, pfx);
947  if (fei == FIB_NODE_INDEX_INVALID)
948  return 0;
949 
951  lb0 = load_balance_get (dpo->dpoi_index);
952  dpo = load_balance_get_bucket_i (lb0, 0);
953  if (dpo->dpoi_type != DPO_L3_PROXY)
954  return 0;
955 
956  l3p = l3_proxy_dpo_get (dpo->dpoi_index);
957  return (l3p->l3p_sw_if_index == sw_if_index);
958 }
959 
960 typedef struct ip_container_proxy_walk_ctx_t_
961 {
963  void *ctx;
965 
966 static fib_table_walk_rc_t
968 {
970  const fib_prefix_t *pfx;
971  const dpo_id_t *dpo;
972  load_balance_t *lb;
973  l3_proxy_dpo_t *l3p;
974 
975  pfx = fib_entry_get_prefix (fei);
977  {
979  lb = load_balance_get (dpo->dpoi_index);
980  dpo = load_balance_get_bucket_i (lb, 0);
981  l3p = l3_proxy_dpo_get (dpo->dpoi_index);
982  ctx->cb (pfx, l3p->l3p_sw_if_index, ctx->ctx);
983  }
984 
986 }
987 
988 void
990 {
991  fib_table_t *fib_table;
993  .cb = cb,
994  .ctx = ctx,
995  };
996 
997  /* *INDENT-OFF* */
998  pool_foreach (fib_table, ip4_main.fibs,
999  ({
1000  fib_table_walk(fib_table->ft_index,
1001  FIB_PROTOCOL_IP4,
1002  ip_container_proxy_fib_table_walk,
1003  &wctx);
1004  }));
1005  pool_foreach (fib_table, ip6_main.fibs,
1006  ({
1007  fib_table_walk(fib_table->ft_index,
1008  FIB_PROTOCOL_IP6,
1009  ip_container_proxy_fib_table_walk,
1010  &wctx);
1011  }));
1012  /* *INDENT-ON* */
1013 }
1014 
1015 clib_error_t *
1017  unformat_input_t * main_input, vlib_cli_command_t * cmd)
1018 {
1019  unformat_input_t _line_input, *line_input = &_line_input;
1020  fib_prefix_t pfx;
1021  u32 is_del, addr_set = 0;
1022  vnet_main_t *vnm;
1023  u32 sw_if_index;
1024 
1025  vnm = vnet_get_main ();
1026  is_del = 0;
1027  sw_if_index = ~0;
1028  clib_memset (&pfx, 0, sizeof (pfx));
1029 
1030  /* Get a line of input. */
1031  if (!unformat_user (main_input, unformat_line_input, line_input))
1032  return 0;
1033 
1034  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1035  {
1036  if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
1037  {
1038  pfx.fp_proto = FIB_PROTOCOL_IP4;
1039  pfx.fp_len = 32;
1040  addr_set = 1;
1041  }
1042  else if (unformat (line_input, "%U",
1043  unformat_ip6_address, &pfx.fp_addr.ip6))
1044  {
1045  pfx.fp_proto = FIB_PROTOCOL_IP6;
1046  pfx.fp_len = 128;
1047  addr_set = 1;
1048  }
1049  else if (unformat (line_input, "%U",
1050  unformat_vnet_sw_interface, vnm, &sw_if_index))
1051  ;
1052  else if (unformat (line_input, "del"))
1053  is_del = 1;
1054  else
1055  {
1056  unformat_free (line_input);
1057  return (clib_error_return (0, "unknown input '%U'",
1058  format_unformat_error, line_input));
1059  }
1060  }
1061 
1062  if (~0 == sw_if_index || !addr_set)
1063  {
1064  unformat_free (line_input);
1065  vlib_cli_output (vm, "interface and address must be set");
1066  return 0;
1067  }
1068 
1070  .prefix = pfx,
1071  .sw_if_index = sw_if_index,
1072  .is_add = !is_del,
1073  };
1075  unformat_free (line_input);
1076  return (NULL);
1077 }
1078 
1079 /* *INDENT-OFF* */
1080 VLIB_CLI_COMMAND (ip_container_command_node, static) = {
1081  .path = "ip container",
1082  .function = ip_container_cmd,
1083  .short_help = "ip container <address> <interface>",
1084  .is_mp_safe = 1,
1085 };
1086 /* *INDENT-ON* */
1087 
1088 clib_error_t *
1090  vlib_cli_command_t * cmd)
1091 {
1092  unformat_input_t _line_input, *line_input = &_line_input;
1093  vnet_main_t *vnm = vnet_get_main ();
1094  fib_prefix_t pfx;
1095  u32 sw_if_index = ~0;
1096  u8 has_proxy;
1097 
1098  if (!unformat_user (main_input, unformat_line_input, line_input))
1099  return 0;
1100  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1101  {
1102  if (unformat (line_input, "%U", unformat_ip4_address, &pfx.fp_addr.ip4))
1103  {
1104  pfx.fp_proto = FIB_PROTOCOL_IP4;
1105  pfx.fp_len = 32;
1106  }
1107  else if (unformat (line_input, "%U",
1108  unformat_ip6_address, &pfx.fp_addr.ip6))
1109  {
1110  pfx.fp_proto = FIB_PROTOCOL_IP6;
1111  pfx.fp_len = 128;
1112  }
1113  else if (unformat (line_input, "%U",
1114  unformat_vnet_sw_interface, vnm, &sw_if_index))
1115  ;
1116  else
1117  {
1118  unformat_free (line_input);
1119  return (clib_error_return (0, "unknown input '%U'",
1120  format_unformat_error, line_input));
1121  }
1122  }
1123 
1124  if (~0 == sw_if_index)
1125  {
1126  unformat_free (line_input);
1127  vlib_cli_output (vm, "no interface");
1128  return (clib_error_return (0, "no interface"));
1129  }
1130 
1131  has_proxy = ip_container_proxy_is_set (&pfx, sw_if_index);
1132  vlib_cli_output (vm, "ip container proxy is: %s", has_proxy ? "on" : "off");
1133 
1134  unformat_free (line_input);
1135  return 0;
1136 }
1137 
1138 /* *INDENT-OFF* */
1139 VLIB_CLI_COMMAND (show_ip_container_command, static) = {
1140  .path = "show ip container",
1141  .function = show_ip_container_cmd_fn,
1142  .short_help = "show ip container <address> <interface>",
1143  .is_mp_safe = 1,
1144 };
1145 /* *INDENT-ON* */
1146 
1147 /*
1148  * fd.io coding-style-patch-verification: ON
1149  *
1150  * Local Variables:
1151  * eval: (c-set-style "gnu")
1152  * End:
1153  */
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:429
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:506
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:666
ip46_address_t fp_src_addr
Definition: mfib_types.h: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:67
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
static uword unformat_dpo(unformat_input_t *input, va_list *args)
Definition: lookup.c:142
A representation of a path as described by a route producer.
Definition: fib_types.h:490
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:521
u32 frp_mitf_flags
MFIB interface flags.
Definition: fib_types.h:559
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static f64 vlib_time_now(vlib_main_t *vm)
Definition: main.h:333
ip_container_proxy_cb_t cb
Definition: lookup.c:962
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:592
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
vlib_main_t * vm
Definition: in2out_ed.c:1582
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:495
unformat_function_t unformat_vnet_sw_interface
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:187
mhash_t address_to_if_address_index
Hash table mapping address to index in interface address pool.
Definition: lookup.h:151
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:535
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:594
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
unformat_function_t unformat_ip4_address
Definition: format.h:68
u32 frp_sw_if_index
The interface.
Definition: fib_types.h:530
#define MFIB_RPF_ID_NONE
Definition: fib_types.h:413
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:903
vl_api_ip6_address_t ip6
Definition: one.api:424
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
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
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:215
Definition: fib_entry.h:116
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:48
vl_api_ip_proto_t proto
Definition: acl_types.api:50
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
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:182
vl_api_ip4_address_t ip4
Definition: one.api:376
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
clib_error_t * ip_container_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:1016
vl_api_address_t dst
Definition: gre.api:55
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:368
clib_error_t * vnet_ip_mroute_cmd(vlib_main_t *vm, unformat_input_t *main_input, vlib_cli_command_t *cmd)
Definition: lookup.c:658
unformat_function_t unformat_ip6_address
Definition: format.h:89
u32 classify_table_index
Definition: fib_types.api:68
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
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
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:380
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:483
#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:967
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:76
void ip_container_proxy_walk(ip_container_proxy_cb_t cb, void *ctx)
Definition: lookup.c:989
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:185
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
#define foreach_flow_hash_bit
Definition: lookup.h:72
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
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
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:600
dpo_proto_t fib_proto_to_dpo(fib_protocol_t fib_proto)
Definition: fib_types.c:324
u32 flow_hash_config_t
A flow hash configuration is a mask of the flow hash options.
Definition: lookup.h:84
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:586
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:436
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:61
#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:161
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:176
u32 table_id
Definition: wireguard.api:100
#define DPO_INVALID
An initialiser for DPOs declared on the stack.
Definition: dpo.h:197
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:1089
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:1144
#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:933
struct fib_table_t_ * fibs
Vector of FIBs.
Definition: ip4.h:111
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:119
u8 * format_ip_adjacency_packet_data(u8 *s, va_list *args)
Definition: lookup.c:131
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:556
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:590
struct fib_table_t_ * fibs
Definition: ip6.h:184
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:181
vl_api_interface_index_t sw_if_index
Definition: wireguard.api:33
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:173
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:179
format_function_t format_ip4_address_and_length
Definition: format.h:74