Line data Source code
1 : /*
2 : * Copyright (c) 2021 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 : #include <vnet/vnet.h>
17 : #include <vlib/vlib.h>
18 :
19 : static clib_error_t *
20 0 : monitor_interface_command_fn (vlib_main_t *vm, unformat_input_t *input,
21 : vlib_cli_command_t *cmd)
22 : {
23 0 : const vnet_main_t *vnm = vnet_get_main ();
24 0 : const vlib_combined_counter_main_t *counters =
25 : vnm->interface_main.combined_sw_if_counters;
26 0 : f64 refresh_interval = 1.0;
27 0 : u32 refresh_count = ~0;
28 0 : clib_error_t *error = 0;
29 : vlib_counter_t vrx[2], vtx[2];
30 : f64 ts[2];
31 0 : u32 hw_if_index = ~0;
32 0 : u8 spin = 0;
33 :
34 0 : while (unformat_check_input (input) != UNFORMAT_END_OF_INPUT)
35 : {
36 0 : if (unformat (input, "%U", unformat_vnet_hw_interface, vnm,
37 : &hw_if_index))
38 : ;
39 0 : else if (unformat (input, "interval %f", &refresh_interval))
40 : ;
41 0 : else if (unformat (input, "count %u", &refresh_count))
42 : ;
43 : else
44 : {
45 0 : error = clib_error_return (0, "unknown input `%U'",
46 : format_unformat_error, input);
47 0 : goto done;
48 : }
49 : }
50 :
51 0 : if (hw_if_index == ~0)
52 : {
53 0 : error = clib_error_return (0, "no interface passed");
54 0 : goto done;
55 : }
56 :
57 0 : vlib_get_combined_counter (counters + VNET_INTERFACE_COUNTER_RX, hw_if_index,
58 0 : &vrx[spin]);
59 0 : vlib_get_combined_counter (counters + VNET_INTERFACE_COUNTER_TX, hw_if_index,
60 0 : &vtx[spin]);
61 0 : ts[spin] = vlib_time_now (vm);
62 :
63 0 : while (refresh_count--)
64 : {
65 : f64 sleep_interval, tsd;
66 :
67 0 : while (((sleep_interval =
68 0 : ts[spin] + refresh_interval - vlib_time_now (vm)) > 0.0))
69 : {
70 0 : uword event_type, *event_data = 0;
71 0 : vlib_process_wait_for_event_or_clock (vm, sleep_interval);
72 0 : event_type = vlib_process_get_events (vm, &event_data);
73 0 : switch (event_type)
74 : {
75 0 : case ~0: /* no events => timeout */
76 0 : break;
77 0 : default:
78 : /* someone pressed a key, abort */
79 0 : vlib_cli_output (vm, "Aborted due to a keypress.");
80 0 : goto done;
81 : }
82 0 : vec_free (event_data);
83 : }
84 0 : spin ^= 1;
85 0 : vlib_get_combined_counter (counters + VNET_INTERFACE_COUNTER_RX,
86 0 : hw_if_index, &vrx[spin]);
87 0 : vlib_get_combined_counter (counters + VNET_INTERFACE_COUNTER_TX,
88 0 : hw_if_index, &vtx[spin]);
89 0 : ts[spin] = vlib_time_now (vm);
90 :
91 0 : tsd = ts[spin] - ts[spin ^ 1];
92 0 : vlib_cli_output (
93 : vm, "rx: %Upps %Ubps tx: %Upps %Ubps", format_base10,
94 0 : (u64) ((vrx[spin].packets - vrx[spin ^ 1].packets) / tsd),
95 : format_base10,
96 0 : (u64) (8 * (vrx[spin].bytes - vrx[spin ^ 1].bytes) / tsd),
97 : format_base10,
98 0 : (u64) ((vtx[spin].packets - vtx[spin ^ 1].packets) / tsd),
99 : format_base10,
100 0 : (u64) (8 * (vtx[spin].bytes - vtx[spin ^ 1].bytes) / tsd));
101 : }
102 :
103 0 : done:
104 0 : return error;
105 : }
106 :
107 272887 : VLIB_CLI_COMMAND (monitor_interface_command, static) = {
108 : .path = "monitor interface",
109 : .short_help =
110 : "monitor interface <interface> [interval <intv>] [count <count>]",
111 : .function = monitor_interface_command_fn,
112 : .is_mp_safe = 1,
113 : };
114 :
115 : /*
116 : * fd.io coding-style-patch-verification: ON
117 : *
118 : * Local Variables:
119 : * eval: (c-set-style "gnu")
120 : * End:
121 : */
|