Skip to content

Commit

Permalink
sonic-utilities: WRED stats feature changes on sonic-utilities
Browse files Browse the repository at this point in the history
* New script for wredstat CLI commands
* portstat script updated to accomodate WRED port stats
* counterpoll script updated to support wredport and wredqueue counters
* CLi to script mapping changes
* UT for the new script changes
* CLI command reference document updated

Signed-off-by: rpmarvell <[email protected]>
  • Loading branch information
rpmarvell committed Dec 5, 2023
1 parent 3037959 commit eb034f9
Show file tree
Hide file tree
Showing 14 changed files with 2,451 additions and 20 deletions.
9 changes: 8 additions & 1 deletion clear/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -276,9 +276,16 @@ def clear_pwm_pg_shared():

@cli.group()
def queue():
"""Clear queue WM"""
"""Clear queue"""
pass

@queue.command()
def wredcounters():
"""Clear queue wredcounters"""
command = ['wredstat', '-c']
run_command(command)


@queue.group()
def watermark():
"""Clear queue user WM. One does not simply clear WM, root is required"""
Expand Down
72 changes: 72 additions & 0 deletions counterpoll/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -382,6 +382,72 @@ def disable(ctx):
fc_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "FLOW_CNT_ROUTE", fc_info)

# WRED queue counter commands
@cli.group()
@click.pass_context
def wredqueue(ctx):
""" WRED queue counter commands """
ctx.obj = ConfigDBConnector()
ctx.obj.connect()

@wredqueue.command()
@click.argument('poll_interval', type=click.IntRange(100, 30000))
@click.pass_context
def interval(ctx, poll_interval):
""" Set wred queue counter query interval """
wred_queue_info = {}
wred_queue_info['POLL_INTERVAL'] = poll_interval
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

@wredqueue.command()
@click.pass_context
def enable(ctx):
""" Enable wred queue counter query """
wred_queue_info = {}
wred_queue_info['FLEX_COUNTER_STATUS'] = 'enable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

@wredqueue.command()
@click.pass_context
def disable(ctx):
""" Disable wred queue counter query """
wred_queue_info = {}
wred_queue_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_QUEUE", wred_queue_info)

# WRED port counter commands
@cli.group()
@click.pass_context
def wredport(ctx):
""" WRED port counter commands """
ctx.obj = ConfigDBConnector()
ctx.obj.connect()

@wredport.command()
@click.argument('poll_interval', type=click.IntRange(100, 30000))
@click.pass_context
def interval(ctx, poll_interval):
""" Set wred port counter query interval """
wred_port_info = {}
wred_port_info['POLL_INTERVAL'] = poll_interval
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@wredport.command()
@click.pass_context
def enable(ctx):
""" Enable wred port counter query """
wred_port_info = {}
wred_port_info['FLEX_COUNTER_STATUS'] = 'enable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@wredport.command()
@click.pass_context
def disable(ctx):
""" Disable wred port counter query """
wred_port_info = {}
wred_port_info['FLEX_COUNTER_STATUS'] = 'disable'
ctx.obj.mod_entry("FLEX_COUNTER_TABLE", "WRED_ECN_PORT", wred_port_info)

@cli.command()
def show():
""" Show the counter configuration """
Expand All @@ -399,6 +465,8 @@ def show():
tunnel_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'TUNNEL')
trap_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_TRAP')
route_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'FLOW_CNT_ROUTE')
wred_queue_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'WRED_ECN_QUEUE')
wred_port_info = configdb.get_entry('FLEX_COUNTER_TABLE', 'WRED_ECN_PORT')

header = ("Type", "Interval (in ms)", "Status")
data = []
Expand Down Expand Up @@ -427,6 +495,10 @@ def show():
if route_info:
data.append(["FLOW_CNT_ROUTE_STAT", route_info.get("POLL_INTERVAL", DEFLT_10_SEC),
route_info.get("FLEX_COUNTER_STATUS", DISABLE)])
if wred_queue_info:
data.append(["WRED_ECN_QUEUE_STAT", wred_queue_info.get("POLL_INTERVAL", DEFLT_10_SEC), wred_queue_info.get("FLEX_COUNTER_STATUS", DISABLE)])
if wred_port_info:
data.append(["WRED_ECN_PORT_STAT", wred_port_info.get("POLL_INTERVAL", DEFLT_1_SEC), wred_port_info.get("FLEX_COUNTER_STATUS", DISABLE)])

click.echo(tabulate(data, headers=header, tablefmt="simple", missingval=""))

Expand Down
133 changes: 131 additions & 2 deletions doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -4547,15 +4547,16 @@ The "current-mode" subcommand is used to display current breakout mode for all i

**show interfaces counters**

This show command displays packet counters for all interfaces since the last time the counters were cleared. To display l3 counters "rif" subcommand can be used. There is no facility to display counters for one specific l2 interface. For l3 interfaces a single interface output mode is present. Optional argument "-a" provides two additional columns - RX-PPS and TX_PPS.
Optional argument "-p" specify a period (in seconds) with which to gather counters over.
This show command displays packet counters for all interfaces(except the "show interface detailed" command) since the last time the counters were cleared. To display l3 counters "rif" subcommand can be used. There is no facility to display counters for one specific l2 interface. For l3 interfaces a single interface output mode is present. Optional argument "-a" provides two additional columns - RX-PPS and TX_PPS.
Optional argument "-p" specify a period (in seconds) with which to gather counters over. To display the detailed per-interface counters "detailed <interface-name>" subcommand can be used.

- Usage:
```
show interfaces counters [-a|--printall] [-p|--period <period>]
show interfaces counters errors
show interfaces counters rates
show interfaces counters rif [-p|--period <period>] [-i <interface_name>]
show interfaces counters detailed <interface_name>
```

- Example:
Expand Down Expand Up @@ -4661,6 +4662,56 @@ Optionally, you can specify a period (in seconds) with which to gather counters
Ethernet24 U 173 16.09 KB/s 0.00% 0 0 0 169 11.39 KB/s 0.00% 0 0 0
```

The "detailed" subcommand is used to display more detailed interface counters. Along with tx/rx counters, it also displays the WRED drop counters that are supported on the platform.

- Example:
```
admin@sonic:~$ show interfaces counters detailed Ethernet8
Packets Received 64 Octets..................... 0
Packets Received 65-127 Octets................. 0
Packets Received 128-255 Octets................ 0
Packets Received 256-511 Octets................ 0
Packets Received 512-1023 Octets............... 0
Packets Received 1024-1518 Octets.............. 0
Packets Received 1519-2047 Octets.............. 0
Packets Received 2048-4095 Octets.............. 0
Packets Received 4096-9216 Octets.............. 0
Packets Received 9217-16383 Octets............. 0
Total Packets Received Without Errors.......... 0
Unicast Packets Received....................... 0
Multicast Packets Received..................... 0
Broadcast Packets Received..................... 0
Jabbers Received............................... N/A
Fragments Received............................. N/A
Undersize Received............................. 0
Overruns Received.............................. 0
Packets Transmitted 64 Octets.................. 0
Packets Transmitted 65-127 Octets.............. 0
Packets Transmitted 128-255 Octets............. 0
Packets Transmitted 256-511 Octets............. 0
Packets Transmitted 512-1023 Octets............ 0
Packets Transmitted 1024-1518 Octets........... 0
Packets Transmitted 1519-2047 Octets........... 0
Packets Transmitted 2048-4095 Octets........... 0
Packets Transmitted 4096-9216 Octets........... 0
Packets Transmitted 9217-16383 Octets.......... 0
Total Packets Transmitted Successfully......... 0
Unicast Packets Transmitted.................... 0
Multicast Packets Transmitted.................. 0
Broadcast Packets Transmitted.................. 0
WRED Green Dropped Packets..................... 0
WRED Yellow Dropped Packets.................... 0
WRED Red Dropped Packets....................... 0
WRED Total Dropped Packets..................... 0
Time Since Counters Last Cleared............... None
```

- NOTE: Interface counters can be cleared by the user with the following command:

```
Expand Down Expand Up @@ -8827,6 +8878,7 @@ This sub-section explains the following queue parameters that can be displayed u
2) queue watermark
3) priority-group watermark
4) queue persistent-watermark
5) queue wredcounters
**show queue counters**
Expand Down Expand Up @@ -9020,6 +9072,83 @@ This command displays the user persistet-watermark for the queues (Egress shared
admin@sonic:~$ sonic-clear priority-group drop counters
```
**show queue wredcounters**
This command displays wred-drop packet/byte and ecn-marked packet/byte counters for all queues of all ports or one specific-port given as arguement.
This command can be used to clear the counters for all queues of all ports. Note that port specific clear is not supported.
- Usage:
```
show queue wredcounters [<interface_name>]
```
- Example:
```
admin@sonic:~$ show queue wredcounters
Port TxQ WredDrp/pkts WredDrp/bytes EcnMarked/pkts EcnMarked/bytes
--------- ----- -------------- --------------- --------------- ----------------
Ethernet0 UC0 0 0 0 0
Ethernet0 UC1 0 0 0 0
Ethernet0 UC2 0 0 0 0
Ethernet0 UC3 0 0 0 0
Ethernet0 UC4 0 0 0 0
Ethernet0 UC5 0 0 0 0
Ethernet0 UC6 0 0 0 0
Ethernet0 UC7 0 0 0 0
Ethernet0 UC8 0 0 0 0
Ethernet0 UC9 0 0 0 0
Ethernet0 MC0 0 0 0 0
Ethernet0 MC1 0 0 0 0
Ethernet0 MC2 0 0 0 0
Ethernet0 MC3 0 0 0 0
Ethernet0 MC4 0 0 0 0
Ethernet0 MC5 0 0 0 0
Ethernet0 MC6 0 0 0 0
Ethernet0 MC7 0 0 0 0
Ethernet0 MC8 0 0 0 0
Ethernet0 MC9 0 0 0 0
Port TxQ WredDrp/pkts WredDrp/bytes EcnMarked/pkts EcnMarked/bytes
--------- ----- -------------- --------------- --------------- ----------------
Ethernet4 UC0 0 0 0 0
Ethernet4 UC1 0 0 0 0
Ethernet4 UC2 0 0 0 0
Ethernet4 UC3 0 0 0 0
Ethernet4 UC4 0 0 0 0
Ethernet4 UC5 0 0 0 0
Ethernet4 UC6 0 0 0 0
Ethernet4 UC7 0 0 0 0
Ethernet4 UC8 0 0 0 0
Ethernet4 UC9 0 0 0 0
Ethernet4 MC0 0 0 0 0
Ethernet4 MC1 0 0 0 0
Ethernet4 MC2 0 0 0 0
Ethernet4 MC3 0 0 0 0
Ethernet4 MC4 0 0 0 0
Ethernet4 MC5 0 0 0 0
Ethernet4 MC6 0 0 0 0
Ethernet4 MC7 0 0 0 0
Ethernet4 MC8 0 0 0 0
Ethernet4 MC9 0 0 0 0
...
```
Optionally, you can specify an interface name in order to display only that particular interface
- Example:
```
admin@sonic:~$ show queue wredcounters Ethernet72
```
- NOTE: Queue counters can be cleared by the user with the following command:
```
admin@sonic:~$ sonic-clear queue wredcounters
```
#### Buffer Pool
This sub-section explains the following buffer pool parameters that can be displayed using "show buffer_pool" command.
Expand Down
65 changes: 62 additions & 3 deletions scripts/portstat
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,8 @@ NStats = namedtuple("NStats", "rx_ok, rx_err, rx_drop, rx_ovr, tx_ok,\
tx_64, tx_65_127, tx_128_255, tx_256_511, tx_512_1023, tx_1024_1518, tx_1519_2047, tx_2048_4095, tx_4096_9216, tx_9217_16383,\
tx_uca, tx_mca, tx_bca, tx_all,\
rx_jbr, rx_frag, rx_usize, rx_ovrrun,\
fec_corr, fec_uncorr, fec_symbol_err")
fec_corr, fec_uncorr, fec_symbol_err,\
wred_grn_drp_pkt, wred_ylw_drp_pkt, wred_red_drp_pkt, wred_tot_drp_pkt")
header_all = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_PPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR',
'TX_OK', 'TX_BPS', 'TX_PPS', 'TX_UTIL', 'TX_ERR', 'TX_DRP', 'TX_OVR']
header_std = ['IFACE', 'STATE', 'RX_OK', 'RX_BPS', 'RX_UTIL', 'RX_ERR', 'RX_DRP', 'RX_OVR',
Expand All @@ -70,7 +71,14 @@ RateStats = namedtuple("RateStats", ratestat_fields)
The order and count of statistics mentioned below needs to be in sync with the values in portstat script
So, any fields added/deleted in here should be reflected in portstat script also
"""
BUCKET_NUM = 45
BUCKET_NUM = 49

wred_green_pkt_stat_capable = "false"
wred_yellow_pkt_stat_capable = "false"
wred_red_pkt_stat_capable = "false"
wred_total_pkt_stat_capable = "false"
is_wred_stats_reqd = True

counter_bucket_dict = {
0:['SAI_PORT_STAT_IF_IN_UCAST_PKTS', 'SAI_PORT_STAT_IF_IN_NON_UCAST_PKTS'],
1:['SAI_PORT_STAT_IF_IN_ERRORS'],
Expand Down Expand Up @@ -116,7 +124,11 @@ counter_bucket_dict = {
41:['SAI_PORT_STAT_IP_IN_RECEIVES'],
42:['SAI_PORT_STAT_IF_IN_FEC_CORRECTABLE_FRAMES'],
43:['SAI_PORT_STAT_IF_IN_FEC_NOT_CORRECTABLE_FRAMES'],
44:['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS']
44:['SAI_PORT_STAT_IF_IN_FEC_SYMBOL_ERRORS'],
45:['SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS'],
46:['SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS'],
47:['SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS'],
48:['SAI_PORT_STAT_WRED_DROPPED_PACKETS']
}

STATUS_NA = 'N/A'
Expand Down Expand Up @@ -157,6 +169,32 @@ class Portstat(object):
Collect the statisitics from all the asics present on the
device and store in a dict
"""
global BUCKET_NUM

global wred_green_pkt_stat_capable
global wred_yellow_pkt_stat_capable
global wred_red_pkt_stat_capable
global wred_total_pkt_stat_capable
global is_wred_stats_reqd

wred_green_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_GREEN_DROP_COUNTER","isSupported")
wred_yellow_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_YELLOW_DROP_COUNTER","isSupported")
wred_red_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_RED_DROP_COUNTER","isSupported")
wred_total_pkt_stat_capable = self.db.get(self.db.STATE_DB, "PORT_COUNTER_CAPABILITIES|WRED_ECN_PORT_WRED_TOTAL_DROP_COUNTER","isSupported")

# Remove the unsupported stats from the counter dict
if ((is_wred_stats_reqd == False) or (wred_green_pkt_stat_capable != "true")) and ('SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_GREEN_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if ((is_wred_stats_reqd == False) or (wred_yellow_pkt_stat_capable != "true")) and ('SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_YELLOW_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if ((is_wred_stats_reqd == False) or (wred_red_pkt_stat_capable != "true")) and ('SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_RED_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)
if ((is_wred_stats_reqd == False) or (wred_total_pkt_stat_capable != "true")) and ('SAI_PORT_STAT_WRED_DROPPED_PACKETS' in counter_bucket_dict.keys()):
del counter_bucket_dict['SAI_PORT_STAT_WRED_DROPPED_PACKETS']
BUCKET_NUM = (BUCKET_NUM - 1)

cnstat_dict, ratestat_dict = self.get_cnstat()
self.cnstat_dict.update(cnstat_dict)
Expand All @@ -170,6 +208,8 @@ class Portstat(object):
"""
Get the counters from specific table.
"""


fields = ["0"]*BUCKET_NUM

_, fvs = counter_table.get(PortCounter(), port)
Expand Down Expand Up @@ -399,9 +439,22 @@ class Portstat(object):
print("Multicast Packets Transmitted.................. {}".format(ns_diff(cntr['tx_mca'], old_cntr['tx_mca'])))
print("Broadcast Packets Transmitted.................. {}".format(ns_diff(cntr['tx_bca'], old_cntr['tx_bca'])))

if wred_green_pkt_stat_capable == "true" or wred_yellow_pkt_stat_capable == "true" or wred_red_pkt_stat_capable == "true" or wred_total_pkt_stat_capable == "true":
print("")
if wred_green_pkt_stat_capable == "true":
print("WRED Green Dropped Packets..................... {}".format(ns_diff(cntr.wred_grn_drp_pkt, old_cntr.wred_grn_drp_pkt)))
if wred_yellow_pkt_stat_capable == "true":
print("WRED Yellow Dropped Packets.................... {}".format(ns_diff(cntr.wred_ylw_drp_pkt, old_cntr.wred_ylw_drp_pkt)))
if wred_red_pkt_stat_capable == "true":
print("WRED Red Dropped Packets....................... {}".format(ns_diff(cntr.wred_red_drp_pkt, old_cntr.wred_red_drp_pkt)))
if wred_total_pkt_stat_capable == "true":
print("WRED Total Dropped Packets..................... {}".format(ns_diff(cntr.wred_tot_drp_pkt, old_cntr.wred_tot_drp_pkt)))
print("")

print("Time Since Counters Last Cleared............... " + str(cnstat_old_dict.get('time')))



def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict,
ratestat_dict, intf_list, use_json,
print_all, errors_only, fec_stats_only,
Expand Down Expand Up @@ -631,6 +684,12 @@ Examples:
namespace = None
display_option = constants.DISPLAY_ALL

global is_wred_stats_reqd

if errors_only or rates_only or fec_stats_only:
is_wred_stats_reqd = False


portstat = Portstat(namespace, display_option)
cnstat_dict, ratestat_dict = portstat.get_cnstat_dict()

Expand Down
Loading

0 comments on commit eb034f9

Please sign in to comment.