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