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