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