FD.io VPP  v20.09-64-g4f7b92f0a
Vector Packet Processing
interface_cli.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  * interface_cli.c: interface CLI
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 /**
41  * @file
42  * @brief Interface CLI.
43  *
44  * Source code for several CLI interface commands.
45  *
46  */
47 
48 #include <vnet/vnet.h>
49 #include <vnet/ip/ip.h>
50 #include <vppinfra/bitmap.h>
51 #include <vnet/fib/ip4_fib.h>
52 #include <vnet/fib/ip6_fib.h>
53 #include <vnet/l2/l2_output.h>
54 #include <vnet/l2/l2_input.h>
56 
57 static int
58 compare_interface_names (void *a1, void *a2)
59 {
60  u32 *hi1 = a1;
61  u32 *hi2 = a2;
62 
63  return vnet_hw_interface_compare (vnet_get_main (), *hi1, *hi2);
64 }
65 
66 static clib_error_t *
68  unformat_input_t * input,
69  vlib_cli_command_t * cmd, int is_show)
70 {
71  clib_error_t *error = 0;
72  vnet_main_t *vnm = vnet_get_main ();
75  u32 hw_if_index, *hw_if_indices = 0;
76  int i, verbose = -1, show_bond = 0;
77 
79  {
80  /* See if user wants to show a specific interface. */
81  if (unformat
82  (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
83  vec_add1 (hw_if_indices, hw_if_index);
84 
85  /* See if user wants to show an interface with a specific hw_if_index. */
86  else if (unformat (input, "%u", &hw_if_index))
87  vec_add1 (hw_if_indices, hw_if_index);
88 
89  else if (unformat (input, "verbose"))
90  verbose = 1; /* this is also the default */
91 
92  else if (unformat (input, "detail"))
93  verbose = 2;
94 
95  else if (unformat (input, "brief"))
96  verbose = 0;
97 
98  else if (unformat (input, "bond"))
99  {
100  show_bond = 1;
101  if (verbose < 0)
102  verbose = 0; /* default to brief for link bonding */
103  }
104 
105  else
106  {
107  error = clib_error_return (0, "unknown input `%U'",
108  format_unformat_error, input);
109  goto done;
110  }
111  }
112 
113  /* Gather interfaces. */
114  if (vec_len (hw_if_indices) == 0)
115  pool_foreach (hi, im->hw_interfaces,
116  vec_add1 (hw_if_indices, hi - im->hw_interfaces));
117 
118  if (verbose < 0)
119  verbose = 1; /* default to verbose (except bond) */
120 
121  if (is_show)
122  {
123  /* Sort by name. */
125 
126  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm, 0, verbose);
127  for (i = 0; i < vec_len (hw_if_indices); i++)
128  {
129  hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
130  if (show_bond == 0) /* show all interfaces */
131  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm,
132  hi, verbose);
133  else if ((hi->bond_info) &&
135  { /* show only bonded interface and all its slave interfaces */
136  int hw_idx;
137  vnet_hw_interface_t *shi;
138  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm,
139  hi, verbose);
140 
141  /* *INDENT-OFF* */
142  clib_bitmap_foreach (hw_idx, hi->bond_info,
143  ({
144  shi = vnet_get_hw_interface(vnm, hw_idx);
145  vlib_cli_output (vm, "%U\n",
146  format_vnet_hw_interface, vnm, shi, verbose);
147  }));
148  /* *INDENT-ON* */
149  }
150  }
151  }
152  else
153  {
154  for (i = 0; i < vec_len (hw_if_indices); i++)
155  {
157 
158  hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
160 
161  if (dc->clear_counters)
162  dc->clear_counters (hi->dev_instance);
163  }
164  }
165 
166 done:
167  vec_free (hw_if_indices);
168  return error;
169 }
170 
171 static clib_error_t *
173  unformat_input_t * input, vlib_cli_command_t * cmd)
174 {
175  return show_or_clear_hw_interfaces (vm, input, cmd, 1 /* is_show */ );
176 }
177 
178 static clib_error_t *
180  unformat_input_t * input, vlib_cli_command_t * cmd)
181 {
182  return show_or_clear_hw_interfaces (vm, input, cmd, 0 /* is_show */ );
183 }
184 
185 
186 /*?
187  * Display more detailed information about all or a list of given interfaces.
188  * The verboseness of the output can be controlled by the following optional
189  * parameters:
190  * - brief: Only show name, index and state (default for bonded interfaces).
191  * - verbose: Also display additional attributes (default for all other interfaces).
192  * - detail: Also display all remaining attributes and extended statistics.
193  *
194  * To limit the output of the command to bonded interfaces and their slave
195  * interfaces, use the '<em>bond</em>' optional parameter.
196  *
197  * @cliexpar
198  * Example of how to display default data for all interfaces:
199  * @cliexstart{show hardware-interfaces}
200  * Name Idx Link Hardware
201  * GigabitEthernet7/0/0 1 up GigabitEthernet7/0/0
202  * Ethernet address ec:f4:bb:c0:bc:fc
203  * Intel e1000
204  * carrier up full duplex speed 1000 mtu 9216
205  * rx queues 1, rx desc 1024, tx queues 3, tx desc 1024
206  * cpu socket 0
207  * GigabitEthernet7/0/1 2 up GigabitEthernet7/0/1
208  * Ethernet address ec:f4:bb:c0:bc:fd
209  * Intel e1000
210  * carrier up full duplex speed 1000 mtu 9216
211  * rx queues 1, rx desc 1024, tx queues 3, tx desc 1024
212  * cpu socket 0
213  * VirtualEthernet0/0/0 3 up VirtualEthernet0/0/0
214  * Ethernet address 02:fe:a5:a9:8b:8e
215  * VirtualEthernet0/0/1 4 up VirtualEthernet0/0/1
216  * Ethernet address 02:fe:c0:4e:3b:b0
217  * VirtualEthernet0/0/2 5 up VirtualEthernet0/0/2
218  * Ethernet address 02:fe:1f:73:92:81
219  * VirtualEthernet0/0/3 6 up VirtualEthernet0/0/3
220  * Ethernet address 02:fe:f2:25:c4:68
221  * local0 0 down local0
222  * local
223  * @cliexend
224  * Example of how to display '<em>verbose</em>' data for an interface by name and
225  * software index (where 2 is the software index):
226  * @cliexstart{show hardware-interfaces GigabitEthernet7/0/0 2 verbose}
227  * Name Idx Link Hardware
228  * GigabitEthernet7/0/0 1 up GigabitEthernet7/0/0
229  * Ethernet address ec:f4:bb:c0:bc:fc
230  * Intel e1000
231  * carrier up full duplex speed 1000 mtu 9216
232  * rx queues 1, rx desc 1024, tx queues 3, tx desc 1024
233  * cpu socket 0
234  * GigabitEthernet7/0/1 2 down GigabitEthernet7/0/1
235  * Ethernet address ec:f4:bb:c0:bc:fd
236  * Intel e1000
237  * carrier up full duplex speed 1000 mtu 9216
238  * rx queues 1, rx desc 1024, tx queues 3, tx desc 1024
239  * cpu socket 0
240  * @cliexend
241  ?*/
242 /* *INDENT-OFF* */
243 VLIB_CLI_COMMAND (show_hw_interfaces_command, static) = {
244  .path = "show hardware-interfaces",
245  .short_help = "show hardware-interfaces [brief|verbose|detail] [bond] "
246  "[<interface> [<interface> [..]]] [<sw_idx> [<sw_idx> [..]]]",
247  .function = show_hw_interfaces,
248 };
249 /* *INDENT-ON* */
250 
251 
252 /*?
253  * Clear the extended statistics for all or a list of given interfaces
254  * (statistics associated with the '<em>show hardware-interfaces</em>' command).
255  *
256  * @cliexpar
257  * Example of how to clear the extended statistics for all interfaces:
258  * @cliexcmd{clear hardware-interfaces}
259  * Example of how to clear the extended statistics for an interface by
260  * name and software index (where 2 is the software index):
261  * @cliexcmd{clear hardware-interfaces GigabitEthernet7/0/0 2}
262  ?*/
263 /* *INDENT-OFF* */
264 VLIB_CLI_COMMAND (clear_hw_interface_counters_command, static) = {
265  .path = "clear hardware-interfaces",
266  .short_help = "clear hardware-interfaces "
267  "[<interface> [<interface> [..]]] [<sw_idx> [<sw_idx> [..]]]",
268  .function = clear_hw_interfaces,
269 };
270 /* *INDENT-ON* */
271 
272 static int
273 sw_interface_name_compare (void *a1, void *a2)
274 {
275  vnet_sw_interface_t *si1 = a1;
276  vnet_sw_interface_t *si2 = a2;
277 
279  si1->sw_if_index, si2->sw_if_index);
280 }
281 
282 static clib_error_t *
284  unformat_input_t * input, vlib_cli_command_t * cmd)
285 {
286  clib_error_t *error = 0;
287  vnet_main_t *vnm = vnet_get_main ();
288  unformat_input_t _linput, *linput = &_linput;
290  vnet_sw_interface_t *si, *sorted_sis = 0;
291  u32 sw_if_index = ~(u32) 0;
292  u8 show_addresses = 0;
293  u8 show_features = 0;
294  u8 show_tag = 0;
295  u8 show_vtr = 0;
296  int verbose = 0;
297 
298  /*
299  * Get a line of input. Won't work if the user typed
300  * "show interface" and nothing more.
301  */
302  if (unformat_user (input, unformat_line_input, linput))
303  {
304  while (unformat_check_input (linput) != UNFORMAT_END_OF_INPUT)
305  {
306  /* See if user wants to show specific interface */
307  if (unformat
308  (linput, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
309  {
310  si = pool_elt_at_index (im->sw_interfaces, sw_if_index);
311  vec_add1 (sorted_sis, si[0]);
312  }
313  else if (unformat (linput, "address") || unformat (linput, "addr"))
314  show_addresses = 1;
315  else if (unformat (linput, "features") || unformat (linput, "feat"))
316  show_features = 1;
317  else if (unformat (linput, "tag"))
318  show_tag = 1;
319  else if (unformat (linput, "vtr"))
320  show_vtr = 1;
321  else if (unformat (linput, "verbose"))
322  verbose = 1;
323  else
324  {
325  vec_free (sorted_sis);
326  error = clib_error_return (0, "unknown input `%U'",
327  format_unformat_error, linput);
328  goto done;
329  }
330  }
331  unformat_free (linput);
332  }
333  if (show_features || show_tag || show_vtr)
334  {
335  if (sw_if_index == ~(u32) 0)
336  {
337  vec_free (sorted_sis);
338  return clib_error_return (0, "Interface not specified...");
339  }
340  }
341 
342  if (show_features)
343  {
344  vnet_interface_features_show (vm, sw_if_index, verbose);
345 
346  l2_input_config_t *l2_input = l2input_intf_config (sw_if_index);
347  u32 fb = l2_input->feature_bitmap;
348  /* intf input features are masked by bridge domain */
349  if (l2_input->bridge)
350  fb &= l2input_bd_config (l2_input->bd_index)->feature_bitmap;
351  vlib_cli_output (vm, "\nl2-input:\n%U", format_l2_input_features, fb,
352  1);
353 
354  l2_output_config_t *l2_output = l2output_intf_config (sw_if_index);
355  vlib_cli_output (vm, "\nl2-output:");
356  if (l2_output->out_vtr_flag)
357  vlib_cli_output (vm, "%10s (%s)", "VTR", "--internal--");
359  l2_output->feature_bitmap, 1);
360  vec_free (sorted_sis);
361  return 0;
362  }
363  if (show_tag)
364  {
365  u8 *tag;
366  tag = vnet_get_sw_interface_tag (vnm, sw_if_index);
367  vlib_cli_output (vm, "%U: %s",
368  format_vnet_sw_if_index_name, vnm, sw_if_index,
369  tag ? (char *) tag : "(none)");
370  vec_free (sorted_sis);
371  return 0;
372  }
373 
374  /*
375  * Show vlan tag rewrite data for one interface.
376  */
377  if (show_vtr)
378  {
379  u32 vtr_op = L2_VTR_DISABLED;
380  u32 push_dot1q = 0, tag1 = 0, tag2 = 0;
381 
382  if (l2vtr_get (vm, vnm, sw_if_index,
383  &vtr_op, &push_dot1q, &tag1, &tag2) != 0)
384  {
385  vlib_cli_output (vm, "%U: Problem getting vlan tag-rewrite data",
386  format_vnet_sw_if_index_name, vnm, sw_if_index);
387  return 0;
388  }
389  vlib_cli_output (vm, "%U: VTR %0U",
390  format_vnet_sw_if_index_name, vnm, sw_if_index,
391  format_vtr, vtr_op, push_dot1q, tag1, tag2);
392  return 0;
393  }
394 
395  if (!show_addresses)
396  vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, 0);
397 
398  if (vec_len (sorted_sis) == 0) /* Get all interfaces */
399  {
400  /* Gather interfaces. */
401  sorted_sis =
403  _vec_len (sorted_sis) = 0;
404  /* *INDENT-OFF* */
405  pool_foreach (si, im->sw_interfaces,
406  ({
407  int visible = vnet_swif_is_api_visible (si);
408  if (visible)
409  vec_add1 (sorted_sis, si[0]);}
410  ));
411  /* *INDENT-ON* */
412  /* Sort by name. */
414  }
415 
416  if (show_addresses)
417  {
418  vec_foreach (si, sorted_sis)
419  {
420  ip4_main_t *im4 = &ip4_main;
421  ip6_main_t *im6 = &ip6_main;
422  ip_lookup_main_t *lm4 = &im4->lookup_main;
423  ip_lookup_main_t *lm6 = &im6->lookup_main;
424  ip_interface_address_t *ia = 0;
425  u32 fib_index4 = 0, fib_index6 = 0;
426 
428  fib_index4 = vec_elt (im4->fib_index_by_sw_if_index,
429  si->sw_if_index);
430 
432  fib_index6 = vec_elt (im6->fib_index_by_sw_if_index,
433  si->sw_if_index);
434 
435  ip4_fib_t *fib4 = ip4_fib_get (fib_index4);
436  ip6_fib_t *fib6 = ip6_fib_get (fib_index6);
437 
440  (vm, "%U (%s): \n unnumbered, use %U",
442  (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? "up" : "dn",
444  else
446  (vm, "%U (%s):",
448  (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? "up" : "dn");
449 
450  /* Display any L2 info */
452  if (l2_input->bridge)
453  {
454  bd_main_t *bdm = &bd_main;
456  vlib_cli_output (vm, " L2 bridge bd-id %d idx %d shg %d %s",
457  bd_id, bd_find_index (bdm, bd_id), l2_input->shg,
458  l2_input->bvi ? "bvi" : " ");
459  }
460  else if (l2_input->xconnect)
461  vlib_cli_output (vm, " L2 xconnect %U",
463  l2_input->output_sw_if_index);
464 
465  /* *INDENT-OFF* */
466  /* Display any IP4 addressing info */
468  1 /* honor unnumbered */,
469  ({
470  ip4_address_t *r4 = ip_interface_address_get_address (lm4, ia);
471  if (fib4->table_id)
472  vlib_cli_output (vm, " L3 %U/%d ip4 table-id %d fib-idx %d",
473  format_ip4_address, r4, ia->address_length,
474  fib4->table_id,
475  ip4_fib_index_from_table_id (fib4->table_id));
476  else
477  vlib_cli_output (vm, " L3 %U/%d",
478  format_ip4_address, r4, ia->address_length);
479  }));
480  /* *INDENT-ON* */
481 
482  /* *INDENT-OFF* */
483  /* Display any IP6 addressing info */
485  1 /* honor unnumbered */,
486  ({
487  ip6_address_t *r6 = ip_interface_address_get_address (lm6, ia);
488  if (fib6->table_id)
489  vlib_cli_output (vm, " L3 %U/%d ip6 table-id %d fib-idx %d",
490  format_ip6_address, r6, ia->address_length,
491  fib6->table_id,
492  ip6_fib_index_from_table_id (fib6->table_id));
493  else
494  vlib_cli_output (vm, " L3 %U/%d",
495  format_ip6_address, r6, ia->address_length);
496  }));
497  /* *INDENT-ON* */
498  }
499  }
500  else
501  {
502  vec_foreach (si, sorted_sis)
503  {
504  vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, si);
505  }
506  }
507 
508 done:
509  vec_free (sorted_sis);
510  return error;
511 }
512 
513 /* *INDENT-OFF* */
514 VLIB_CLI_COMMAND (show_sw_interfaces_command, static) = {
515  .path = "show interface",
516  .short_help = "show interface [address|addr|features|feat|vtr] [<interface> [<interface> [..]]] [verbose]",
517  .function = show_sw_interfaces,
518  .is_mp_safe = 1,
519 };
520 /* *INDENT-ON* */
521 
522 /* Root of all interface commands. */
523 /* *INDENT-OFF* */
524 VLIB_CLI_COMMAND (vnet_cli_interface_command, static) = {
525  .path = "interface",
526  .short_help = "Interface commands",
527 };
528 /* *INDENT-ON* */
529 
530 /* *INDENT-OFF* */
531 VLIB_CLI_COMMAND (vnet_cli_set_interface_command, static) = {
532  .path = "set interface",
533  .short_help = "Interface commands",
534 };
535 /* *INDENT-ON* */
536 
537 static clib_error_t *
539  unformat_input_t * input, vlib_cli_command_t * cmd)
540 {
541  vnet_main_t *vnm = vnet_get_main ();
545  int j, n_counters;
546 
547  n_counters = vec_len (im->combined_sw_if_counters);
548 
549  for (j = 0; j < n_counters; j++)
550  {
551  im = &vnm->interface_main;
552  cm = im->combined_sw_if_counters + j;
554  }
555 
556  n_counters = vec_len (im->sw_if_counters);
557 
558  for (j = 0; j < n_counters; j++)
559  {
560  im = &vnm->interface_main;
561  sm = im->sw_if_counters + j;
563  }
564 
565  return 0;
566 }
567 
568 /*?
569  * Clear the statistics for all interfaces (statistics associated with the
570  * '<em>show interface</em>' command).
571  *
572  * @cliexpar
573  * Example of how to clear the statistics for all interfaces:
574  * @cliexcmd{clear interfaces}
575  ?*/
576 /* *INDENT-OFF* */
577 VLIB_CLI_COMMAND (clear_interface_counters_command, static) = {
578  .path = "clear interfaces",
579  .short_help = "clear interfaces",
580  .function = clear_interface_counters,
581 };
582 /* *INDENT-ON* */
583 
584 /**
585  * Parse subinterface names.
586  *
587  * The following subinterface syntax is supported. The first two are for
588  * backwards compatability:
589  *
590  * <intf-name> <id>
591  * - a subinterface with the name <intf-name>.<id>. The subinterface
592  * is a single dot1q vlan with vlan id <id> and exact-match semantics.
593  *
594  * <intf-name> <min_id>-<max_id>
595  * - a set of the above subinterfaces, repeating for each id
596  * in the range <min_id> to <max_id>
597  *
598  * In the following, exact-match semantics (i.e. the number of vlan tags on the
599  * packet must match the number of tags in the configuration) are used only if
600  * the keyword exact-match is present. Non-exact match is the default.
601  *
602  * <intf-name> <id> dot1q <outer_id> [exact-match]
603  * - a subinterface with the name <intf-name>.<id>. The subinterface
604  * is a single dot1q vlan with vlan id <outer_id>.
605  *
606  * <intf-name> <id> dot1q any [exact-match]
607  * - a subinterface with the name <intf-name>.<id>. The subinterface
608  * is a single dot1q vlan with any vlan id.
609  *
610  * <intf-name> <id> dot1q <outer_id> inner-dot1q <inner_id> [exact-match]
611  * - a subinterface with the name <intf-name>.<id>. The subinterface
612  * is a double dot1q vlan with outer vlan id <outer_id> and inner vlan id
613  * <inner_id>.
614  *
615  * <intf-name> <id> dot1q <outer_id> inner-dot1q any [exact-match]
616  * - a subinterface with the name <intf-name>.<id>. The subinterface
617  * is a double dot1q vlan with outer vlan id <id> and any inner vlan id.
618  *
619  * <intf-name> <id> dot1q any inner-dot1q any [exact-match]
620  *
621  * - a subinterface with the name <intf-name>.<id>. The subinterface
622  * is a double dot1q vlan with any outer vlan id and any inner vlan id.
623  *
624  * For each of the above CLI, there is a duplicate that uses the keyword
625  * "dot1ad" in place of the first "dot1q". These interfaces use ethertype
626  * 0x88ad in place of 0x8100 for the outer ethertype. Note that for double-
627  * tagged packets the inner ethertype is always 0x8100. Also note that
628  * the dot1q and dot1ad naming spaces are independent, so it is legal to
629  * have both "Gig3/0/0.1 dot1q 100" and "Gig3/0/0.2 dot1ad 100". For example:
630  *
631  * <intf-name> <id> dot1ad <outer_id> inner-dot1q <inner_id> [exact-match]
632  * - a subinterface with the name <intf-name>.<id>. The subinterface
633  * is a double dot1ad vlan with outer vlan id <outer_id> and inner vlan
634  * id <inner_id>.
635  *
636  * <intf-name> <id> untagged
637  * - a subinterface with the name <intf-name>.<id>. The subinterface
638  * has no vlan tags. Only one can be specified per interface.
639  *
640  * <intf-name> <id> default
641  * - a subinterface with the name <intf-name>.<id>. This is associated
642  * with a packet that did not match any other configured subinterface
643  * on this interface. Only one can be specified per interface.
644  */
645 
646 static clib_error_t *
648  vnet_sw_interface_t * template)
649 {
650  clib_error_t *error = 0;
651  u32 inner_vlan, outer_vlan;
652 
653  if (unformat (input, "any inner-dot1q any"))
654  {
655  template->sub.eth.flags.two_tags = 1;
656  template->sub.eth.flags.outer_vlan_id_any = 1;
657  template->sub.eth.flags.inner_vlan_id_any = 1;
658  }
659  else if (unformat (input, "any"))
660  {
661  template->sub.eth.flags.one_tag = 1;
662  template->sub.eth.flags.outer_vlan_id_any = 1;
663  }
664  else if (unformat (input, "%d inner-dot1q any", &outer_vlan))
665  {
666  template->sub.eth.flags.two_tags = 1;
667  template->sub.eth.flags.inner_vlan_id_any = 1;
668  template->sub.eth.outer_vlan_id = outer_vlan;
669  }
670  else if (unformat (input, "%d inner-dot1q %d", &outer_vlan, &inner_vlan))
671  {
672  template->sub.eth.flags.two_tags = 1;
673  template->sub.eth.outer_vlan_id = outer_vlan;
674  template->sub.eth.inner_vlan_id = inner_vlan;
675  }
676  else if (unformat (input, "%d", &outer_vlan))
677  {
678  template->sub.eth.flags.one_tag = 1;
679  template->sub.eth.outer_vlan_id = outer_vlan;
680  }
681  else
682  {
683  error = clib_error_return (0, "expected dot1q config, got `%U'",
684  format_unformat_error, input);
685  goto done;
686  }
687 
689  {
690  if (unformat (input, "exact-match"))
691  {
692  template->sub.eth.flags.exact_match = 1;
693  }
694  }
695 
696 done:
697  return error;
698 }
699 
700 static clib_error_t *
702  unformat_input_t * input, vlib_cli_command_t * cmd)
703 {
704  vnet_main_t *vnm = vnet_get_main ();
705  clib_error_t *error = 0;
706  u32 hw_if_index, sw_if_index;
708  u32 id, id_min, id_max;
709  vnet_sw_interface_t template;
710 
711  hw_if_index = ~0;
712  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
713  {
714  error = clib_error_return (0, "unknown interface `%U'",
715  format_unformat_error, input);
716  goto done;
717  }
718 
719  clib_memset (&template, 0, sizeof (template));
720  template.sub.eth.raw_flags = 0;
721 
722  if (unformat (input, "%d default", &id_min))
723  {
724  id_max = id_min;
725  template.sub.eth.flags.default_sub = 1;
726  }
727  else if (unformat (input, "%d untagged", &id_min))
728  {
729  id_max = id_min;
730  template.sub.eth.flags.no_tags = 1;
731  template.sub.eth.flags.exact_match = 1;
732  }
733  else if (unformat (input, "%d dot1q", &id_min))
734  {
735  /* parse dot1q config */
736  id_max = id_min;
737  error = parse_vlan_sub_interfaces (input, &template);
738  if (error)
739  goto done;
740  }
741  else if (unformat (input, "%d dot1ad", &id_min))
742  {
743  /* parse dot1ad config */
744  id_max = id_min;
745  template.sub.eth.flags.dot1ad = 1;
746  error = parse_vlan_sub_interfaces (input, &template);
747  if (error)
748  goto done;
749  }
750  else if (unformat (input, "%d-%d", &id_min, &id_max))
751  {
752  template.sub.eth.flags.one_tag = 1;
753  template.sub.eth.flags.exact_match = 1;
754  if (id_min > id_max)
755  goto id_error;
756  }
757  else if (unformat (input, "%d", &id_min))
758  {
759  id_max = id_min;
760  template.sub.eth.flags.one_tag = 1;
761  template.sub.eth.outer_vlan_id = id_min;
762  template.sub.eth.flags.exact_match = 1;
763  }
764  else
765  {
766  id_error:
767  error = clib_error_return (0, "expected ID or ID MIN-MAX, got `%U'",
768  format_unformat_error, input);
769  goto done;
770  }
771 
772  hi = vnet_get_hw_interface (vnm, hw_if_index);
773 
775  {
776  error =
778  "not allowed as %v belong to a BondEthernet interface",
779  hi->name);
780  goto done;
781  }
782 
783  for (id = id_min; id <= id_max; id++)
784  {
785  uword *p;
787  u64 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
788  u64 *kp;
789 
790  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
791  if (p)
792  {
793  if (CLIB_DEBUG > 0)
794  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
795  hi->sw_if_index, id);
796  continue;
797  }
798 
799  template.type = VNET_SW_INTERFACE_TYPE_SUB;
800  template.flood_class = VNET_FLOOD_CLASS_NORMAL;
801  template.sup_sw_if_index = hi->sw_if_index;
802  template.sub.id = id;
803  if (id_min < id_max)
804  template.sub.eth.outer_vlan_id = id;
805 
806  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
807  if (error)
808  goto done;
809 
810  kp = clib_mem_alloc (sizeof (*kp));
811  *kp = sup_and_sub_key;
812 
813  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
814  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
816  vnet_get_main (), sw_if_index);
817  }
818 
819 done:
820  return error;
821 }
822 
823 /*?
824  * This command is used to add VLAN IDs to interfaces, also known as subinterfaces.
825  * The primary input to this command is the '<em>interface</em>' and '<em>subId</em>'
826  * (subinterface Id) parameters. If no additional VLAN ID is provide, the VLAN ID is
827  * assumed to be the '<em>subId</em>'. The VLAN ID and '<em>subId</em>' can be different,
828  * but this is not recommended.
829  *
830  * This command has several variations:
831  * - <b>create sub-interfaces <interface> <subId></b> - Create a subinterface to
832  * process packets with a given 802.1q VLAN ID (same value as the '<em>subId</em>').
833  *
834  * - <b>create sub-interfaces <interface> <subId> default</b> - Adding the
835  * '<em>default</em>' parameter indicates that packets with VLAN IDs that do not
836  * match any other subinterfaces should be sent to this subinterface.
837  *
838  * - <b>create sub-interfaces <interface> <subId> untagged</b> - Adding the
839  * '<em>untagged</em>' parameter indicates that packets no VLAN IDs should be sent
840  * to this subinterface.
841  *
842  * - <b>create sub-interfaces <interface> <subId>-<subId></b> - Create a range of
843  * subinterfaces to handle a range of VLAN IDs.
844  *
845  * - <b>create sub-interfaces <interface> <subId> dot1q|dot1ad <vlanId>|any [exact-match]</b> -
846  * Use this command to specify the outer VLAN ID, to either be explicit or to make the
847  * VLAN ID different from the '<em>subId</em>'.
848  *
849  * - <b>create sub-interfaces <interface> <subId> dot1q|dot1ad <vlanId>|any inner-dot1q
850  * <vlanId>|any [exact-match]</b> - Use this command to specify the outer VLAN ID and
851  * the inner VLAN ID.
852  *
853  * When '<em>dot1q</em>' or '<em>dot1ad</em>' is explicitly entered, subinterfaces
854  * can be configured as either exact-match or non-exact match. Non-exact match is the CLI
855  * default. If '<em>exact-match</em>' is specified, packets must have the same number of
856  * VLAN tags as the configuration. For non-exact-match, packets must at least that number
857  * of tags. L3 (routed) interfaces must be configured as exact-match. L2 interfaces are
858  * typically configured as non-exact-match. If '<em>dot1q</em>' or '<em>dot1ad</em>' is NOT
859  * entered, then the default behavior is exact-match.
860  *
861  * Use the '<em>show interface</em>' command to display all subinterfaces.
862  *
863  * @cliexpar
864  * @parblock
865  * Example of how to create a VLAN subinterface 11 to process packets on 802.1q VLAN ID 11:
866  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 11}
867  *
868  * The previous example is shorthand and is equivalent to:
869  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 11 dot1q 11 exact-match}
870  *
871  *
872  * Example of how to create a subinterface number that is different from the VLAN ID:
873  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 11 dot1q 100}
874  *
875  *
876  * Examples of how to create q-in-q and q-in-any subinterfaces:
877  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 11 dot1q 100 inner-dot1q 200}
878  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 12 dot1q 100 inner-dot1q any}
879  *
880  * Examples of how to create dot1ad interfaces:
881  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 11 dot1ad 11}
882  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 12 dot1ad 100 inner-dot1q 200}
883  *
884  *
885  * Examples of '<em>exact-match</em>' versus non-exact match. A packet with
886  * outer VLAN 100 and inner VLAN 200 would match this interface, because the default
887  * is non-exact match:
888  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 5 dot1q 100}
889  *
890  * However, the same packet would NOT match this interface because '<em>exact-match</em>'
891  * is specified and only one VLAN is configured, but packet contains two VLANs:
892  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 5 dot1q 100 exact-match}
893  *
894  *
895  * Example of how to created a subinterface to process untagged packets:
896  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 5 untagged}
897  *
898  * Example of how to created a subinterface to process any packet with a VLAN ID that
899  * does not match any other subinterface:
900  * @cliexcmd{create sub-interfaces GigabitEthernet2/0/0 7 default}
901  *
902  * When subinterfaces are created, they are in the down state. Example of how to
903  * enable a newly created subinterface:
904  * @cliexcmd{set interface GigabitEthernet2/0/0.7 up}
905  * @endparblock
906  ?*/
907 /* *INDENT-OFF* */
908 VLIB_CLI_COMMAND (create_sub_interfaces_command, static) = {
909  .path = "create sub-interfaces",
910  .short_help = "create sub-interfaces <interface> "
911  "{<subId> [default|untagged]} | "
912  "{<subId>-<subId>} | "
913  "{<subId> dot1q|dot1ad <vlanId>|any [inner-dot1q <vlanId>|any] [exact-match]}",
914  .function = create_sub_interfaces,
915 };
916 /* *INDENT-ON* */
917 
918 static clib_error_t *
920  unformat_input_t * input, vlib_cli_command_t * cmd)
921 {
922  vnet_main_t *vnm = vnet_get_main ();
923  clib_error_t *error;
925 
926  sw_if_index = ~0;
927  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
928  {
929  error = clib_error_return (0, "unknown interface `%U'",
930  format_unformat_error, input);
931  goto done;
932  }
933 
934  if (!unformat (input, "%U", unformat_vnet_sw_interface_flags, &flags))
935  {
936  error = clib_error_return (0, "unknown flags `%U'",
937  format_unformat_error, input);
938  goto done;
939  }
940 
941  error = vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
942  if (error)
943  goto done;
944 
945 done:
946  return error;
947 }
948 
949 
950 /*?
951  * This command is used to change the admin state (up/down) of an interface.
952  *
953  * If an interface is down, the optional '<em>punt</em>' flag can also be set.
954  * The '<em>punt</em>' flag implies the interface is disabled for forwarding
955  * but punt all traffic to slow-path. Use the '<em>enable</em>' flag to clear
956  * '<em>punt</em>' flag (interface is still down).
957  *
958  * @cliexpar
959  * Example of how to configure the admin state of an interface to '<em>up</em?':
960  * @cliexcmd{set interface state GigabitEthernet2/0/0 up}
961  * Example of how to configure the admin state of an interface to '<em>down</em?':
962  * @cliexcmd{set interface state GigabitEthernet2/0/0 down}
963  ?*/
964 /* *INDENT-OFF* */
965 VLIB_CLI_COMMAND (set_state_command, static) = {
966  .path = "set interface state",
967  .short_help = "set interface state <interface> [up|down|punt|enable]",
968  .function = set_state,
969 };
970 /* *INDENT-ON* */
971 
972 static clib_error_t *
974  unformat_input_t * input, vlib_cli_command_t * cmd)
975 {
976  vnet_main_t *vnm = vnet_get_main ();
977  u32 unnumbered_sw_if_index = ~0;
978  u32 inherit_from_sw_if_index = ~0;
979  int enable = 1;
980 
981  if (unformat (input, "%U use %U",
982  unformat_vnet_sw_interface, vnm, &unnumbered_sw_if_index,
983  unformat_vnet_sw_interface, vnm, &inherit_from_sw_if_index))
984  enable = 1;
985  else if (unformat (input, "del %U",
987  &unnumbered_sw_if_index))
988  enable = 0;
989  else
990  return clib_error_return (0, "parse error '%U'",
991  format_unformat_error, input);
992 
993  if (~0 == unnumbered_sw_if_index)
994  return clib_error_return (0, "Specify the unnumbered interface");
995  if (enable && ~0 == inherit_from_sw_if_index)
996  return clib_error_return (0, "When enabling unnumbered specify the"
997  " IP enabled interface that it uses");
998 
999  vnet_sw_interface_update_unnumbered (unnumbered_sw_if_index,
1000  inherit_from_sw_if_index, enable);
1001 
1002  return (NULL);
1003 }
1004 
1005 /* *INDENT-OFF* */
1006 VLIB_CLI_COMMAND (set_unnumbered_command, static) = {
1007  .path = "set interface unnumbered",
1008  .short_help = "set interface unnumbered [<interface> use <interface> | del <interface>]",
1009  .function = set_unnumbered,
1010 };
1011 /* *INDENT-ON* */
1012 
1013 
1014 
1015 static clib_error_t *
1017  unformat_input_t * input, vlib_cli_command_t * cmd)
1018 {
1019  vnet_main_t *vnm = vnet_get_main ();
1021  clib_error_t *error;
1022  u32 hw_if_index, hw_class_index;
1023 
1024  hw_if_index = ~0;
1025  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
1026  {
1027  error = clib_error_return (0, "unknown hardware interface `%U'",
1028  format_unformat_error, input);
1029  goto done;
1030  }
1031 
1032  if (!unformat_user (input, unformat_hash_string,
1033  im->hw_interface_class_by_name, &hw_class_index))
1034  {
1035  error = clib_error_return (0, "unknown hardware class `%U'",
1036  format_unformat_error, input);
1037  goto done;
1038  }
1039 
1040  error = vnet_hw_interface_set_class (vnm, hw_if_index, hw_class_index);
1041  if (error)
1042  goto done;
1043 
1044 done:
1045  return error;
1046 }
1047 
1048 /* *INDENT-OFF* */
1049 VLIB_CLI_COMMAND (set_hw_class_command, static) = {
1050  .path = "set interface hw-class",
1051  .short_help = "Set interface hardware class",
1052  .function = set_hw_class,
1053 };
1054 /* *INDENT-ON* */
1055 
1056 static clib_error_t *
1058 {
1059  return 0;
1060 }
1061 
1063 
1064 static clib_error_t *
1066  unformat_input_t * input,
1067  vlib_cli_command_t * cmd)
1068 {
1069  u32 hw_if_index;
1070  u32 new_dev_instance;
1071  vnet_main_t *vnm = vnet_get_main ();
1072  int rv;
1073 
1074  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
1075  return clib_error_return (0, "unknown hardware interface `%U'",
1076  format_unformat_error, input);
1077 
1078  if (!unformat (input, "%d", &new_dev_instance))
1079  return clib_error_return (0, "new dev instance missing");
1080 
1081  rv = vnet_interface_name_renumber (hw_if_index, new_dev_instance);
1082 
1083  switch (rv)
1084  {
1085  case 0:
1086  break;
1087 
1088  default:
1089  return clib_error_return (0, "vnet_interface_name_renumber returned %d",
1090  rv);
1091 
1092  }
1093 
1094  return 0;
1095 }
1096 
1097 
1098 /* *INDENT-OFF* */
1099 VLIB_CLI_COMMAND (renumber_interface_command, static) = {
1100  .path = "renumber interface",
1101  .short_help = "renumber interface <interface> <new-dev-instance>",
1102  .function = renumber_interface_command_fn,
1103 };
1104 /* *INDENT-ON* */
1105 
1106 static clib_error_t *
1108  unformat_input_t * input, vlib_cli_command_t * cmd)
1109 {
1110  vnet_main_t *vnm = vnet_get_main ();
1111  u32 hw_if_index;
1114  ethernet_interface_t *eif;
1115 
1116  if (unformat (input, "on %U",
1117  unformat_vnet_hw_interface, vnm, &hw_if_index))
1118  ;
1119  else if (unformat (input, "off %U",
1120  unformat_ethernet_interface, vnm, &hw_if_index))
1121  flags = 0;
1122  else
1123  return clib_error_return (0, "unknown input `%U'",
1124  format_unformat_error, input);
1125 
1126  eif = ethernet_get_interface (em, hw_if_index);
1127  if (!eif)
1128  return clib_error_return (0, "not supported");
1129 
1130  ethernet_set_flags (vnm, hw_if_index, flags);
1131  return 0;
1132 }
1133 
1134 /* *INDENT-OFF* */
1135 VLIB_CLI_COMMAND (set_interface_promiscuous_cmd, static) = {
1136  .path = "set interface promiscuous",
1137  .short_help = "set interface promiscuous [on|off] <interface>",
1138  .function = promiscuous_cmd,
1139 };
1140 /* *INDENT-ON* */
1141 
1142 static clib_error_t *
1144 {
1145  vnet_main_t *vnm = vnet_get_main ();
1146  u32 hw_if_index, sw_if_index, mtu;
1148  u32 mtus[VNET_N_MTU] = { 0, 0, 0, 0 };
1149 
1150  if (unformat (input, "%d %U", &mtu,
1151  unformat_vnet_hw_interface, vnm, &hw_if_index))
1152  {
1153  /*
1154  * Change physical MTU on interface. Only supported for Ethernet
1155  * interfaces
1156  */
1157  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1158  ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index);
1159 
1160  if (!eif)
1161  return clib_error_return (0, "not supported");
1162 
1163  if (mtu < hi->min_supported_packet_bytes)
1164  return clib_error_return (0, "Invalid mtu (%d): "
1165  "must be >= min pkt bytes (%d)", mtu,
1167 
1168  if (mtu > hi->max_supported_packet_bytes)
1169  return clib_error_return (0, "Invalid mtu (%d): must be <= (%d)", mtu,
1171 
1172  vnet_hw_interface_set_mtu (vnm, hw_if_index, mtu);
1173  goto done;
1174  }
1175  else if (unformat (input, "packet %d %U", &mtu,
1176  unformat_vnet_sw_interface, vnm, &sw_if_index))
1177  /* Set default packet MTU (including L3 header */
1178  mtus[VNET_MTU_L3] = mtu;
1179  else if (unformat (input, "ip4 %d %U", &mtu,
1180  unformat_vnet_sw_interface, vnm, &sw_if_index))
1181  mtus[VNET_MTU_IP4] = mtu;
1182  else if (unformat (input, "ip6 %d %U", &mtu,
1183  unformat_vnet_sw_interface, vnm, &sw_if_index))
1184  mtus[VNET_MTU_IP6] = mtu;
1185  else if (unformat (input, "mpls %d %U", &mtu,
1186  unformat_vnet_sw_interface, vnm, &sw_if_index))
1187  mtus[VNET_MTU_MPLS] = mtu;
1188  else
1189  return clib_error_return (0, "unknown input `%U'",
1190  format_unformat_error, input);
1191 
1192  vnet_sw_interface_set_protocol_mtu (vnm, sw_if_index, mtus);
1193 
1194 done:
1195  return 0;
1196 }
1197 
1198 /* *INDENT-OFF* */
1199 VLIB_CLI_COMMAND (set_interface_mtu_cmd, static) = {
1200  .path = "set interface mtu",
1201  .short_help = "set interface mtu [packet|ip4|ip6|mpls] <value> <interface>",
1202  .function = mtu_cmd,
1203 };
1204 /* *INDENT-ON* */
1205 
1206 static clib_error_t *
1208  vlib_cli_command_t * cmd)
1209 {
1210  vnet_main_t *vnm = vnet_get_main ();
1213  u32 sw_if_index = ~0;
1214  vnet_sw_interface_t *si, *sorted_sis = 0;
1215 
1216  if (unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1217  {
1218  si = pool_elt_at_index (im->sw_interfaces, sw_if_index);
1219  vec_add1 (sorted_sis, si[0]);
1220  }
1221 
1222  /* if an interface name was not passed, get all interfaces */
1223  if (vec_len (sorted_sis) == 0)
1224  {
1225  sorted_sis =
1227  _vec_len (sorted_sis) = 0;
1228  /* *INDENT-OFF* */
1229  pool_foreach (si, im->sw_interfaces,
1230  ({
1231  int visible = vnet_swif_is_api_visible (si);
1232  if (visible)
1233  vec_add1 (sorted_sis, si[0]);}
1234  ));
1235  /* *INDENT-ON* */
1236  /* Sort by name. */
1238  }
1239 
1240  vec_foreach (si, sorted_sis)
1241  {
1242  vnet_sw_interface_t *sup_si;
1244 
1245  sup_si = vnet_get_sup_sw_interface (vnm, si->sw_if_index);
1246  ei = ethernet_get_interface (em, sup_si->hw_if_index);
1247 
1248  vlib_cli_output (vm, "%U (%s):",
1251  "up" : "dn");
1252 
1253  if (ei && ei->secondary_addrs)
1254  {
1255  mac_address_t *sec_addr;
1256 
1257  vec_foreach (sec_addr, ei->secondary_addrs)
1258  {
1259  vlib_cli_output (vm, " %U", format_mac_address_t, sec_addr);
1260  }
1261  }
1262  }
1263 
1264  vec_free (sorted_sis);
1265  return 0;
1266 }
1267 
1268 /*?
1269  * This command is used to display interface secondary mac addresses.
1270  *
1271  * @cliexpar
1272  * Example of how to display interface secondary mac addresses:
1273  * @cliexstart{show interface secondary-mac-address}
1274  * @cliexend
1275 ?*/
1276 /* *INDENT-OFF* */
1277 VLIB_CLI_COMMAND (show_interface_sec_mac_addr, static) = {
1278  .path = "show interface secondary-mac-address",
1279  .short_help = "show interface secondary-mac-address [<interface>]",
1280  .function = show_interface_sec_mac_addr_fn,
1281 };
1282 /* *INDENT-ON* */
1283 
1284 static clib_error_t *
1286  vlib_cli_command_t * cmd)
1287 {
1288  vnet_main_t *vnm = vnet_get_main ();
1289  vnet_sw_interface_t *si = NULL;
1290  clib_error_t *error = 0;
1291  u32 sw_if_index = ~0;
1292  u8 mac[6] = { 0 };
1293  u8 is_add, is_del;
1294 
1295  is_add = is_del = 0;
1296 
1297  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
1298  {
1299  error = clib_error_return (0, "unknown interface `%U'",
1300  format_unformat_error, input);
1301  goto done;
1302  }
1303  if (!unformat_user (input, unformat_ethernet_address, mac))
1304  {
1305  error = clib_error_return (0, "expected mac address `%U'",
1306  format_unformat_error, input);
1307  goto done;
1308  }
1309 
1310  while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
1311  {
1312  if (unformat (input, "add"))
1313  is_add = 1;
1314  else if (unformat (input, "del"))
1315  is_del = 1;
1316  else
1317  break;
1318  }
1319 
1320  if (is_add == is_del)
1321  {
1322  error = clib_error_return (0, "must choose one of add or del");
1323  goto done;
1324  }
1325 
1326  si = vnet_get_sw_interface (vnm, sw_if_index);
1327  error =
1328  vnet_hw_interface_add_del_mac_address (vnm, si->hw_if_index, mac, is_add);
1329 
1330 done:
1331  return error;
1332 }
1333 
1334 /*?
1335  * The '<em>set interface secondary-mac-address </em>' command allows adding
1336  * or deleting extra MAC addresses on a given interface without changing the
1337  * default MAC address. This could allow packets sent to these MAC addresses
1338  * to be received without setting the interface to promiscuous mode.
1339  * Not all interfaces support this operation. The ones that do are mostly
1340  * hardware NICs, though virtio does also.
1341  *
1342  * @cliexpar
1343  * @parblock
1344  * Example of how to add a secondary MAC Address on an interface:
1345  * @cliexcmd{set interface secondary-mac-address GigabitEthernet0/8/0 aa:bb:cc:dd:ee:01 add}
1346  * Example of how to delete a secondary MAC address from an interface:
1347  * @cliexcmd{set interface secondary-mac-address GigabitEthernet0/8/0 aa:bb:cc:dd:ee:01 del}
1348  * @endparblock
1349 ?*/
1350 /* *INDENT-OFF* */
1351 VLIB_CLI_COMMAND (interface_add_del_mac_address_cmd, static) = {
1352  .path = "set interface secondary-mac-address",
1353  .short_help = "set interface secondary-mac-address <interface> <mac-address> [(add|del)]",
1354  .function = interface_add_del_mac_address,
1355 };
1356 /* *INDENT-ON* */
1357 
1358 static clib_error_t *
1360  vlib_cli_command_t * cmd)
1361 {
1362  vnet_main_t *vnm = vnet_get_main ();
1363  vnet_sw_interface_t *si = NULL;
1364  clib_error_t *error = 0;
1365  u32 sw_if_index = ~0;
1366  u8 mac[6] = { 0 };
1367 
1368  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
1369  {
1370  error = clib_error_return (0, "unknown interface `%U'",
1371  format_unformat_error, input);
1372  goto done;
1373  }
1374  if (!unformat_user (input, unformat_ethernet_address, mac))
1375  {
1376  error = clib_error_return (0, "expected mac address `%U'",
1377  format_unformat_error, input);
1378  goto done;
1379  }
1380  si = vnet_get_sw_interface (vnm, sw_if_index);
1381  error = vnet_hw_interface_change_mac_address (vnm, si->hw_if_index, mac);
1382 done:
1383  return error;
1384 }
1385 
1386 /*?
1387  * The '<em>set interface mac address </em>' command allows to set MAC address of given interface.
1388  * In case of NIC interfaces the one has to support MAC address change. A side effect of MAC address
1389  * change are changes of MAC addresses in FIB tables (ipv4 and ipv6).
1390  *
1391  * @cliexpar
1392  * @parblock
1393  * Example of how to change MAC Address of interface:
1394  * @cliexcmd{set interface mac address GigabitEthernet0/8/0 aa:bb:cc:dd:ee:01}
1395  * @cliexcmd{set interface mac address host-vpp0 aa:bb:cc:dd:ee:02}
1396  * @cliexcmd{set interface mac address tap-0 aa:bb:cc:dd:ee:03}
1397  * @cliexcmd{set interface mac address pg0 aa:bb:cc:dd:ee:04}
1398  * @endparblock
1399 ?*/
1400 /* *INDENT-OFF* */
1401 VLIB_CLI_COMMAND (set_interface_mac_address_cmd, static) = {
1402  .path = "set interface mac address",
1403  .short_help = "set interface mac address <interface> <mac-address>",
1404  .function = set_interface_mac_address,
1405 };
1406 /* *INDENT-ON* */
1407 
1408 static clib_error_t *
1410 {
1411  vnet_main_t *vnm = vnet_get_main ();
1412  u32 sw_if_index = ~0;
1413  u8 *tag = 0;
1414 
1415  if (!unformat (input, "%U %s", unformat_vnet_sw_interface,
1416  vnm, &sw_if_index, &tag))
1417  return clib_error_return (0, "unknown input `%U'",
1418  format_unformat_error, input);
1419 
1420  vnet_set_sw_interface_tag (vnm, tag, sw_if_index);
1421 
1422  return 0;
1423 }
1424 
1425 /* *INDENT-OFF* */
1426 VLIB_CLI_COMMAND (set_tag_command, static) = {
1427  .path = "set interface tag",
1428  .short_help = "set interface tag <interface> <tag>",
1429  .function = set_tag,
1430 };
1431 /* *INDENT-ON* */
1432 
1433 static clib_error_t *
1435  vlib_cli_command_t * cmd)
1436 {
1437  vnet_main_t *vnm = vnet_get_main ();
1438  u32 sw_if_index = ~0;
1439 
1440  if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
1441  return clib_error_return (0, "unknown input `%U'",
1442  format_unformat_error, input);
1443 
1444  vnet_clear_sw_interface_tag (vnm, sw_if_index);
1445 
1446  return 0;
1447 }
1448 
1449 /* *INDENT-OFF* */
1450 VLIB_CLI_COMMAND (clear_tag_command, static) = {
1451  .path = "clear interface tag",
1452  .short_help = "clear interface tag <interface>",
1453  .function = clear_tag,
1454 };
1455 /* *INDENT-ON* */
1456 
1457 static clib_error_t *
1459  unformat_input_t * input, vlib_cli_command_t * cmd)
1460 {
1461  vnet_main_t *vnm = vnet_get_main ();
1462  u32 sw_if_index = ~0;
1463  u8 enable = 0;
1464 
1465  if (!unformat (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index));
1466  else if (unformat (input, "enable"))
1467  enable = 1;
1468  else if (unformat (input, "disable"))
1469  enable = 0;
1470  else
1471  return clib_error_return (0, "unknown input: `%U'",
1472  format_unformat_error, input);
1473 
1474  if (~0 == sw_if_index)
1475  return clib_error_return (0, "specify an interface: `%U'",
1476  format_unformat_error, input);
1477 
1478  vnet_sw_interface_ip_directed_broadcast (vnm, sw_if_index, enable);
1479 
1480  return 0;
1481 }
1482 
1483 /*?
1484  * This command is used to enable/disable IP directed broadcast
1485  * If directed broadcast is enabled a packet sent to the interface's
1486  * subnet broadcast address will be sent L2 broadcast on the interface,
1487  * otherwise it is dropped.
1488  ?*/
1489 /* *INDENT-OFF* */
1490 VLIB_CLI_COMMAND (set_ip_directed_broadcast_command, static) = {
1491  .path = "set interface ip directed-broadcast",
1492  .short_help = "set interface enable <interface> <enable|disable>",
1493  .function = set_ip_directed_broadcast,
1494 };
1495 /* *INDENT-ON* */
1496 
1497 static clib_error_t *
1500 {
1501  vnet_hw_interface_t *hw = vnet_get_hw_interface (vnm, hw_if_index);
1502  vnet_device_class_t *dev_class =
1504  clib_error_t *error;
1505  vnet_hw_interface_rx_mode old_mode;
1506  int rv;
1507 
1509  mode = hw->default_rx_mode;
1510 
1511  rv = vnet_hw_interface_get_rx_mode (vnm, hw_if_index, queue_id, &old_mode);
1512  switch (rv)
1513  {
1514  case 0:
1515  if (old_mode == mode)
1516  return 0; /* same rx-mode, no change */
1517  break;
1518  case VNET_API_ERROR_INVALID_INTERFACE:
1519  return clib_error_return (0, "invalid interface");
1520  case VNET_API_ERROR_INVALID_QUEUE:
1521  return clib_error_return (0, "invalid queue");
1522  default:
1523  return clib_error_return (0, "unknown error");
1524  }
1525 
1526  if (dev_class->rx_mode_change_function)
1527  {
1528  error = dev_class->rx_mode_change_function (vnm, hw_if_index, queue_id,
1529  mode);
1530  if (error)
1531  return (error);
1532  }
1533 
1534  rv = vnet_hw_interface_set_rx_mode (vnm, hw_if_index, queue_id, mode);
1535  switch (rv)
1536  {
1537  case 0:
1538  break;
1539  case VNET_API_ERROR_UNSUPPORTED:
1540  return clib_error_return (0, "unsupported");
1541  case VNET_API_ERROR_INVALID_INTERFACE:
1542  return clib_error_return (0, "invalid interface");
1543  case VNET_API_ERROR_INVALID_QUEUE:
1544  return clib_error_return (0, "invalid queue");
1545  default:
1546  return clib_error_return (0, "unknown error");
1547  }
1548 
1549  return 0;
1550 }
1551 
1552 clib_error_t *
1554  u8 queue_id_valid, u32 queue_id,
1556 {
1557  clib_error_t *error = 0;
1558  vnet_hw_interface_t *hw;
1559  int i;
1560 
1561  hw = vnet_get_hw_interface (vnm, hw_if_index);
1562 
1563  if (queue_id_valid == 0)
1564  {
1565  for (i = 0; i < vec_len (hw->dq_runtime_index_by_queue); i++)
1566  {
1567  error = set_hw_interface_rx_mode (vnm, hw_if_index, i, mode);
1568  if (error)
1569  break;
1570  }
1571  hw->default_rx_mode = mode;
1572  }
1573  else
1574  error = set_hw_interface_rx_mode (vnm, hw_if_index, queue_id, mode);
1575 
1576  return (error);
1577 }
1578 
1579 static clib_error_t *
1581  vlib_cli_command_t * cmd)
1582 {
1583  clib_error_t *error = 0;
1584  unformat_input_t _line_input, *line_input = &_line_input;
1585  vnet_main_t *vnm = vnet_get_main ();
1586  u32 hw_if_index = (u32) ~ 0;
1587  u32 queue_id = (u32) ~ 0;
1589  u8 queue_id_valid = 0;
1590 
1591  if (!unformat_user (input, unformat_line_input, line_input))
1592  return 0;
1593 
1594  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1595  {
1596  if (unformat
1597  (line_input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
1598  ;
1599  else if (unformat (line_input, "queue %d", &queue_id))
1600  queue_id_valid = 1;
1601  else if (unformat (line_input, "polling"))
1603  else if (unformat (line_input, "interrupt"))
1605  else if (unformat (line_input, "adaptive"))
1607  else
1608  {
1609  error = clib_error_return (0, "parse error: '%U'",
1610  format_unformat_error, line_input);
1611  unformat_free (line_input);
1612  return error;
1613  }
1614  }
1615 
1616  unformat_free (line_input);
1617 
1618  if (hw_if_index == (u32) ~ 0)
1619  return clib_error_return (0, "please specify valid interface name");
1620 
1622  return clib_error_return (0, "please specify valid rx-mode");
1623 
1624  error = set_hw_interface_change_rx_mode (vnm, hw_if_index, queue_id_valid,
1625  queue_id, mode);
1626 
1627  return (error);
1628 }
1629 
1630 /*?
1631  * This command is used to assign the RX packet processing mode (polling,
1632  * interrupt, adaptive) of the a given interface, and optionally a
1633  * given queue. If the '<em>queue</em>' is not provided, the '<em>mode</em>'
1634  * is applied to all queues of the interface. Not all interfaces support
1635  * all modes. To display the current rx-mode use the command
1636  * '<em>show interface rx-placement</em>'.
1637  *
1638  * @cliexpar
1639  * Example of how to assign rx-mode to all queues on an interface:
1640  * @cliexcmd{set interface rx-mode VirtualEthernet0/0/12 polling}
1641  * Example of how to assign rx-mode to one queue of an interface:
1642  * @cliexcmd{set interface rx-mode VirtualEthernet0/0/12 queue 0 interrupt}
1643  * Example of how to display the rx-mode of all interfaces:
1644  * @cliexstart{show interface rx-placement}
1645  * Thread 1 (vpp_wk_0):
1646  * node dpdk-input:
1647  * GigabitEthernet7/0/0 queue 0 (polling)
1648  * node vhost-user-input:
1649  * VirtualEthernet0/0/12 queue 0 (interrupt)
1650  * VirtualEthernet0/0/12 queue 2 (polling)
1651  * VirtualEthernet0/0/13 queue 0 (polling)
1652  * VirtualEthernet0/0/13 queue 2 (polling)
1653  * Thread 2 (vpp_wk_1):
1654  * node dpdk-input:
1655  * GigabitEthernet7/0/1 queue 0 (polling)
1656  * node vhost-user-input:
1657  * VirtualEthernet0/0/12 queue 1 (polling)
1658  * VirtualEthernet0/0/12 queue 3 (polling)
1659  * VirtualEthernet0/0/13 queue 1 (polling)
1660  * VirtualEthernet0/0/13 queue 3 (polling)
1661  * @cliexend
1662 ?*/
1663 /* *INDENT-OFF* */
1664 VLIB_CLI_COMMAND (cmd_set_if_rx_mode,static) = {
1665  .path = "set interface rx-mode",
1666  .short_help = "set interface rx-mode <interface> [queue <n>] [polling | interrupt | adaptive]",
1667  .function = set_interface_rx_mode,
1668 };
1669 /* *INDENT-ON* */
1670 
1671 static clib_error_t *
1673  vlib_cli_command_t * cmd)
1674 {
1675  u8 *s = 0;
1676  vnet_main_t *vnm = vnet_get_main ();
1679  vlib_node_t *pn = vlib_get_node_by_name (vm, (u8 *) "device-input");
1680  uword si;
1681  int index = 0;
1682 
1683  /* *INDENT-OFF* */
1684  foreach_vlib_main (({
1686  ({
1687  rt = vlib_node_get_runtime_data (this_vlib_main, si);
1688 
1689  if (vec_len (rt->devices_and_queues))
1690  s = format (s, " node %U:\n", format_vlib_node_name, vm, si);
1691 
1692  vec_foreach (dq, rt->devices_and_queues)
1693  {
1694  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm,
1695  dq->hw_if_index);
1696  s = format (s, " %U queue %u (%U)\n",
1697  format_vnet_sw_if_index_name, vnm, hi->sw_if_index,
1698  dq->queue_id,
1699  format_vnet_hw_interface_rx_mode, dq->mode);
1700  }
1701  }));
1702  if (vec_len (s) > 0)
1703  {
1704  vlib_cli_output(vm, "Thread %u (%s):\n%v", index,
1705  vlib_worker_threads[index].name, s);
1706  vec_reset_length (s);
1707  }
1708  index++;
1709  }));
1710  /* *INDENT-ON* */
1711 
1712  vec_free (s);
1713  return 0;
1714 }
1715 
1716 /*?
1717  * This command is used to display the interface and queue worker
1718  * thread placement.
1719  *
1720  * @cliexpar
1721  * Example of how to display the interface placement:
1722  * @cliexstart{show interface rx-placement}
1723  * Thread 1 (vpp_wk_0):
1724  * node dpdk-input:
1725  * GigabitEthernet7/0/0 queue 0 (polling)
1726  * node vhost-user-input:
1727  * VirtualEthernet0/0/12 queue 0 (polling)
1728  * VirtualEthernet0/0/12 queue 2 (polling)
1729  * VirtualEthernet0/0/13 queue 0 (polling)
1730  * VirtualEthernet0/0/13 queue 2 (polling)
1731  * Thread 2 (vpp_wk_1):
1732  * node dpdk-input:
1733  * GigabitEthernet7/0/1 queue 0 (polling)
1734  * node vhost-user-input:
1735  * VirtualEthernet0/0/12 queue 1 (polling)
1736  * VirtualEthernet0/0/12 queue 3 (polling)
1737  * VirtualEthernet0/0/13 queue 1 (polling)
1738  * VirtualEthernet0/0/13 queue 3 (polling)
1739  * @cliexend
1740 ?*/
1741 /* *INDENT-OFF* */
1742 VLIB_CLI_COMMAND (show_interface_rx_placement, static) = {
1743  .path = "show interface rx-placement",
1744  .short_help = "show interface rx-placement",
1745  .function = show_interface_rx_placement_fn,
1746 };
1747 /* *INDENT-ON* */
1748 
1749 clib_error_t *
1750 set_hw_interface_rx_placement (u32 hw_if_index, u32 queue_id,
1751  u32 thread_index, u8 is_main)
1752 {
1753  vnet_main_t *vnm = vnet_get_main ();
1755  clib_error_t *error = 0;
1757  int rv;
1758 
1759  if (is_main)
1760  thread_index = 0;
1761  else
1762  thread_index += vdm->first_worker_thread_index;
1763 
1764  if (thread_index > vdm->last_worker_thread_index)
1765  return clib_error_return (0,
1766  "please specify valid worker thread or main");
1767 
1768  rv = vnet_hw_interface_get_rx_mode (vnm, hw_if_index, queue_id, &mode);
1769 
1770  if (rv)
1771  return clib_error_return (0, "not found");
1772 
1773  rv = vnet_hw_interface_unassign_rx_thread (vnm, hw_if_index, queue_id);
1774 
1775  if (rv)
1776  return clib_error_return (0, "not found");
1777 
1778  vnet_hw_interface_assign_rx_thread (vnm, hw_if_index, queue_id,
1779  thread_index);
1780  vnet_hw_interface_set_rx_mode (vnm, hw_if_index, queue_id, mode);
1781 
1782  return (error);
1783 }
1784 
1785 static clib_error_t *
1787  vlib_cli_command_t * cmd)
1788 {
1789  clib_error_t *error = 0;
1790  unformat_input_t _line_input, *line_input = &_line_input;
1791  vnet_main_t *vnm = vnet_get_main ();
1792  u32 hw_if_index = (u32) ~ 0;
1793  u32 queue_id = (u32) 0;
1794  u32 thread_index = (u32) ~ 0;
1795  u8 is_main = 0;
1796 
1797  if (!unformat_user (input, unformat_line_input, line_input))
1798  return 0;
1799 
1800  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1801  {
1802  if (unformat
1803  (line_input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
1804  ;
1805  else if (unformat (line_input, "queue %d", &queue_id))
1806  ;
1807  else if (unformat (line_input, "main", &thread_index))
1808  is_main = 1;
1809  else if (unformat (line_input, "worker %d", &thread_index))
1810  ;
1811  else
1812  {
1813  error = clib_error_return (0, "parse error: '%U'",
1814  format_unformat_error, line_input);
1815  unformat_free (line_input);
1816  return error;
1817  }
1818  }
1819 
1820  unformat_free (line_input);
1821 
1822  if (hw_if_index == (u32) ~ 0)
1823  return clib_error_return (0, "please specify valid interface name");
1824 
1825  error = set_hw_interface_rx_placement (hw_if_index, queue_id, thread_index,
1826  is_main);
1827 
1828  return (error);
1829 }
1830 
1831 /*?
1832  * This command is used to assign a given interface, and optionally a
1833  * given queue, to a different thread. If the '<em>queue</em>' is not provided,
1834  * it defaults to 0. The '<em>worker</em>' parameter is zero based and the index
1835  * in the thread name, for example, 0 in the thread name '<em>vpp_wk_0</em>'.
1836  *
1837  * @cliexpar
1838  * Example of how to display the interface placement:
1839  * @cliexstart{show interface rx-placement}
1840  * Thread 1 (vpp_wk_0):
1841  * node dpdk-input:
1842  * GigabitEthernet7/0/0 queue 0 (polling)
1843  * node vhost-user-input:
1844  * VirtualEthernet0/0/12 queue 0 (polling)
1845  * VirtualEthernet0/0/12 queue 2 (polling)
1846  * VirtualEthernet0/0/13 queue 0 (polling)
1847  * VirtualEthernet0/0/13 queue 2 (polling)
1848  * Thread 2 (vpp_wk_1):
1849  * node dpdk-input:
1850  * GigabitEthernet7/0/1 queue 0 (polling)
1851  * node vhost-user-input:
1852  * VirtualEthernet0/0/12 queue 1 (polling)
1853  * VirtualEthernet0/0/12 queue 3 (polling)
1854  * VirtualEthernet0/0/13 queue 1 (polling)
1855  * VirtualEthernet0/0/13 queue 3 (polling)
1856  * @cliexend
1857  * Example of how to assign a interface and queue to a worker thread:
1858  * @cliexcmd{set interface rx-placement VirtualEthernet0/0/12 queue 1 worker 0}
1859  * Example of how to display the interface placement:
1860  * @cliexstart{show interface rx-placement}
1861  * Thread 1 (vpp_wk_0):
1862  * node dpdk-input:
1863  * GigabitEthernet7/0/0 queue 0 (polling)
1864  * node vhost-user-input:
1865  * VirtualEthernet0/0/12 queue 0 (polling)
1866  * VirtualEthernet0/0/12 queue 1 (polling)
1867  * VirtualEthernet0/0/12 queue 2 (polling)
1868  * VirtualEthernet0/0/13 queue 0 (polling)
1869  * VirtualEthernet0/0/13 queue 2 (polling)
1870  * Thread 2 (vpp_wk_1):
1871  * node dpdk-input:
1872  * GigabitEthernet7/0/1 queue 0 (polling)
1873  * node vhost-user-input:
1874  * VirtualEthernet0/0/12 queue 3 (polling)
1875  * VirtualEthernet0/0/13 queue 1 (polling)
1876  * VirtualEthernet0/0/13 queue 3 (polling)
1877  * @cliexend
1878 ?*/
1879 /* *INDENT-OFF* */
1880 VLIB_CLI_COMMAND (cmd_set_if_rx_placement,static) = {
1881  .path = "set interface rx-placement",
1882  .short_help = "set interface rx-placement <interface> [queue <n>] "
1883  "[worker <n> | main]",
1884  .function = set_interface_rx_placement,
1885  .is_mp_safe = 1,
1886 };
1887 /* *INDENT-ON* */
1888 
1889 clib_error_t *
1891  clib_bitmap_t * bitmap)
1892 {
1893  vnet_main_t *vnm = vnet_get_main ();
1894  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1895 
1896  return vnet_hw_interface_set_rss_queues (vnm, hi, bitmap);
1897 }
1898 
1899 static clib_error_t *
1901  unformat_input_t * input,
1902  vlib_cli_command_t * cmd)
1903 {
1904  clib_error_t *error = 0;
1905  unformat_input_t _line_input, *line_input = &_line_input;
1906  vnet_main_t *vnm = vnet_get_main ();
1907  u32 hw_if_index = (u32) ~ 0;
1908  clib_bitmap_t *bitmap = NULL;
1909 
1910  if (!unformat_user (input, unformat_line_input, line_input))
1911  return 0;
1912 
1913  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
1914  {
1915  if (unformat
1916  (line_input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
1917  ;
1918  else
1919  if (unformat (line_input, "list %U", unformat_bitmap_list, &bitmap))
1920  ;
1921  else
1922  {
1923  error = clib_error_return (0, "parse error: '%U'",
1924  format_unformat_error, line_input);
1925  unformat_free (line_input);
1926  goto done;
1927  }
1928  }
1929 
1930  unformat_free (line_input);
1931 
1932  if (hw_if_index == (u32) ~ 0)
1933  {
1934  error = clib_error_return (0, "please specify valid interface name");
1935  goto done;
1936  }
1937 
1938  if (bitmap == NULL)
1939  {
1940  error = clib_error_return (0, "please specify the valid rss queues");
1941  goto done;
1942  }
1943 
1944  error = set_interface_rss_queues (vm, hw_if_index, bitmap);
1945 
1946 done:
1947  if (bitmap)
1948  clib_bitmap_free (bitmap);
1949 
1950  return (error);
1951 }
1952 
1953 /*?
1954  * This command is used to set the rss queues of a given interface
1955  * Not all the interfaces support this operation.
1956  * To display the current rss queues, use the command
1957  * '<em>show hardware-interfaces</em>'.
1958  *
1959  * @cliexpar
1960  * Example of how to set the rss queues to 0,2-5,7 of an interface:
1961  * @cliexstart{set interface rss queues VirtualFunctionEthernet18/1/0 list 0,2-5,7}
1962  * @cliexend
1963 ?*/
1964 /* *INDENT-OFF* */
1965 VLIB_CLI_COMMAND (cmd_set_interface_rss_queues,static) = {
1966  .path = "set interface rss queues",
1967  .short_help = "set interface rss queues <interface> <list <queue-list>>",
1968  .function = set_interface_rss_queues_fn,
1969 };
1970 /* *INDENT-ON* */
1971 
1972 static u8 *
1973 format_vnet_pcap (u8 * s, va_list * args)
1974 {
1975  vnet_pcap_t *pp = va_arg (*args, vnet_pcap_t *);
1976  int type = va_arg (*args, int);
1977  int printed = 0;
1978 
1979  if (type == 0)
1980  {
1981  if (pp->pcap_rx_enable)
1982  {
1983  s = format (s, "rx");
1984  printed = 1;
1985  }
1986  if (pp->pcap_tx_enable)
1987  {
1988  if (printed)
1989  s = format (s, " and ");
1990  s = format (s, "tx");
1991  printed = 1;
1992  }
1993  if (pp->pcap_drop_enable)
1994  {
1995  if (printed)
1996  s = format (s, " and ");
1997  s = format (s, "drop");
1998  printed = 1;
1999  }
2000  return s;
2001  }
2002  s = format (s, "unknown type %d!", type);
2003  return s;
2004 }
2005 
2006 
2007 int
2009 {
2011  vnet_pcap_t *pp = &vm->pcap;
2012  pcap_main_t *pm = &pp->pcap_main;
2014  vnet_classify_filter_set_t *set = 0;
2015 
2016  if (a->status)
2017  {
2018  if (pp->pcap_rx_enable || pp->pcap_tx_enable || pp->pcap_drop_enable)
2019  {
2021  (vm, "pcap %U dispatch capture enabled: %d of %d pkts...",
2022  format_vnet_pcap, pp, 0 /* print type */ ,
2024  vlib_cli_output (vm, "capture to file %s", pm->file_name);
2025  }
2026  else
2027  vlib_cli_output (vm, "pcap dispatch capture disabled");
2028 
2029  return 0;
2030  }
2031 
2032  /* Consistency checks */
2033 
2034  /* Enable w/ capture already enabled not allowed */
2035  if ((pp->pcap_rx_enable + pp->pcap_tx_enable + pp->pcap_drop_enable)
2036  && (a->rx_enable + a->tx_enable + a->drop_enable))
2037  return VNET_API_ERROR_INVALID_VALUE;
2038 
2039  /* Disable capture with capture already disabled, not interesting */
2040  if (((pp->pcap_rx_enable + pp->pcap_tx_enable + pp->pcap_drop_enable) == 0)
2041  && ((a->rx_enable + a->tx_enable + a->drop_enable == 0)))
2042  return VNET_API_ERROR_VALUE_EXIST;
2043 
2044  /* Change number of packets to capture while capturing */
2045  if ((pp->pcap_rx_enable + pp->pcap_tx_enable + pp->pcap_drop_enable)
2046  && (a->rx_enable + a->tx_enable + a->drop_enable)
2048  return VNET_API_ERROR_INVALID_VALUE_2;
2049 
2050  set = pool_elt_at_index (cm->filter_sets, cm->filter_set_by_sw_if_index[0]);
2051 
2052  /* Classify filter specified, but no classify filter configured */
2053  if ((a->rx_enable + a->tx_enable + a->drop_enable) && a->filter &&
2054  (set->table_indices == 0 || set->table_indices[0] == ~0))
2055  return VNET_API_ERROR_NO_SUCH_LABEL;
2056 
2057  if (a->rx_enable + a->tx_enable + a->drop_enable)
2058  {
2059  void *save_pcap_data;
2060 
2061  /* Sanity check max bytes per pkt */
2062  if (a->max_bytes_per_pkt < 32 || a->max_bytes_per_pkt > 9000)
2063  return VNET_API_ERROR_INVALID_MEMORY_SIZE;
2064 
2065  /* Clean up from previous run, if any */
2067 
2068  /* Throw away the data buffer? */
2069  if (a->free_data)
2070  vec_free (pm->pcap_data);
2071 
2072  save_pcap_data = pm->pcap_data;
2073 
2074  memset (pm, 0, sizeof (*pm));
2075 
2076  pm->pcap_data = save_pcap_data;
2077 
2080  if (pm->lock == 0)
2081  clib_spinlock_init (&(pm->lock));
2082 
2083  if (a->filename == 0)
2084  {
2085  u8 *stem = 0;
2086 
2087  if (a->rx_enable)
2088  stem = format (stem, "rx");
2089  if (a->tx_enable)
2090  stem = format (stem, "tx");
2091  if (a->drop_enable)
2092  stem = format (stem, "drop");
2093  a->filename = format (0, "/tmp/%v.pcap%c", stem, 0);
2094  vec_free (stem);
2095  }
2096 
2097  pm->file_name = (char *) a->filename;
2098  pm->n_packets_captured = 0;
2099  pm->packet_type = PCAP_PACKET_TYPE_ethernet;
2100  /* Preallocate the data vector? */
2101  if (a->preallocate_data)
2102  {
2103  vec_validate
2104  (pm->pcap_data, a->packets_to_capture
2105  * ((sizeof (pcap_packet_header_t) + a->max_bytes_per_pkt)));
2107  }
2109  pp->pcap_sw_if_index = a->sw_if_index;
2110  if (a->filter)
2111  pp->filter_classify_table_index = set->table_indices[0];
2112  else
2113  pp->filter_classify_table_index = ~0;
2114  pp->pcap_rx_enable = a->rx_enable;
2115  pp->pcap_tx_enable = a->tx_enable;
2116  pp->pcap_drop_enable = a->drop_enable;
2118  }
2119  else
2120  {
2121  pp->pcap_rx_enable = 0;
2122  pp->pcap_tx_enable = 0;
2123  pp->pcap_drop_enable = 0;
2124  pp->filter_classify_table_index = ~0;
2125  if (pm->n_packets_captured)
2126  {
2127  clib_error_t *error;
2129  vlib_cli_output (vm, "Write %d packets to %s, and stop capture...",
2130  pm->n_packets_captured, pm->file_name);
2131  error = pcap_write (pm);
2132  if (pm->flags & PCAP_MAIN_INIT_DONE)
2133  pcap_close (pm);
2134  /* Report I/O errors... */
2135  if (error)
2136  {
2137  clib_error_report (error);
2138  return VNET_API_ERROR_SYSCALL_ERROR_1;
2139  }
2140  vec_free (pm->file_name);
2141  if (a->free_data)
2142  vec_free (pm->pcap_data);
2143  return 0;
2144  }
2145  else
2146  return VNET_API_ERROR_NO_SUCH_ENTRY;
2147  }
2148 
2149  return 0;
2150 }
2151 
2152 static clib_error_t *
2154  unformat_input_t * input, vlib_cli_command_t * cmd)
2155 {
2156  unformat_input_t _line_input, *line_input = &_line_input;
2158  vnet_main_t *vnm = vnet_get_main ();
2159  u8 *filename = 0;
2160  u32 max = 1000;
2161  u32 max_bytes_per_pkt = 512;
2162  int rv;
2163  int rx_enable = 0;
2164  int tx_enable = 0;
2165  int preallocate_data = 0;
2166  int drop_enable = 0;
2167  int status = 0;
2168  int filter = 0;
2169  int free_data = 0;
2170  u32 sw_if_index = 0; /* default: any interface */
2171 
2172  /* Get a line of input. */
2173  if (!unformat_user (input, unformat_line_input, line_input))
2174  return 0;
2175 
2176  while (unformat_check_input (line_input) != UNFORMAT_END_OF_INPUT)
2177  {
2178  if (unformat (line_input, "rx"))
2179  rx_enable = 1;
2180  else if (unformat (line_input, "tx"))
2181  tx_enable = 1;
2182  else if (unformat (line_input, "drop"))
2183  drop_enable = 1;
2184  else if (unformat (line_input, "off"))
2185  rx_enable = tx_enable = drop_enable = 0;
2186  else if (unformat (line_input, "max-bytes-per-pkt %u",
2187  &max_bytes_per_pkt))
2188  ;
2189  else if (unformat (line_input, "max %d", &max))
2190  ;
2191  else if (unformat (line_input, "packets-to-capture %d", &max))
2192  ;
2193  else if (unformat (line_input, "file %U", unformat_vlib_tmpfile,
2194  &filename))
2195  ;
2196  else if (unformat (line_input, "status %=", &status, 1))
2197  ;
2198  else if (unformat (line_input, "intfc %U",
2199  unformat_vnet_sw_interface, vnm, &sw_if_index))
2200  ;
2201  else if (unformat (line_input, "interface %U",
2202  unformat_vnet_sw_interface, vnm, &sw_if_index))
2203  ;
2204  else if (unformat (line_input, "preallocate-data %=",
2205  &preallocate_data, 1))
2206  ;
2207  else if (unformat (line_input, "free-data %=", &free_data, 1))
2208  ;
2209  else if (unformat (line_input, "intfc any")
2210  || unformat (line_input, "interface any"))
2211  sw_if_index = 0;
2212  else if (unformat (line_input, "filter"))
2213  filter = 1;
2214  else
2215  {
2216  return clib_error_return (0, "unknown input `%U'",
2217  format_unformat_error, line_input);
2218  }
2219  }
2220 
2221  unformat_free (line_input);
2222 
2223  /* no need for memset (a, 0, sizeof (*a)), set all fields here. */
2224  a->filename = filename;
2225  a->rx_enable = rx_enable;
2226  a->tx_enable = tx_enable;
2227  a->preallocate_data = preallocate_data;
2228  a->free_data = free_data;
2229  a->drop_enable = drop_enable;
2230  a->status = status;
2231  a->packets_to_capture = max;
2232  a->sw_if_index = sw_if_index;
2233  a->filter = filter;
2234  a->max_bytes_per_pkt = max_bytes_per_pkt;
2235 
2237 
2238  switch (rv)
2239  {
2240  case 0:
2241  break;
2242 
2243  case VNET_API_ERROR_INVALID_VALUE:
2244  return clib_error_return (0, "dispatch trace already enabled...");
2245 
2246  case VNET_API_ERROR_VALUE_EXIST:
2247  return clib_error_return (0, "dispatch trace already disabled...");
2248 
2249  case VNET_API_ERROR_INVALID_VALUE_2:
2250  return clib_error_return
2251  (0, "can't change number of records to capture while tracing...");
2252 
2253  case VNET_API_ERROR_SYSCALL_ERROR_1:
2254  return clib_error_return (0, "I/O writing trace capture...");
2255 
2256  case VNET_API_ERROR_NO_SUCH_ENTRY:
2257  return clib_error_return (0, "No packets captured...");
2258 
2259  case VNET_API_ERROR_INVALID_MEMORY_SIZE:
2260  return clib_error_return (0,
2261  "Max bytes per pkt must be > 32, < 9000...");
2262 
2263  case VNET_API_ERROR_NO_SUCH_LABEL:
2264  return clib_error_return
2265  (0, "No classify filter configured, see 'classify filter...'");
2266 
2267  default:
2268  vlib_cli_output (vm, "WARNING: trace configure returned %d", rv);
2269  break;
2270  }
2271  return 0;
2272 }
2273 
2274 /*?
2275  * This command is used to start or stop a packet capture, or show
2276  * the status of packet capture.
2277  *
2278  * This command has the following optional parameters:
2279  *
2280  *
2281  * - <b>rx</b> - Capture received packets
2282  *
2283  * - <b>tx</b> - Capture transmitted packets
2284  *
2285  * - <b>drop</b> - Capture dropped packets
2286  *
2287  * - <b>off</b> - Stop capturing packets, write results to the specified file
2288  *
2289  * - <b>max <nn></b> - Depth of local buffer. Once '<em>nn</em>' number
2290  * of packets have been received, buffer is flushed to file. Once another
2291  * '<em>nn</em>' number of packets have been received, buffer is flushed
2292  * to file, overwriting previous write. If not entered, value defaults
2293  * to 100. Can only be updated if packet capture is off.
2294  *
2295  * - <b>max-bytes-per-pkt <nnnn></b> - Maximum number of bytes to capture
2296  * for each packet. Must be >= 32, <= 9000.
2297  *
2298  * - <b>preallocate-data</b> - Preallocate the data buffer, to avoid
2299  * vector expansion delays during pcap capture
2300  *
2301  * - <b>free-data</b> - Free the data buffer. Ordinarily it's a feature
2302  * to retain the data buffer so this option is seldom used.
2303  *
2304  * - <b>intfc <interface-name>|any</b> - Used to specify a given interface,
2305  * or use '<em>any</em>' to run packet capture on all interfaces.
2306  * '<em>any</em>' is the default if not provided. Settings from a previous
2307  * packet capture are preserved, so '<em>any</em>' can be used to reset
2308  * the interface setting.
2309  *
2310  * - <b>filter</b> - Use the pcap rx / tx / drop trace filter, which
2311  * must be configured. Use <b>classify filter pcap...</b> to configure the
2312  * filter. The filter will only be executed if the per-interface or
2313  * any-interface tests fail.
2314  *
2315  * - <b>file <name></b> - Used to specify the output filename. The file will
2316  * be placed in the '<em>/tmp</em>' directory, so only the filename is
2317  * supported. Directory should not be entered. If file already exists, file
2318  * will be overwritten. If no filename is provided, the file will be
2319  * named "/tmp/rx.pcap", "/tmp/tx.pcap", "/tmp/rxandtx.pcap", etc.
2320  * Can only be updated if packet capture is off.
2321  *
2322  * - <b>status</b> - Displays the current status and configured attributes
2323  * associated with a packet capture. If packet capture is in progress,
2324  * '<em>status</em>' also will return the number of packets currently in
2325  * the local buffer. All additional attributes entered on command line
2326  * with '<em>status</em>' will be ignored and not applied.
2327  *
2328  * @cliexpar
2329  * Example of how to display the status of a tx packet capture when off:
2330  * @cliexstart{pcap trace status}
2331  * max is 100, for any interface to file /tmp/vpe.pcap
2332  * pcap tx capture is off...
2333  * @cliexend
2334  * Example of how to start a tx packet capture:
2335  * @cliexstart{pcap trace tx max 35 intfc GigabitEthernet0/8/0 file vppTest.pcap}
2336  * @cliexend
2337  * Example of how to display the status of a tx packet capture in progress:
2338  * @cliexstart{pcap trace status}
2339  * max is 35, for interface GigabitEthernet0/8/0 to file /tmp/vppTest.pcap
2340  * pcap tx capture is on: 20 of 35 pkts...
2341  * @cliexend
2342  * Example of how to stop a tx packet capture:
2343  * @cliexstart{pcap trace off}
2344  * captured 21 pkts...
2345  * saved to /tmp/vppTest.pcap...
2346  * @cliexend
2347 ?*/
2348 /* *INDENT-OFF* */
2349 
2350 VLIB_CLI_COMMAND (pcap_tx_trace_command, static) = {
2351  .path = "pcap trace",
2352  .short_help =
2353  "pcap trace [rx] [tx] [drop] [off] [max <nn>] [intfc <interface>|any]\n"
2354  " [file <name>] [status] [max-bytes-per-pkt <nnnn>][filter]\n"
2355  " [preallocate-data][free-data]",
2356  .function = pcap_trace_command_fn,
2357 };
2358 /* *INDENT-ON* */
2359 
2360 /*
2361  * fd.io coding-style-patch-verification: ON
2362  *
2363  * Local Variables:
2364  * eval: (c-set-style "gnu")
2365  * End:
2366  */
uword * sibling_bitmap
Definition: node.h:340
unformat_function_t unformat_vnet_hw_interface
#define vec_validate(V, I)
Make sure vector is long enough for given index (no header, unspecified alignment) ...
Definition: vec.h:509
static clib_error_t * clear_interface_counters(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u8 * format_l2_input_features(u8 *s, va_list *args)
Definition: l2_input.c:68
pcap_main_t pcap_main
Definition: main.h:73
format_function_t format_vnet_sw_interface
static clib_error_t * create_sub_interfaces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define hash_set(h, key, value)
Definition: hash.h:255
char * file_name
File name of pcap output.
Definition: pcap.h:162
static clib_error_t * promiscuous_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * set_hw_class(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
clib_error_t * set_hw_interface_rx_placement(u32 hw_if_index, u32 queue_id, u32 thread_index, u8 is_main)
clib_error_t * set_interface_rss_queues(vlib_main_t *vm, u32 hw_if_index, clib_bitmap_t *bitmap)
static int sw_interface_name_compare(void *a1, void *a2)
void vnet_sw_interface_ip_directed_broadcast(vnet_main_t *vnm, u32 sw_if_index, u8 enable)
Definition: interface.c:703
static clib_error_t * set_state(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 flags
flags
Definition: pcap.h:174
vl_api_mac_address_t mac
Definition: l2.api:502
vl_api_wireguard_peer_flags_t flags
Definition: wireguard.api:103
a
Definition: bitmap.h:538
uword first_worker_thread_index
Definition: devices.h:53
u32 n_packets_to_capture
Number of packets to capture.
Definition: pcap.h:165
static ip6_fib_t * ip6_fib_get(fib_node_index_t index)
Definition: ip6_fib.h:165
static clib_error_t * set_interface_mac_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
mac_address_t * secondary_addrs
Definition: ethernet.h:166
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
u32 max_bytes_per_pkt
Definition: main.h:71
u8 * format_l2_output_features(u8 *s, va_list *args)
Definition: l2_output.c:45
unformat_function_t unformat_hash_string
Definition: hash.h:719
vnet_interface_main_t interface_main
Definition: vnet.h:59
unsigned long u64
Definition: types.h:89
l2_input_config_t * l2input_intf_config(u32 sw_if_index)
Get a pointer to the config for the given interface.
Definition: l2_input.c:517
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:592
word vnet_sw_interface_compare(vnet_main_t *vnm, uword sw_if_index0, uword sw_if_index1)
Definition: interface.c:1218
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1395
static void vnet_clear_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * set_tag(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * renumber_interface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:989
#define hash_set_mem(h, key, value)
Definition: hash.h:275
ip_lookup_main_t lookup_main
Definition: ip4.h:108
static vnet_sw_interface_t * vnet_get_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
uword * sub_interface_sw_if_index_by_id
Definition: interface.h:585
vlib_main_t * vm
Definition: in2out_ed.c:1582
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:122
u8 * format(u8 *s, const char *fmt,...)
Definition: format.c:424
unformat_function_t unformat_vnet_sw_interface
#define vec_validate_aligned(V, I, A)
Make sure vector is long enough for given index (no header, specified alignment)
Definition: vec.h:520
static clib_error_t * clear_hw_interfaces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
struct _vnet_device_class vnet_device_class_t
uword * dq_runtime_index_by_queue
Definition: interface.h:610
static u8 * format_vnet_pcap(u8 *s, va_list *args)
format_function_t format_vnet_sw_if_index_name
unsigned char u8
Definition: types.h:56
u8 id[64]
Definition: dhcp.api:160
static clib_error_t * interface_add_del_mac_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
uword last_worker_thread_index
Definition: devices.h:54
ethernet_main_t ethernet_main
Definition: init.c:45
vnet_hw_interface_rx_mode
Definition: interface.h:53
format_function_t format_vnet_hw_interface
uword unformat_vlib_tmpfile(unformat_input_t *input, va_list *args)
Definition: format.c:192
uword flags
Definition: clib_error.h:29
PCAP main state data structure.
Definition: pcap.h:156
clib_spinlock_t lock
spinlock to protect e.g.
Definition: pcap.h:159
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:61
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:513
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:173
u32 output_sw_if_index
Definition: l2_input.h:36
static vnet_device_class_t * vnet_get_device_class(vnet_main_t *vnm, u32 dev_class_index)
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
Definition: vec.h:350
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:881
static clib_error_t * parse_vlan_sub_interfaces(unformat_input_t *input, vnet_sw_interface_t *template)
Parse subinterface names.
#define vec_elt_at_index(v, i)
Get vector value at index i checking that i is in bounds.
static vnet_sw_interface_t * vnet_get_sup_sw_interface(vnet_main_t *vnm, u32 sw_if_index)
u32 filter_classify_table_index
Definition: main.h:74
#define clib_error_return(e, args...)
Definition: error.h:99
u8 pcap_rx_enable
Definition: main.h:65
unsigned int u32
Definition: types.h:88
static clib_error_t * set_unnumbered(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
A collection of simple counters.
Definition: counter.h:57
u8 * vnet_trace_placeholder
Definition: trace.c:43
void vnet_sw_interface_set_protocol_mtu(vnet_main_t *vnm, u32 sw_if_index, u32 mtu[])
Definition: interface.c:682
static clib_error_t * mtu_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
unformat_function_t unformat_line_input
Definition: format.h:283
static void clib_spinlock_init(clib_spinlock_t *p)
Definition: lock.h:63
u32 max_supported_packet_bytes
Definition: interface.h:576
vl_api_fib_path_type_t type
Definition: fib_types.api:123
vnet_crypto_main_t * cm
Definition: quic_crypto.c:53
vnet_hw_interface_t * hw_interfaces
Definition: interface.h:858
clib_error_t * pcap_close(pcap_main_t *pm)
Close PCAP file.
Definition: pcap.c:74
vlib_worker_thread_t * vlib_worker_threads
Definition: threads.c:34
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
l2_output_config_t * l2output_intf_config(u32 sw_if_index)
Get a pointer to the config for the given interface.
Definition: l2_output.c:616
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:534
vlib_node_t * vlib_get_node_by_name(vlib_main_t *vm, u8 *name)
Definition: node.c:45
u8 pcap_drop_enable
Definition: main.h:69
u8 * pcap_data
Vector of pcap data.
Definition: pcap.h:184
u32 bd_id
Definition: gbp.api:188
int vnet_pcap_dispatch_trace_configure(vnet_pcap_dispatch_trace_args_t *a)
struct _unformat_input_t unformat_input_t
int vnet_hw_interface_get_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode *mode)
Definition: devices.c:313
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:875
vnet_sw_interface_flags_t flags
Definition: interface.h:738
clib_error_t * set_hw_interface_change_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u8 queue_id_valid, u32 queue_id, vnet_hw_interface_rx_mode mode)
ip6_main_t ip6_main
Definition: ip6_forward.c:2781
static clib_error_t * show_sw_interfaces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
vlib_simple_counter_main_t * sw_if_counters
Definition: interface.h:880
word vnet_hw_interface_compare(vnet_main_t *vnm, uword hw_if_index0, uword hw_if_index1)
Definition: interface.c:1232
static clib_error_t * set_interface_rx_placement(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void vnet_sw_interface_update_unnumbered(u32 unnumbered_sw_if_index, u32 ip_sw_if_index, u8 enable)
Definition: interface.c:1557
u32 pcap_sw_if_index
Definition: main.h:72
#define foreach_vlib_main(body)
Definition: threads.h:242
static int compare_interface_names(void *a1, void *a2)
Definition: interface_cli.c:58
uword * hw_interface_class_by_name
Definition: interface.h:868
vl_api_tunnel_mode_t mode
Definition: gre.api:48
clib_error_t * vnet_hw_interface_set_rss_queues(vnet_main_t *vnm, vnet_hw_interface_t *hi, clib_bitmap_t *bitmap)
Definition: interface.c:1696
The IPv4 FIB.
Definition: ip4_fib.h:39
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:597
static clib_error_t * set_interface_rss_queues_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define UNFORMAT_END_OF_INPUT
Definition: format.h:145
static clib_error_t * clear_tag(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
void vnet_interface_features_show(vlib_main_t *vm, u32 sw_if_index, int verbose)
Display the set of driver features configured on a specific interface Called by "show interface" hand...
Definition: feature.c:491
sll srl srl sll sra u16x4 i
Definition: vector_sse42.h:317
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:380
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:113
Definition: ip6.h:71
#define clib_warning(format, args...)
Definition: error.h:59
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:152
static_always_inline l2_bridge_domain_t * l2input_bd_config(u32 bd_index)
Definition: l2_input.h:86
clib_error_t * pcap_write(pcap_main_t *pm)
Write PCAP file.
Definition: pcap.c:89
string name[64]
Definition: ip.api:44
static clib_error_t * pcap_trace_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:158
struct _vnet_classify_main vnet_classify_main_t
Definition: vnet_classify.h:55
Packet header.
Definition: pcap.h:144
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:233
#define PCAP_MAIN_INIT_DONE
Definition: pcap.h:175
void vnet_hw_interface_assign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, uword thread_index)
Definition: devices.c:139
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:696
ip_lookup_main_t lookup_main
Definition: ip6.h:181
IPv4 main type.
Definition: ip4.h:106
static void vnet_set_sw_interface_tag(vnet_main_t *vnm, u8 *tag, u32 sw_if_index)
Bitmaps built as vectors of machine words.
#define clib_error_report(e)
Definition: error.h:113
#define clib_bitmap_free(v)
Free a bitmap.
Definition: bitmap.h:92
vnet_classify_main_t vnet_classify_main
Definition: vnet_classify.c:29
static u8 * vnet_get_sw_interface_tag(vnet_main_t *vnm, u32 sw_if_index)
static clib_error_t * show_hw_interfaces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static void * clib_mem_alloc(uword size)
Definition: mem.h:157
uword unformat_ethernet_interface(unformat_input_t *input, va_list *args)
Definition: interface.c:310
static vlib_main_t * vlib_get_main(void)
Definition: global_funcs.h:23
vl_api_ip4_address_t hi
Definition: arp.api:37
#define vec_elt(v, i)
Get vector value at index i.
static clib_error_t * show_or_clear_hw_interfaces(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd, int is_show)
Definition: interface_cli.c:67
static clib_error_t * show_interface_sec_mac_addr_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
pcap_packet_type_t packet_type
Packet type.
Definition: pcap.h:168
void vnet_hw_interface_set_mtu(vnet_main_t *vnm, u32 hw_if_index, u32 mtu)
Definition: interface.c:730
l2input_main_t l2input_main
Definition: l2_input.c:127
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:967
static void show_bond(vlib_main_t *vm)
Definition: cli.c:892
u32 feature_bitmap
Definition: l2_bd.h:69
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unformat_function_t unformat_vnet_sw_interface_flags
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: ip_interface.h:57
static clib_error_t * vnet_interface_cli_init(vlib_main_t *vm)
u64 uword
Definition: types.h:112
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:1055
static void unformat_free(unformat_input_t *i)
Definition: format.h:163
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:872
static clib_error_t * set_ip_directed_broadcast(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static clib_error_t * set_hw_interface_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u32 queue_id, vnet_hw_interface_rx_mode mode)
u32 index
Definition: flow_types.api:221
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:65
A collection of combined counters.
Definition: counter.h:188
#define hash_get_mem(h, key)
Definition: hash.h:269
int vnet_hw_interface_unassign_rx_thread(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id)
Definition: devices.c:188
u32 l2vtr_get(vlib_main_t *vlib_main, vnet_main_t *vnet_main, u32 sw_if_index, u32 *vtr_op, u32 *push_dot1q, u32 *vtr_tag1, u32 *vtr_tag2)
Get vtag tag rewrite on the given interface.
Definition: l2_vtr.c:347
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
u32 min_supported_packet_bytes
Definition: interface.h:573
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:44
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1144
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, vnet_sw_interface_flags_t flags)
Definition: interface.c:507
u8 * format_mac_address_t(u8 *s, va_list *args)
Definition: mac_address.c:27
uword clib_bitmap_t
Definition: bitmap.h:50
#define vec_foreach(var, vec)
Vector iterator.
vnet_hw_interface_rx_mode default_rx_mode
Definition: interface.h:607
vnet_device_class_t * device_classes
Definition: interface.h:865
u32 bd_find_index(bd_main_t *bdm, u32 bd_id)
Get a bridge domain.
Definition: l2_bd.c:70
u8 pcap_tx_enable
Definition: main.h:67
int vnet_hw_interface_set_rx_mode(vnet_main_t *vnm, u32 hw_if_index, u16 queue_id, vnet_hw_interface_rx_mode mode)
Definition: devices.c:253
static clib_error_t * set_interface_rx_mode(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
clib_error_t * vnet_hw_interface_add_del_mac_address(vnet_main_t *vnm, u32 hw_if_index, const u8 *mac_address, u8 is_add)
Definition: interface.c:1460
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, const u8 *mac_address)
Definition: interface.c:1548
u8 si
Definition: lisp_types.api:47
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:584
vnet_pcap_t pcap
Definition: main.h:204
bd_main_t bd_main
Definition: l2_bd.c:44
#define CLIB_CACHE_LINE_BYTES
Definition: cache.h:59
u32 * fib_index_by_sw_if_index
Definition: ip6.h:196
u32 n_packets_captured
Number of packets currently captured.
Definition: pcap.h:171
static clib_error_t * show_interface_rx_placement_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
format_function_t format_vtr
vnet_device_main_t vnet_device_main
Definition: devices.c:22
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
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:171
u32 ethernet_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:426
clib_error_t * vnet_hw_interface_set_class(vnet_main_t *vnm, u32 hw_if_index, u32 hw_class_index)
Definition: interface.c:1182
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:128