FD.io VPP  v16.12-rc0-308-g931be3a
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  * Interface CLI.
43  */
44 
45 #include <vnet/vnet.h>
46 #include <vnet/ip/ip.h>
47 #include <vppinfra/bitmap.h>
48 #include <vnet/fib/ip4_fib.h>
49 #include <vnet/fib/ip6_fib.h>
50 
51 static int
52 compare_interface_names (void *a1, void *a2)
53 {
54  u32 *hi1 = a1;
55  u32 *hi2 = a2;
56 
57  return vnet_hw_interface_compare (vnet_get_main (), *hi1, *hi2);
58 }
59 
60 static clib_error_t *
62  unformat_input_t * input,
63  vlib_cli_command_t * cmd)
64 {
65  clib_error_t *error = 0;
66  vnet_main_t *vnm = vnet_get_main ();
69  u32 hw_if_index, *hw_if_indices = 0;
70  int i, verbose = -1, is_show, show_bond = 0;
71 
72  is_show = strstr (cmd->path, "show") != 0;
74  {
75  /* See if user wants to show a specific interface. */
76  if (unformat
77  (input, "%U", unformat_vnet_hw_interface, vnm, &hw_if_index))
78  vec_add1 (hw_if_indices, hw_if_index);
79 
80  /* See if user wants to show an interface with a specific hw_if_index. */
81  else if (unformat (input, "%u", &hw_if_index))
82  vec_add1 (hw_if_indices, hw_if_index);
83 
84  else if (unformat (input, "verbose"))
85  verbose = 1; /* this is also the default */
86 
87  else if (unformat (input, "detail"))
88  verbose = 2;
89 
90  else if (unformat (input, "brief"))
91  verbose = 0;
92 
93  else if (unformat (input, "bond"))
94  {
95  show_bond = 1;
96  if (verbose < 0)
97  verbose = 0; /* default to brief for link bonding */
98  }
99 
100  else
101  {
102  error = clib_error_return (0, "unknown input `%U'",
103  format_unformat_error, input);
104  goto done;
105  }
106  }
107 
108  /* Gather interfaces. */
109  if (vec_len (hw_if_indices) == 0)
110  pool_foreach (hi, im->hw_interfaces,
111  vec_add1 (hw_if_indices, hi - im->hw_interfaces));
112 
113  if (verbose < 0)
114  verbose = 1; /* default to verbose (except bond) */
115 
116  if (is_show)
117  {
118  /* Sort by name. */
120 
121  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm, 0, verbose);
122  for (i = 0; i < vec_len (hw_if_indices); i++)
123  {
124  hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
125  if (show_bond == 0) /* show all interfaces */
126  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm,
127  hi, verbose);
128  else if ((hi->bond_info) &&
130  { /* show only bonded interface and all its slave interfaces */
131  int hw_idx;
132  vnet_hw_interface_t *shi;
133  vlib_cli_output (vm, "%U\n", format_vnet_hw_interface, vnm,
134  hi, verbose);
135 
136  /* *INDENT-OFF* */
137  clib_bitmap_foreach (hw_idx, hi->bond_info,
138  ({
139  shi = vnet_get_hw_interface(vnm, hw_idx);
140  vlib_cli_output (vm, "%U\n",
141  format_vnet_hw_interface, vnm, shi, verbose);
142  }));
143  /* *INDENT-ON* */
144  }
145  }
146  }
147  else
148  {
149  for (i = 0; i < vec_len (hw_if_indices); i++)
150  {
152 
153  hi = vnet_get_hw_interface (vnm, hw_if_indices[i]);
155 
156  if (dc->clear_counters)
157  dc->clear_counters (hi->dev_instance);
158  }
159  }
160 
161 done:
162  vec_free (hw_if_indices);
163  return error;
164 }
165 
166 /* *INDENT-OFF* */
167 /*?
168  * Displays various information about the state of the current terminal
169  * session.
170  *
171  * @cliexpar
172  * @cliexstart{show hardware}
173  * Name Link Hardware
174  * GigabitEthernet2/0/0 up GigabitEthernet2/0/0
175  * Ethernet address 00:50:56:b7:7c:83
176  * Intel 82545em_copper
177  * link up, media 1000T full-duplex, master,
178  * 0 unprocessed, 384 total buffers on rx queue 0 ring
179  * 237 buffers in driver rx cache
180  * rx total packets 1816
181  * rx total bytes 181084
182  * rx good packets 1816
183  * rx good bytes 181084
184  * rx 65 127 byte packets 1586
185  * rx 256 511 byte packets 230
186  * tx total packets 346
187  * tx total bytes 90224
188  * tx good packets 346
189  * tx good bytes 88840
190  * tx 64 byte packets 1
191  * tx 65 127 byte packets 115
192  * tx 256 511 byte packets 230
193  * @cliexend
194  ?*/
195 VLIB_CLI_COMMAND (show_hw_interfaces_command, static) = {
196  .path = "show hardware-interfaces",
197  .short_help = "show hardware-interfaces [brief|verbose|detail] [bond] [<if-name1> <if-name2> ...]",
198  .function = show_or_clear_hw_interfaces,
199 };
200 /* *INDENT-ON* */
201 
202 /* *INDENT-OFF* */
203 VLIB_CLI_COMMAND (clear_hw_interface_counters_command, static) = {
204  .path = "clear hardware-interfaces",
205  .short_help = "Clear hardware interfaces statistics",
206  .function = show_or_clear_hw_interfaces,
207 };
208 /* *INDENT-ON* */
209 
210 static int
211 sw_interface_name_compare (void *a1, void *a2)
212 {
213  vnet_sw_interface_t *si1 = a1;
214  vnet_sw_interface_t *si2 = a2;
215 
217  si1->sw_if_index, si2->sw_if_index);
218 }
219 
220 static clib_error_t *
222  unformat_input_t * input, vlib_cli_command_t * cmd)
223 {
224  clib_error_t *error = 0;
225  vnet_main_t *vnm = vnet_get_main ();
227  vnet_sw_interface_t *si, *sorted_sis = 0;
228  u32 sw_if_index = ~(u32) 0;
229  u8 show_addresses = 0;
230  u8 show_features = 0;
231 
233  {
234  /* See if user wants to show specific interface */
235  if (unformat
236  (input, "%U", unformat_vnet_sw_interface, vnm, &sw_if_index))
237  {
238  si = pool_elt_at_index (im->sw_interfaces, sw_if_index);
239  vec_add1 (sorted_sis, si[0]);
240  }
241  else if (unformat (input, "address") || unformat (input, "addr"))
242  show_addresses = 1;
243  else if (unformat (input, "features") || unformat (input, "feat"))
244  show_features = 1;
245  else
246  {
247  error = clib_error_return (0, "unknown input `%U'",
248  format_unformat_error, input);
249  goto done;
250  }
251  }
252 
253  if (show_features)
254  {
255  if (sw_if_index == ~(u32) 0)
256  return clib_error_return (0, "Interface not specified...");
257 
258  vnet_interface_features_show (vm, sw_if_index);
259  return 0;
260  }
261 
262  if (!show_addresses)
263  vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, 0);
264 
265  if (vec_len (sorted_sis) == 0) /* Get all interfaces */
266  {
267  /* Gather interfaces. */
268  sorted_sis =
270  _vec_len (sorted_sis) = 0;
271  pool_foreach (si, im->sw_interfaces, (
272  {
273  vec_add1 (sorted_sis, si[0]);
274  }
275  ));
276 
277  /* Sort by name. */
279  }
280 
281  if (show_addresses)
282  {
283  vec_foreach (si, sorted_sis)
284  {
286  ip4_main_t *im4 = &ip4_main;
287  ip6_main_t *im6 = &ip6_main;
288  ip_lookup_main_t *lm4 = &im4->lookup_main;
289  ip_lookup_main_t *lm6 = &im6->lookup_main;
290  ip_interface_address_t *ia = 0;
291  ip4_address_t *r4;
292  ip6_address_t *r6;
293  u32 fib_index4 = 0, fib_index6 = 0;
294  ip4_fib_t *fib4;
295  ip6_fib_t *fib6;
296  l2_input_config_t *config;
297 
299  fib_index4 = vec_elt (im4->fib_index_by_sw_if_index,
300  si->sw_if_index);
301 
303  fib_index6 = vec_elt (im6->fib_index_by_sw_if_index,
304  si->sw_if_index);
305 
306  fib4 = ip4_fib_get (fib_index4);
307  fib6 = ip6_fib_get (fib_index6);
308 
311  (vm, "%U (%s): \n unnumbered, use %U",
313  vnm, si->sw_if_index,
314  (si->flags & VNET_SW_INTERFACE_FLAG_ADMIN_UP) ? "up" : "dn",
316 
317  else
318  {
319  vlib_cli_output (vm, "%U (%s):",
321  vnm, si->sw_if_index,
323  ? "up" : "dn");
324  }
325 
326  /* Display any L2 addressing info */
327  vec_validate (l2m->configs, si->sw_if_index);
328  config = vec_elt_at_index (l2m->configs, si->sw_if_index);
329  if (config->bridge)
330  {
331  u32 bd_id = l2input_main.bd_configs[config->bd_index].bd_id;
332  vlib_cli_output (vm, " l2 bridge bd_id %d%s%d", bd_id,
333  config->bvi ? " bvi shg " : " shg ",
334  config->shg);
335  }
336  else if (config->xconnect)
337  {
338  vlib_cli_output (vm, " l2 xconnect %U",
340  vnm, config->output_sw_if_index);
341  }
342 
343  /* Display any IP4 addressing info */
344  /* *INDENT-OFF* */
346  1 /* honor unnumbered */,
347  ({
348  r4 = ip_interface_address_get_address (lm4, ia);
349  if (fib4->table_id)
350  {
351  vlib_cli_output (vm, " %U/%d table %d",
352  format_ip4_address, r4,
353  ia->address_length,
354  fib4->table_id);
355  }
356  else
357  {
358  vlib_cli_output (vm, " %U/%d",
359  format_ip4_address, r4,
360  ia->address_length);
361  }
362  }));
363  /* *INDENT-ON* */
364 
365  /* Display any IP6 addressing info */
366  /* *INDENT-OFF* */
368  1 /* honor unnumbered */,
369  ({
370  r6 = ip_interface_address_get_address (lm6, ia);
371  if (fib6->table_id)
372  {
373  vlib_cli_output (vm, " %U/%d table %d",
374  format_ip6_address, r6,
375  ia->address_length,
376  fib6->table_id);
377  }
378  else
379  {
380  vlib_cli_output (vm, " %U/%d",
381  format_ip6_address, r6,
382  ia->address_length);
383  }
384  }));
385  /* *INDENT-ON* */
386  }
387  }
388  else
389  {
390  vec_foreach (si, sorted_sis)
391  {
392  vlib_cli_output (vm, "%U\n", format_vnet_sw_interface, vnm, si);
393  }
394  }
395 
396 done:
397  vec_free (sorted_sis);
398  return error;
399 }
400 
401 /* *INDENT-OFF* */
402 VLIB_CLI_COMMAND (show_sw_interfaces_command, static) = {
403  .path = "show interfaces",
404  .short_help = "show interfaces [address|addr|features|feat] [<if-name1> <if-name2> ...]",
405  .function = show_sw_interfaces,
406 };
407 /* *INDENT-ON* */
408 
409 /* Root of all interface commands. */
410 /* *INDENT-OFF* */
411 VLIB_CLI_COMMAND (vnet_cli_interface_command, static) = {
412  .path = "interface",
413  .short_help = "Interface commands",
414 };
415 /* *INDENT-ON* */
416 
417 /* *INDENT-OFF* */
418 VLIB_CLI_COMMAND (vnet_cli_set_interface_command, static) = {
419  .path = "set interface",
420  .short_help = "Interface commands",
421 };
422 /* *INDENT-ON* */
423 
424 static clib_error_t *
426  unformat_input_t * input, vlib_cli_command_t * cmd)
427 {
428  vnet_main_t *vnm = vnet_get_main ();
432  static vnet_main_t **my_vnet_mains;
433  int i, j, n_counters;
434 
435  vec_reset_length (my_vnet_mains);
436 
437  for (i = 0; i < vec_len (vnet_mains); i++)
438  {
439  if (vnet_mains[i])
440  vec_add1 (my_vnet_mains, vnet_mains[i]);
441  }
442 
443  if (vec_len (vnet_mains) == 0)
444  vec_add1 (my_vnet_mains, vnm);
445 
446  n_counters = vec_len (im->combined_sw_if_counters);
447 
448  for (j = 0; j < n_counters; j++)
449  {
450  for (i = 0; i < vec_len (my_vnet_mains); i++)
451  {
452  im = &my_vnet_mains[i]->interface_main;
453  cm = im->combined_sw_if_counters + j;
455  }
456  }
457 
458  n_counters = vec_len (im->sw_if_counters);
459 
460  for (j = 0; j < n_counters; j++)
461  {
462  for (i = 0; i < vec_len (my_vnet_mains); i++)
463  {
464  im = &my_vnet_mains[i]->interface_main;
465  sm = im->sw_if_counters + j;
467  }
468  }
469 
470  return 0;
471 }
472 
473 /* *INDENT-OFF* */
474 VLIB_CLI_COMMAND (clear_interface_counters_command, static) = {
475  .path = "clear interfaces",
476  .short_help = "Clear interfaces statistics",
477  .function = clear_interface_counters,
478 };
479 /* *INDENT-ON* */
480 
481 /**
482  * Parse subinterface names.
483  *
484  * The following subinterface syntax is supported. The first two are for
485  * backwards compatability:
486  *
487  * <intf-name> <id>
488  * - a subinterface with the name <intf-name>.<id>. The subinterface
489  * is a single dot1q vlan with vlan id <id> and exact-match semantics.
490  *
491  * <intf-name> <min_id>-<max_id>
492  * - a set of the above subinterfaces, repeating for each id
493  * in the range <min_id> to <max_id>
494  *
495  * In the following, exact-match semantics (i.e. the number of vlan tags on the
496  * packet must match the number of tags in the configuration) are used only if
497  * the keyword exact-match is present. Non-exact match is the default.
498  *
499  * <intf-name> <id> dot1q <outer_id> [exact-match]
500  * - a subinterface with the name <intf-name>.<id>. The subinterface
501  * is a single dot1q vlan with vlan id <outer_id>.
502  *
503  * <intf-name> <id> dot1q any [exact-match]
504  * - a subinterface with the name <intf-name>.<id>. The subinterface
505  * is a single dot1q vlan with any vlan id.
506  *
507  * <intf-name> <id> dot1q <outer_id> inner-dot1q <inner_id> [exact-match]
508  * - a subinterface with the name <intf-name>.<id>. The subinterface
509  * is a double dot1q vlan with outer vlan id <outer_id> and inner vlan id
510  * <inner_id>.
511  *
512  * <intf-name> <id> dot1q <outer_id> inner-dot1q any [exact-match]
513  * - a subinterface with the name <intf-name>.<id>. The subinterface
514  * is a double dot1q vlan with outer vlan id <id> and any inner vlan id.
515  *
516  * <intf-name> <id> dot1q any inner-dot1q any [exact-match]
517  *
518  * - a subinterface with the name <intf-name>.<id>. The subinterface
519  * is a double dot1q vlan with any outer vlan id and any inner vlan id.
520  *
521  * For each of the above CLI, there is a duplicate that uses the keyword
522  * "dot1ad" in place of the first "dot1q". These interfaces use ethertype
523  * 0x88ad in place of 0x8100 for the outer ethertype. Note that for double-
524  * tagged packets the inner ethertype is always 0x8100. Also note that
525  * the dot1q and dot1ad naming spaces are independent, so it is legal to
526  * have both "Gig3/0/0.1 dot1q 100" and "Gig3/0/0.2 dot1ad 100". For example:
527  *
528  * <intf-name> <id> dot1ad <outer_id> inner-dot1q <inner_id> [exact-match]
529  * - a subinterface with the name <intf-name>.<id>. The subinterface
530  * is a double dot1ad vlan with outer vlan id <outer_id> and inner vlan
531  * id <inner_id>.
532  *
533  * <intf-name> <id> untagged
534  * - a subinterface with the name <intf-name>.<id>. The subinterface
535  * has no vlan tags. Only one can be specified per interface.
536  *
537  * <intf-name> <id> default
538  * - a subinterface with the name <intf-name>.<id>. This is associated
539  * with a packet that did not match any other configured subinterface
540  * on this interface. Only one can be specified per interface.
541  */
542 
543 static clib_error_t *
545  vnet_sw_interface_t * template)
546 {
547  clib_error_t *error = 0;
548  u32 inner_vlan, outer_vlan;
549 
550  if (unformat (input, "any inner-dot1q any"))
551  {
552  template->sub.eth.flags.two_tags = 1;
553  template->sub.eth.flags.outer_vlan_id_any = 1;
554  template->sub.eth.flags.inner_vlan_id_any = 1;
555  }
556  else if (unformat (input, "any"))
557  {
558  template->sub.eth.flags.one_tag = 1;
559  template->sub.eth.flags.outer_vlan_id_any = 1;
560  }
561  else if (unformat (input, "%d inner-dot1q any", &outer_vlan))
562  {
563  template->sub.eth.flags.two_tags = 1;
564  template->sub.eth.flags.inner_vlan_id_any = 1;
565  template->sub.eth.outer_vlan_id = outer_vlan;
566  }
567  else if (unformat (input, "%d inner-dot1q %d", &outer_vlan, &inner_vlan))
568  {
569  template->sub.eth.flags.two_tags = 1;
570  template->sub.eth.outer_vlan_id = outer_vlan;
571  template->sub.eth.inner_vlan_id = inner_vlan;
572  }
573  else if (unformat (input, "%d", &outer_vlan))
574  {
575  template->sub.eth.flags.one_tag = 1;
576  template->sub.eth.outer_vlan_id = outer_vlan;
577  }
578  else
579  {
580  error = clib_error_return (0, "expected dot1q config, got `%U'",
581  format_unformat_error, input);
582  goto done;
583  }
584 
586  {
587  if (unformat (input, "exact-match"))
588  {
589  template->sub.eth.flags.exact_match = 1;
590  }
591  }
592 
593 done:
594  return error;
595 }
596 
597 static clib_error_t *
599  unformat_input_t * input, vlib_cli_command_t * cmd)
600 {
601  vnet_main_t *vnm = vnet_get_main ();
602  clib_error_t *error = 0;
603  u32 hw_if_index, sw_if_index;
605  u32 id, id_min, id_max;
606  vnet_sw_interface_t template;
607 
608  hw_if_index = ~0;
609  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
610  {
611  error = clib_error_return (0, "unknown interface `%U'",
612  format_unformat_error, input);
613  goto done;
614  }
615 
616  memset (&template, 0, sizeof (template));
617  template.sub.eth.raw_flags = 0;
618 
619  if (unformat (input, "%d default", &id_min))
620  {
621  id_max = id_min;
622  template.sub.eth.flags.default_sub = 1;
623  }
624  else if (unformat (input, "%d untagged", &id_min))
625  {
626  id_max = id_min;
627  template.sub.eth.flags.no_tags = 1;
628  template.sub.eth.flags.exact_match = 1;
629  }
630  else if (unformat (input, "%d dot1q", &id_min))
631  {
632  /* parse dot1q config */
633  id_max = id_min;
634  error = parse_vlan_sub_interfaces (input, &template);
635  if (error)
636  goto done;
637  }
638  else if (unformat (input, "%d dot1ad", &id_min))
639  {
640  /* parse dot1ad config */
641  id_max = id_min;
642  template.sub.eth.flags.dot1ad = 1;
643  error = parse_vlan_sub_interfaces (input, &template);
644  if (error)
645  goto done;
646  }
647  else if (unformat (input, "%d-%d", &id_min, &id_max))
648  {
649  template.sub.eth.flags.one_tag = 1;
650  template.sub.eth.flags.exact_match = 1;
651  if (id_min > id_max)
652  goto id_error;
653  }
654  else if (unformat (input, "%d", &id_min))
655  {
656  id_max = id_min;
657  template.sub.eth.flags.one_tag = 1;
658  template.sub.eth.outer_vlan_id = id_min;
659  template.sub.eth.flags.exact_match = 1;
660  }
661  else
662  {
663  id_error:
664  error = clib_error_return (0, "expected ID or ID MIN-MAX, got `%U'",
665  format_unformat_error, input);
666  goto done;
667  }
668 
669  hi = vnet_get_hw_interface (vnm, hw_if_index);
670 
672  {
673  error =
675  "not allowed as %v belong to a BondEthernet interface",
676  hi->name);
677  goto done;
678  }
679 
680  for (id = id_min; id <= id_max; id++)
681  {
682  uword *p;
684  u64 sup_and_sub_key = ((u64) (hi->sw_if_index) << 32) | (u64) id;
685  u64 *kp;
686 
687  p = hash_get_mem (im->sw_if_index_by_sup_and_sub, &sup_and_sub_key);
688  if (p)
689  {
690  if (CLIB_DEBUG > 0)
691  clib_warning ("sup sw_if_index %d, sub id %d already exists\n",
692  hi->sw_if_index, id);
693  continue;
694  }
695 
696  kp = clib_mem_alloc (sizeof (*kp));
697  *kp = sup_and_sub_key;
698 
699  template.type = VNET_SW_INTERFACE_TYPE_SUB;
700  template.sup_sw_if_index = hi->sw_if_index;
701  template.sub.id = id;
702  if (id_min < id_max)
703  template.sub.eth.outer_vlan_id = id;
704 
705  error = vnet_create_sw_interface (vnm, &template, &sw_if_index);
706  if (error)
707  goto done;
708 
709  hash_set (hi->sub_interface_sw_if_index_by_id, id, sw_if_index);
710  hash_set_mem (im->sw_if_index_by_sup_and_sub, kp, sw_if_index);
712  vnet_get_main (), sw_if_index);
713  }
714 
715 done:
716  return error;
717 }
718 
719 /* *INDENT-OFF* */
720 /*?
721  * Create vlan subinterfaces
722  *
723  * @cliexpar
724  * @cliexstart{create sub-interfaces}
725  *
726  * To create a vlan subinterface 11 to process packets on 802.1q VLAN id 11, use:
727  *
728  * vpp# create sub GigabitEthernet2/0/0 11
729  *
730  * This shorthand is equivalent to:
731  * vpp# create sub GigabitEthernet2/0/0 11 dot1q 11 exact-match
732  *
733  * You can specify a subinterface number that is different from the vlan id:
734  * vpp# create sub GigabitEthernet2/0/0 11 dot1q 100
735  *
736  * You can create qinq and q-in-any interfaces:
737  * vpp# create sub GigabitEthernet2/0/0 11 dot1q 100 inner-dot1q 200
738  * vpp# create sub GigabitEthernet2/0/0 12 dot1q 100 inner-dot1q any
739  *
740  * You can also create dot1ad interfaces:
741  * vpp# create sub GigabitEthernet2/0/0 11 dot1ad 11
742  * vpp# create sub GigabitEthernet2/0/0 12 dot1q 100 inner-dot1q 200
743  *
744  * Subinterfaces can be configured as either exact-match or non-exact match.
745  * Non-exact match is the CLI default. If exact-match is specified,
746  * packets must have the same number of vlan tags as the configuration.
747  * For non-exact-match, packets must at least that number of tags.
748  * L3 (routed) interfaces must be configured as exact-match.
749  * L2 interfaces are typically configured as non-exact-match.
750  *
751  * For example, a packet with outer vlan 100 and inner 200 would match this interface:
752  * vpp# create sub GigabitEthernet2/0/0 5 dot1q 100
753  *
754  * but would not match this interface:
755  * vpp# create sub GigabitEthernet2/0/0 5 dot1q 100 exact-match
756  *
757  * There are two special subinterfaces that can be configured. Subinterface untagged has no vlan tags:
758  * vpp# create sub GigabitEthernet2/0/0 5 untagged
759  *
760  * The subinterface default matches any packet that does not match any other subinterface:
761  * vpp# create sub GigabitEthernet2/0/0 7 default
762  * @cliexend
763  ?*/
764 VLIB_CLI_COMMAND (create_sub_interfaces_command, static) = {
765  .path = "create sub-interfaces",
766  .short_help = "create sub-interfaces <nn>[-<nn>] [dot1q|dot1ad|default|untagged]",
767  .function = create_sub_interfaces,
768 };
769 /* *INDENT-ON* */
770 
771 static clib_error_t *
773  unformat_input_t * input, vlib_cli_command_t * cmd)
774 {
775  vnet_main_t *vnm = vnet_get_main ();
776  clib_error_t *error;
777  u32 sw_if_index, flags;
778 
779  sw_if_index = ~0;
780  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
781  {
782  error = clib_error_return (0, "unknown interface `%U'",
783  format_unformat_error, input);
784  goto done;
785  }
786 
787  if (!unformat (input, "%U", unformat_vnet_sw_interface_flags, &flags))
788  {
789  error = clib_error_return (0, "unknown flags `%U'",
790  format_unformat_error, input);
791  goto done;
792  }
793 
794  error = vnet_sw_interface_set_flags (vnm, sw_if_index, flags);
795  if (error)
796  goto done;
797 
798 done:
799  return error;
800 }
801 
802 
803 /* *INDENT-OFF* */
804 /*?
805  * Interface admin up/down
806  *
807  * @cliexpar
808  * @cliexstart{set interface state}
809  * vpp# set interface state GigabitEthernet2/0/0 up
810  * vpp# set interface state GigabitEthernet2/0/0 down
811  * @cliexend
812  ?*/
813 VLIB_CLI_COMMAND (set_state_command, static) = {
814  .path = "set interface state",
815  .short_help = "Set interface state",
816  .function = set_state,
817 };
818 /* *INDENT-ON* */
819 
820 static clib_error_t *
822  unformat_input_t * input, vlib_cli_command_t * cmd)
823 {
824  vnet_main_t *vnm = vnet_get_main ();
825  u32 unnumbered_sw_if_index;
826  u32 inherit_from_sw_if_index;
828  int is_set = 0;
829  int is_del = 0;
830 
831  if (unformat (input, "%U use %U",
832  unformat_vnet_sw_interface, vnm, &unnumbered_sw_if_index,
833  unformat_vnet_sw_interface, vnm, &inherit_from_sw_if_index))
834  is_set = 1;
835  else if (unformat (input, "del %U",
837  &unnumbered_sw_if_index))
838  is_del = 1;
839  else
840  return clib_error_return (0, "parse error '%U'",
841  format_unformat_error, input);
842 
843  si = vnet_get_sw_interface (vnm, unnumbered_sw_if_index);
844  if (is_del)
845  {
847  si->unnumbered_sw_if_index = (u32) ~ 0;
848  ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 0);
849  ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 0);
850  }
851  else if (is_set)
852  {
854  si->unnumbered_sw_if_index = inherit_from_sw_if_index;
855  ip4_sw_interface_enable_disable (unnumbered_sw_if_index, 1);
856  ip6_sw_interface_enable_disable (unnumbered_sw_if_index, 1);
857  }
858 
859  return 0;
860 }
861 
862 /* *INDENT-OFF* */
863 VLIB_CLI_COMMAND (set_unnumbered_command, static) = {
864  .path = "set interface unnumbered",
865  .short_help = "set interface unnumbered [<intfc> use <intfc> | del <intfc>]",
866  .function = set_unnumbered,
867 };
868 /* *INDENT-ON* */
869 
870 
871 
872 static clib_error_t *
874  unformat_input_t * input, vlib_cli_command_t * cmd)
875 {
876  vnet_main_t *vnm = vnet_get_main ();
878  clib_error_t *error;
879  u32 hw_if_index, hw_class_index;
880 
881  hw_if_index = ~0;
882  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
883  {
884  error = clib_error_return (0, "unknown hardware interface `%U'",
885  format_unformat_error, input);
886  goto done;
887  }
888 
889  if (!unformat_user (input, unformat_hash_string,
890  im->hw_interface_class_by_name, &hw_class_index))
891  {
892  error = clib_error_return (0, "unknown hardware class `%U'",
893  format_unformat_error, input);
894  goto done;
895  }
896 
897  error = vnet_hw_interface_set_class (vnm, hw_if_index, hw_class_index);
898  if (error)
899  goto done;
900 
901 done:
902  return error;
903 }
904 
905 /* *INDENT-OFF* */
906 VLIB_CLI_COMMAND (set_hw_class_command, static) = {
907  .path = "set interface hw-class",
908  .short_help = "Set interface hardware class",
909  .function = set_hw_class,
910 };
911 /* *INDENT-ON* */
912 
913 static clib_error_t *
915 {
916  return 0;
917 }
918 
920 
921 static clib_error_t *
923  unformat_input_t * input,
924  vlib_cli_command_t * cmd)
925 {
926  u32 hw_if_index;
927  u32 new_dev_instance;
928  vnet_main_t *vnm = vnet_get_main ();
929  int rv;
930 
931  if (!unformat_user (input, unformat_vnet_hw_interface, vnm, &hw_if_index))
932  return clib_error_return (0, "unknown hardware interface `%U'",
933  format_unformat_error, input);
934 
935  if (!unformat (input, "%d", &new_dev_instance))
936  return clib_error_return (0, "new dev instance missing");
937 
938  rv = vnet_interface_name_renumber (hw_if_index, new_dev_instance);
939 
940  switch (rv)
941  {
942  case 0:
943  break;
944 
945  default:
946  return clib_error_return (0, "vnet_interface_name_renumber returned %d",
947  rv);
948 
949  }
950 
951  return 0;
952 }
953 
954 
955 /* *INDENT-OFF* */
956 VLIB_CLI_COMMAND (renumber_interface_command, static) = {
957  .path = "renumber interface",
958  .short_help = "renumber interface <if-name> <new-dev-instance>",
959  .function = renumber_interface_command_fn,
960 };
961 /* *INDENT-ON* */
962 
963 static clib_error_t *
965  unformat_input_t * input, vlib_cli_command_t * cmd)
966 {
967  vnet_main_t *vnm = vnet_get_main ();
968  u32 hw_if_index;
972 
973  if (unformat (input, "on %U",
974  unformat_vnet_hw_interface, vnm, &hw_if_index))
975  ;
976  else if (unformat (input, "off %U",
977  unformat_ethernet_interface, vnm, &hw_if_index))
978  flags = 0;
979  else
980  return clib_error_return (0, "unknown input `%U'",
981  format_unformat_error, input);
982 
983  eif = ethernet_get_interface (em, hw_if_index);
984  if (!eif)
985  return clib_error_return (0, "not supported");
986 
987  ethernet_set_flags (vnm, hw_if_index, flags);
988  return 0;
989 }
990 
991 /* *INDENT-OFF* */
992 VLIB_CLI_COMMAND (set_interface_promiscuous_cmd, static) = {
993  .path = "set interface promiscuous",
994  .short_help = "set interface promiscuous [on | off] <intfc>",
995  .function = promiscuous_cmd,
996 };
997 /* *INDENT-ON* */
998 
999 static clib_error_t *
1001 {
1002  vnet_main_t *vnm = vnet_get_main ();
1003  u32 hw_if_index, mtu;
1006 
1007  if (unformat (input, "%d %U", &mtu,
1008  unformat_vnet_hw_interface, vnm, &hw_if_index))
1009  {
1010  vnet_hw_interface_t *hi = vnet_get_hw_interface (vnm, hw_if_index);
1011  ethernet_interface_t *eif = ethernet_get_interface (em, hw_if_index);
1012 
1013  if (!eif)
1014  return clib_error_return (0, "not supported");
1015 
1016  if (mtu < hi->min_supported_packet_bytes)
1017  return clib_error_return (0, "Invalid mtu (%d): "
1018  "must be >= min pkt bytes (%d)", mtu,
1020 
1021  if (mtu > hi->max_supported_packet_bytes)
1022  return clib_error_return (0, "Invalid mtu (%d): must be <= (%d)", mtu,
1024 
1025  if (hi->max_packet_bytes != mtu)
1026  {
1027  hi->max_packet_bytes = mtu;
1028  ethernet_set_flags (vnm, hw_if_index, flags);
1029  }
1030  }
1031  else
1032  return clib_error_return (0, "unknown input `%U'",
1033  format_unformat_error, input);
1034  return 0;
1035 }
1036 
1037 /* *INDENT-OFF* */
1038 VLIB_CLI_COMMAND (set_interface_mtu_cmd, static) = {
1039  .path = "set interface mtu",
1040  .short_help = "set interface mtu <value> <intfc>",
1041  .function = mtu_cmd,
1042 };
1043 /* *INDENT-ON* */
1044 
1045 static clib_error_t *
1047  vlib_cli_command_t * cmd)
1048 {
1049  vnet_main_t *vnm = vnet_get_main ();
1050  clib_error_t *error = 0;
1051  u32 sw_if_index = ~0;
1052  u64 mac = 0;
1053 
1054  if (!unformat_user (input, unformat_vnet_sw_interface, vnm, &sw_if_index))
1055  {
1056  error = clib_error_return (0, "unknown interface `%U'",
1057  format_unformat_error, input);
1058  goto done;
1059  }
1060  if (!unformat_user (input, unformat_ethernet_address, &mac))
1061  {
1062  error = clib_error_return (0, "expected mac address `%U'",
1063  format_unformat_error, input);
1064  goto done;
1065  }
1066  error = vnet_hw_interface_change_mac_address (vnm, sw_if_index, mac);
1067 done:
1068  return error;
1069 }
1070 
1071 /*?
1072  * The '<em>set interface mac address </em>' command allows to set MAC address of given interface.
1073  * In case of NIC interfaces the one has to support MAC address change. A side effect of MAC address
1074  * change are changes of MAC addresses in FIB tables (ipv4 and ipv6).
1075  *
1076  * @cliexpar
1077  * @parblock
1078  * Example of how to change MAC Address of interface:
1079  * @cliexcmd{set interface mac address GigabitEthernet0/8/0 aa:bb:cc:dd:ee:01}
1080  * @cliexcmd{set interface mac address host-vpp0 aa:bb:cc:dd:ee:02}
1081  * @cliexcmd{set interface mac address tap-0 aa:bb:cc:dd:ee:03}
1082  * @cliexcmd{set interface mac address pg0 aa:bb:cc:dd:ee:04}
1083  * @endparblock
1084 ?*/
1085 /* *INDENT-OFF* */
1086 VLIB_CLI_COMMAND (set_interface_mac_address_cmd, static) = {
1087  .path = "set interface mac address",
1088  .short_help = "set interface mac address <intfc> <mac-address>",
1089  .function = set_interface_mac_address,
1090 };
1091 /* *INDENT-ON* */
1092 
1093 /*
1094  * fd.io coding-style-patch-verification: ON
1095  *
1096  * Local Variables:
1097  * eval: (c-set-style "gnu")
1098  * End:
1099  */
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:396
#define foreach_ip_interface_address(lm, a, sw_if_index, loop, body)
Definition: lookup.h:434
static clib_error_t * clear_interface_counters(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define VNET_SW_INTERFACE_FLAG_UNNUMBERED
Definition: interface.h:497
vmrglw vmrglh hi
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:254
l2_input_config_t * configs
Definition: l2_input.h:66
sll srl srl sll sra u16x4 i
Definition: vector_sse2.h:343
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)
uword unformat(unformat_input_t *i, char *fmt,...)
Definition: unformat.c:966
static int sw_interface_name_compare(void *a1, void *a2)
static clib_error_t * set_state(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
static ip6_fib_t * ip6_fib_get(fib_node_index_t index)
Definition: ip6_fib.h:108
static clib_error_t * set_interface_mac_address(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
unformat_function_t unformat_hash_string
Definition: hash.h:681
vnet_interface_main_t interface_main
Definition: vnet.h:72
clib_error_t * vnet_hw_interface_change_mac_address(vnet_main_t *vnm, u32 hw_if_index, u64 mac_address)
Definition: interface.c:1321
#define UNFORMAT_END_OF_INPUT
Definition: format.h:143
static vnet_hw_interface_t * vnet_get_hw_interface(vnet_main_t *vnm, u32 hw_if_index)
vnet_main_t ** vnet_mains
Definition: vnet.h:92
#define vec_add1(V, E)
Add 1 element to end of vector (unspecified alignment).
Definition: vec.h:482
word vnet_sw_interface_compare(vnet_main_t *vnm, uword sw_if_index0, uword sw_if_index1)
Definition: interface.c:1041
int vnet_interface_name_renumber(u32 sw_if_index, u32 new_show_dev_instance)
Definition: interface.c:1177
static clib_error_t * renumber_interface_command_fn(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
#define hash_set_mem(h, key, value)
Definition: hash.h:274
ip_lookup_main_t lookup_main
Definition: ip4.h:96
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:423
u32 * fib_index_by_sw_if_index
Table index indexed by software interface.
Definition: ip4.h:104
unformat_function_t unformat_vnet_sw_interface
struct _vnet_device_class vnet_device_class_t
format_function_t format_vnet_sw_if_index_name
#define vec_reset_length(v)
Reset vector length to zero NULL-pointer tolerant.
ethernet_main_t ethernet_main
Definition: ethernet.h:279
vnet_main_t * vnet_get_main(void)
Definition: misc.c:46
format_function_t format_vnet_hw_interface
uword flags
Definition: error.h:83
void vlib_clear_combined_counters(vlib_combined_counter_main_t *cm)
Clear a collection of combined counters.
Definition: counter.c:67
#define pool_foreach(VAR, POOL, BODY)
Iterate through pool.
Definition: pool.h:348
#define VLIB_INIT_FUNCTION(x)
Definition: init.h:111
u32 output_sw_if_index
Definition: l2_input.h:35
#define vec_new(T, N)
Create new vector of given type and length (unspecified alignment, no header).
Definition: vec.h:270
vlib_combined_counter_main_t * combined_sw_if_counters
Definition: interface.h:577
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.
#define clib_warning(format, args...)
Definition: error.h:59
unsigned long u64
Definition: types.h:89
uword unformat_user(unformat_input_t *input, unformat_function_t *func,...)
Definition: unformat.c:977
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:59
void vnet_interface_features_show(vlib_main_t *vm, u32 sw_if_index)
Display the set of driver features configured on a specific interface Called by "show interface" hand...
Definition: feature.c:272
static clib_error_t * mtu_cmd(vlib_main_t *vm, unformat_input_t *input, vlib_cli_command_t *cmd)
u32 max_supported_packet_bytes
Definition: interface.h:406
vnet_hw_interface_t * hw_interfaces
Definition: interface.h:554
#define clib_bitmap_foreach(i, ai, body)
Macro to iterate across set bits in a bitmap.
Definition: bitmap.h:361
#define pool_elt_at_index(p, i)
Returns pointer to element at given index.
Definition: pool.h:369
void ip4_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip4_forward.c:709
uword * sw_if_index_by_sup_and_sub
Definition: interface.h:571
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:576
word vnet_hw_interface_compare(vnet_main_t *vnm, uword hw_if_index0, uword hw_if_index1)
Definition: interface.c:1055
void vlib_cli_output(vlib_main_t *vm, char *fmt,...)
Definition: cli.c:575
static int compare_interface_names(void *a1, void *a2)
Definition: interface_cli.c:52
uword * hw_interface_class_by_name
Definition: interface.h:564
#define VNET_HW_INTERFACE_BOND_INFO_SLAVE
Definition: interface.h:434
#define vec_free(V)
Free vector&#39;s memory (no header).
Definition: vec.h:300
static ip4_fib_t * ip4_fib_get(u32 index)
Get the FIB at the given index.
Definition: ip4_fib.h:71
Definition: ip6.h:66
Definition: ip4.h:48
#define ETHERNET_INTERFACE_FLAG_MTU
Definition: ethernet.h:118
#define ETHERNET_INTERFACE_FLAG_ACCEPT_ALL
Definition: ethernet.h:113
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:61
#define VLIB_CLI_COMMAND(x,...)
Definition: cli.h:154
#define VNET_SW_INTERFACE_FLAG_ADMIN_UP
Definition: interface.h:490
uword unformat_ethernet_address(unformat_input_t *input, va_list *args)
Definition: format.c:245
unsigned int u32
Definition: types.h:88
u8 * format_unformat_error(u8 *s, va_list *va)
Definition: unformat.c:91
ip6_main_t ip6_main
Definition: ip6_forward.c:2655
ip_lookup_main_t lookup_main
Definition: ip6.h:132
IPv4 main type.
Definition: ip4.h:95
Bitmaps built as vectors of machine words.
char * path
Definition: cli.h:95
static void * clib_mem_alloc(uword size)
Definition: mem.h:109
uword unformat_ethernet_interface(unformat_input_t *input, va_list *args)
Definition: interface.c:184
u64 uword
Definition: types.h:112
#define vec_elt(v, i)
Get vector value at index i.
l2input_main_t l2input_main
Definition: l2_input.c:87
ethernet_interface_t * ethernet_get_interface(ethernet_main_t *em, u32 hw_if_index)
Definition: interface.c:543
#define vec_len(v)
Number of elements in vector (rvalue-only, NULL tolerant)
unsigned char u8
Definition: types.h:56
unformat_function_t unformat_vnet_sw_interface_flags
static clib_error_t * vnet_interface_cli_init(vlib_main_t *vm)
#define vec_sort_with_function(vec, f)
Sort a vector using the supplied element comparison function.
Definition: vec.h:920
vnet_sw_interface_t * sw_interfaces
Definition: interface.h:568
l2_bridge_domain_t * bd_configs
Definition: l2_input.h:69
A collection of combined counters.
Definition: counter.h:212
#define hash_get_mem(h, key)
Definition: hash.h:268
static uword unformat_check_input(unformat_input_t *i)
Definition: format.h:169
u32 min_supported_packet_bytes
Definition: interface.h:403
void vlib_clear_simple_counters(vlib_simple_counter_main_t *cm)
Clear a collection of simple counters.
Definition: counter.c:43
ip4_main_t ip4_main
Global ip4 main structure.
Definition: ip4_forward.c:1060
#define vec_foreach(var, vec)
Vector iterator.
clib_error_t * vnet_sw_interface_set_flags(vnet_main_t *vnm, u32 sw_if_index, u32 flags)
Definition: interface.c:530
vnet_device_class_t * device_classes
Definition: interface.h:561
#define clib_error_return(e, args...)
Definition: error.h:111
struct _unformat_input_t unformat_input_t
clib_error_t * vnet_create_sw_interface(vnet_main_t *vnm, vnet_sw_interface_t *template, u32 *sw_if_index)
Definition: interface.c:582
u32 flags
Definition: vhost-user.h:75
u32 * fib_index_by_sw_if_index
Definition: ip6.h:141
void ip6_sw_interface_enable_disable(u32 sw_if_index, u32 is_enable)
Definition: ip6_forward.c:412
u32 ethernet_set_flags(vnet_main_t *vnm, u32 hw_if_index, u32 flags)
Definition: interface.c:298
clib_error_t * vnet_hw_interface_set_class(vnet_main_t *vnm, u32 hw_if_index, u32 hw_class_index)
Definition: interface.c:1000
static uword pool_elts(void *v)
Number of active elements in a pool.
Definition: pool.h:109