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