Skip to content

Commit

Permalink
Add_intf_range (sonic-net#913)
Browse files Browse the repository at this point in the history
* Add_intf_range
  • Loading branch information
stevenlu99 authored Jun 6, 2020
1 parent f7b7fcb commit d2c997c
Show file tree
Hide file tree
Showing 6 changed files with 137 additions and 38 deletions.
57 changes: 34 additions & 23 deletions config/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
import ipaddress
from swsssdk import ConfigDBConnector, SonicV2Connector, SonicDBConfig
from minigraph import parse_device_desc_xml
from utilities_common.intf_filter import parse_interface_in_filter

import aaa
import mlnx
Expand Down Expand Up @@ -1843,21 +1844,26 @@ def startup(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

if interface_name_is_valid(interface_name) is False:
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")
intf_fs = parse_interface_in_filter(interface_name)
if len(intf_fs) == 1 and interface_name_is_valid(interface_name) is False:
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")

log_info("'interface startup {}' executing...".format(interface_name))
port_dict = config_db.get_table('PORT')
for port_name in port_dict.keys():
if port_name in intf_fs:
config_db.mod_entry("PORT", port_name, {"admin_status": "up"})

portchannel_list = config_db.get_table("PORTCHANNEL")
for po_name in portchannel_list.keys():
if po_name in intf_fs:
config_db.mod_entry("PORTCHANNEL", po_name, {"admin_status": "up"})

subport_list = config_db.get_table("VLAN_SUB_INTERFACE")
for sp_name in subport_list.keys():
if sp_name in intf_fs:
config_db.mod_entry("VLAN_SUB_INTERFACE", sp_name, {"admin_status": "up"})

if interface_name.startswith("Ethernet"):
if VLAN_SUB_INTERFACE_SEPARATOR in interface_name:
config_db.mod_entry("VLAN_SUB_INTERFACE", interface_name, {"admin_status": "up"})
else:
config_db.mod_entry("PORT", interface_name, {"admin_status": "up"})
elif interface_name.startswith("PortChannel"):
if VLAN_SUB_INTERFACE_SEPARATOR in interface_name:
config_db.mod_entry("VLAN_SUB_INTERFACE", interface_name, {"admin_status": "up"})
else:
config_db.mod_entry("PORTCHANNEL", interface_name, {"admin_status": "up"})
#
# 'shutdown' subcommand
#
Expand All @@ -1874,19 +1880,24 @@ def shutdown(ctx, interface_name):
if interface_name is None:
ctx.fail("'interface_name' is None!")

if interface_name_is_valid(interface_name) is False:
intf_fs = parse_interface_in_filter(interface_name)
if len(intf_fs) == 1 and interface_name_is_valid(interface_name) is False:
ctx.fail("Interface name is invalid. Please enter a valid interface name!!")

if interface_name.startswith("Ethernet"):
if VLAN_SUB_INTERFACE_SEPARATOR in interface_name:
config_db.mod_entry("VLAN_SUB_INTERFACE", interface_name, {"admin_status": "down"})
else:
config_db.mod_entry("PORT", interface_name, {"admin_status": "down"})
elif interface_name.startswith("PortChannel"):
if VLAN_SUB_INTERFACE_SEPARATOR in interface_name:
config_db.mod_entry("VLAN_SUB_INTERFACE", interface_name, {"admin_status": "down"})
else:
config_db.mod_entry("PORTCHANNEL", interface_name, {"admin_status": "down"})
port_dict = config_db.get_table('PORT')
for port_name in port_dict.keys():
if port_name in intf_fs:
config_db.mod_entry("PORT", port_name, {"admin_status": "down"})

portchannel_list = config_db.get_table("PORTCHANNEL")
for po_name in portchannel_list.keys():
if po_name in intf_fs:
config_db.mod_entry("PORTCHANNEL", po_name, {"admin_status": "down"})

subport_list = config_db.get_table("VLAN_SUB_INTERFACE")
for sp_name in subport_list.keys():
if sp_name in intf_fs:
config_db.mod_entry("VLAN_SUB_INTERFACE", sp_name, {"admin_status": "down"})

#
# 'speed' subcommand
Expand Down
31 changes: 30 additions & 1 deletion doc/Command-Reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -2312,7 +2312,7 @@ Optional argument "-p" specify a period (in seconds) with which to gather counte
show interfaces counters [-a|--printall] [-p|--period <period>]
show interfaces counters errors
show interfaces counters rates
show interfaces counters rif [-p|--period <period>] <interface_name>
show interfaces counters rif [-p|--period <period>] [-i <interface_name>]
```
- Example:
Expand All @@ -2327,6 +2327,13 @@ Optional argument "-p" specify a period (in seconds) with which to gather counte
Ethernet16 U 16,679,692,972 13.83 MB/s 0.27% 0 17,605 0 18,206,586,265 17.51 MB/s 0.34% 0 0 0
Ethernet20 U 47,983,339,172 35.89 MB/s 0.70% 0 2,174 0 58,986,354,359 51.83 MB/s 1.01% 0 0 0
Ethernet24 U 33,543,533,441 36.59 MB/s 0.71% 0 1,613 0 43,066,076,370 49.92 MB/s 0.97% 0 0 0

admin@sonic:~$ show interfaces counters -i Ethernet4,Ethernet12-16
IFACE STATE RX_OK RX_BPS RX_UTIL RX_ERR RX_DRP RX_OVR TX_OK TX_BPS TX_UTIL TX_ERR TX_DRP TX_OVR
----------- ------- --------------- ----------- --------- -------- -------- -------- --------------- ----------- --------- -------- -------- --------
Ethernet4 U 453,838,006,636 632.97 MB/s 12.36% 0 1,636 0 388,299,875,056 529.34 MB/s 10.34% 0 0 0
Ethernet12 U 458,052,204,029 636.84 MB/s 12.44% 0 17,614 0 388,341,776,615 527.37 MB/s 10.30% 0 0 0
Ethernet16 U 16,679,692,972 13.83 MB/s 0.27% 0 17,605 0 18,206,586,265 17.51 MB/s 0.34% 0 0 0
```
The "errors" subcommand is used to display the interface errors.
Expand Down Expand Up @@ -2527,6 +2534,18 @@ This command displays some more fields such as Lanes, Speed, MTU, Type, Asymmetr
Ethernet0 101,102 40G 9100 fortyGigE1/1/1 up up
```
- Example (to only display the status for range of interfaces):
```
admin@sonic:~$ show interfaces status Ethernet8,Ethernet168-180
Interface Lanes Speed MTU Alias Oper Admin Type Asym PFC
----------- ----------------- ------- ----- --------------- ------ ------- ------ ----------
Ethernet8 49,50,51,52 100G 9100 hundredGigE3 down down N/A N/A
Ethernet168 9,10,11,12 100G 9100 hundredGigE43 down down N/A N/A
Ethernet172 13,14,15,16 100G 9100 hundredGigE44 down down N/A N/A
Ethernet176 109,110,111,112 100G 9100 hundredGigE45 down down N/A N/A
Ethernet180 105,106,107,108 100G 9100 hundredGigE46 down down N/A N/A
```
**show interfaces transceiver**
This command is already explained [here](#Transceivers)
Expand Down Expand Up @@ -2720,6 +2739,11 @@ This command is used to administratively shut down either the Physical interface
admin@sonic:~$ sudo config interface Ethernet63 shutdown
```
shutdown multiple interfaces
```
admin@sonic:~$ sudo config interface shutdown Ethernet8,Ethernet16-20,Ethernet32
```
**config interface startup <interface_name> (Versions >= 201904)**
**config interface <interface_name> startup (Versions <= 201811)**
Expand Down Expand Up @@ -2748,6 +2772,11 @@ This command is used for administratively bringing up the Physical interface or
admin@sonic:~$ sudo config interface Ethernet63 startup
```
startup multiple interfaces
```
admin@sonic:~$ sudo config interface startup Ethernet8,Ethernet16-20,Ethernet32
```
**config interface speed <interface_name> (Versions >= 201904)**
**config interface <interface_name> speed (Versions <= 201811)**
Expand Down
16 changes: 11 additions & 5 deletions scripts/intfutil
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ from tabulate import tabulate
from natsort import natsorted
from swsssdk import ConfigDBConnector
from pprint import pprint
from utilities_common.intf_filter import parse_interface_in_filter

import os

# mock the redis for unit test purposes #
Expand Down Expand Up @@ -345,7 +347,7 @@ header_stat_sub_intf = ['Sub port interface', 'Speed', 'MTU', 'Vlan', 'Admin', '

class IntfStatus(object):

def display_intf_status(self, appl_db_keys, front_panel_ports_list, portchannel_speed_dict, appl_db_sub_intf_keys, sub_intf_list, sub_intf_only):
def display_intf_status(self, intf_name, appl_db_keys, front_panel_ports_list, portchannel_speed_dict, appl_db_sub_intf_keys, sub_intf_list, sub_intf_only):
"""
Generate interface-status output
"""
Expand All @@ -354,6 +356,8 @@ class IntfStatus(object):
table = []
key = []

intf_fs = parse_interface_in_filter(intf_name)

#
# Iterate through all the keys and append port's associated state to
# the result table.
Expand All @@ -362,7 +366,8 @@ class IntfStatus(object):
for i in appl_db_keys:
key = re.split(':', i, maxsplit=1)[-1].strip()
if key in front_panel_ports_list:
table.append((key,
if intf_name is None or key in intf_fs:
table.append((key,
appl_db_port_status_get(self.appl_db, key, PORT_LANES_STATUS),
appl_db_port_status_get(self.appl_db, key, PORT_SPEED),
appl_db_port_status_get(self.appl_db, key, PORT_MTU_STATUS),
Expand All @@ -376,7 +381,8 @@ class IntfStatus(object):

for po, value in portchannel_speed_dict.iteritems():
if po:
table.append((po,
if intf_name is None or po in intf_fs:
table.append((po,
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_LANES_STATUS, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_SPEED, self.portchannel_speed_dict),
appl_db_portchannel_status_get(self.appl_db, self.config_db, po, PORT_MTU_STATUS, self.portchannel_speed_dict),
Expand Down Expand Up @@ -434,7 +440,7 @@ class IntfStatus(object):
intf_name = intf_name[:sub_intf_sep_idx]

self.front_panel_ports_list = get_frontpanel_port_list(self.config_db)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, intf_name)
appl_db_keys = appl_db_keys_get(self.appl_db, self.front_panel_ports_list, None)
self.int_to_vlan_dict = get_interface_vlan_dict(self.config_db)
self.get_raw_po_int_configdb_info = get_raw_portchannel_info(self.config_db)
self.portchannel_list = get_portchannel_list(self.get_raw_po_int_configdb_info)
Expand All @@ -449,7 +455,7 @@ class IntfStatus(object):
appl_db_sub_intf_keys = appl_db_sub_intf_keys_get(self.appl_db, self.sub_intf_list, sub_intf_name)
if appl_db_keys is None:
return
self.display_intf_status(appl_db_keys, self.front_panel_ports_list, self.portchannel_speed_dict, appl_db_sub_intf_keys, self.sub_intf_list, sub_intf_only)
self.display_intf_status(intf_name, appl_db_keys, self.front_panel_ports_list, self.portchannel_speed_dict, appl_db_sub_intf_keys, self.sub_intf_list, sub_intf_only)



Expand Down
23 changes: 15 additions & 8 deletions scripts/portstat
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ from collections import namedtuple, OrderedDict
from natsort import natsorted
from tabulate import tabulate
from utilities_common.netstat import ns_diff, ns_brate, ns_prate, ns_util, table_as_json
from utilities_common.intf_filter import parse_interface_in_filter

PORT_RATE = 40

Expand Down Expand Up @@ -128,7 +129,7 @@ class Portstat(object):
else:
return STATUS_NA

def cnstat_print(self, cnstat_dict, use_json, print_all, errors_only, rates_only):
def cnstat_print(self, cnstat_dict, intf_list, use_json, print_all, errors_only, rates_only):
"""
Print the cnstat.
"""
Expand All @@ -138,7 +139,8 @@ class Portstat(object):
for key, data in cnstat_dict.iteritems():
if key == 'time':
continue

if intf_list and key not in intf_list:
continue
if print_all:
header = header_all
table.append((key, self.get_port_state(key),
Expand Down Expand Up @@ -169,7 +171,7 @@ class Portstat(object):
else:
print tabulate(table, header, tablefmt='simple', stralign='right')

def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict, use_json, print_all, errors_only, rates_only):
def cnstat_diff_print(self, cnstat_new_dict, cnstat_old_dict, intf_list, use_json, print_all, errors_only, rates_only):
"""
Print the difference between two cnstat results.
"""
Expand All @@ -186,6 +188,8 @@ class Portstat(object):
if key in cnstat_old_dict:
old_cntr = cnstat_old_dict.get(key)

if intf_list and key not in intf_list:
continue
port_speed = self.get_port_speed(key)
if print_all:
header = header_all
Expand Down Expand Up @@ -306,6 +310,7 @@ Examples:
parser.add_argument('-R', '--rate', action='store_true', help='Display interface rates')
parser.add_argument('-t', '--tag', type=str, help='Save stats with name TAG', default=None)
parser.add_argument('-p', '--period', type=int, help='Display stats over a specified period (in seconds).', default=0)
parser.add_argument('-i', '--interface', type=str, help='Display stats for interface lists.', default=None)
args = parser.parse_args()

save_fresh_stats = args.clear
Expand All @@ -319,7 +324,7 @@ Examples:
uid = str(os.getuid())
wait_time_in_seconds = args.period
print_all = args.all

intf_fs = args.interface
if tag_name is not None:
cnstat_file = uid + "-" + tag_name
else:
Expand Down Expand Up @@ -351,13 +356,15 @@ Examples:
os.rmdir(cnstat_dir)
sys.exit(0)

intf_list = parse_interface_in_filter(intf_fs)

portstat = Portstat()
# The cnstat_dict just give an ordered dict of all output.
cnstat_dict = portstat.get_cnstat()

# Now decide what information to display
if raw_stats:
portstat.cnstat_print(cnstat_dict, use_json, print_all, errors_only, rates_only)
portstat.cnstat_print(cnstat_dict, intf_list, use_json, print_all, errors_only, rates_only)
sys.exit(0)

# At this point, either we'll create a file or open an existing one.
Expand All @@ -384,21 +391,21 @@ Examples:
try:
cnstat_cached_dict = pickle.load(open(cnstat_fqn_file, 'r'))
print "Last cached time was " + str(cnstat_cached_dict.get('time'))
portstat.cnstat_diff_print(cnstat_dict, cnstat_cached_dict, use_json, print_all, errors_only, rates_only)
portstat.cnstat_diff_print(cnstat_dict, cnstat_cached_dict, intf_list, use_json, print_all, errors_only, rates_only)
except IOError as e:
print e.errno, e
else:
if tag_name:
print "\nFile '%s' does not exist" % cnstat_fqn_file
print "Did you run 'portstat -c -t %s' to record the counters via tag %s?\n" % (tag_name, tag_name)
else:
portstat.cnstat_print(cnstat_dict, use_json, print_all, errors_only, rates_only)
portstat.cnstat_print(cnstat_dict, intf_list, use_json, print_all, errors_only, rates_only)
else:
#wait for the specified time and then gather the new stats and output the difference.
time.sleep(wait_time_in_seconds)
print "The rates are calculated within %s seconds period" % wait_time_in_seconds
cnstat_new_dict = portstat.get_cnstat()
portstat.cnstat_diff_print(cnstat_new_dict, cnstat_dict, use_json, print_all, errors_only, rates_only)
portstat.cnstat_diff_print(cnstat_new_dict, cnstat_dict, intf_list, use_json, print_all, errors_only, rates_only)

if __name__ == "__main__":
main()
5 changes: 4 additions & 1 deletion show/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -947,9 +947,10 @@ def status(interfacename, verbose):
@interfaces.group(invoke_without_command=True)
@click.option('-a', '--printall', is_flag=True)
@click.option('-p', '--period')
@click.option('-i', '--interface')
@click.option('--verbose', is_flag=True, help="Enable verbose output")
@click.pass_context
def counters(ctx, verbose, period, printall):
def counters(ctx, verbose, period, interface, printall):
"""Show interface counters"""

if ctx.invoked_subcommand is None:
Expand All @@ -959,6 +960,8 @@ def counters(ctx, verbose, period, printall):
cmd += " -a"
if period is not None:
cmd += " -p {}".format(period)
if interface is not None:
cmd += " -i {}".format(interface)

run_command(cmd, display_cmd=verbose)

Expand Down
43 changes: 43 additions & 0 deletions utilities_common/intf_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Interface filtering functions

SONIC_PORT_NAME_PREFIX = "Ethernet"
SONIC_LAG_NAME_PREFIX = "PortChannel"

def parse_interface_in_filter(intf_filter):
intf_fs = []

if intf_filter is None:
return intf_fs

fs = intf_filter.split(',')
for x in fs:
if '-' in x:
# handle range
if not x.startswith(SONIC_PORT_NAME_PREFIX) and not x.startswith(SONIC_LAG_NAME_PREFIX):
continue
if x.startswith(SONIC_PORT_NAME_PREFIX):
intf = SONIC_PORT_NAME_PREFIX
if x.startswith(SONIC_LAG_NAME_PREFIX):
intf = SONIC_LAG_NAME_PREFIX
start = x.split('-')[0].split(intf,1)[1]
end = x.split('-')[1]

if not start.isdigit() or not end.isdigit():
continue
for i in range(int(start), int(end)+1):
intf_fs.append(intf+str(i))
else:
intf_fs.append(x)

return intf_fs

def interface_in_filter(intf, filter):
if filter is None:
return True

intf_fs = parse_interface_in_filter(filter)
if intf in intf_fs:
return True

return False

0 comments on commit d2c997c

Please sign in to comment.