diff --git a/doc/Command-Reference.md b/doc/Command-Reference.md index 294695a72d..61955eab36 100644 --- a/doc/Command-Reference.md +++ b/doc/Command-Reference.md @@ -8920,90 +8920,122 @@ This command displays the MAC (FDB) entries either in full or partial as given b 1) show mac - displays the full table 2) show mac -v - displays the MACs learnt on the particular VLAN ID. 3) show mac -p - displays the MACs learnt on the particular port. +4) show mac -a - display the MACs that match a specific mac-address +5) show mac -t - display the MACs that match a specific type (static/dynamic) +6) show mac -c - display the count of MAC addresses +To show the default MAC address aging time on the switch. - Usage: ``` - show mac [-v ] [-p ] + show mac [-v ] [-p ] [-a ] [-t ] [-c] ``` - Example: ``` admin@sonic:~$ show mac - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` -Optionally, you can specify a VLAN ID or interface name in order to display only that particular entries +Optionally, you can specify a VLAN ID or interface name or type or mac-address in order to display only that particular entries - Examples: ``` admin@sonic:~$ show mac -v 1000 - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` ``` admin@sonic:~$ show mac -p Ethernet192 - No. Vlan MacAddress Port - ----- ------ ----------------- ----------- - 1 1000 E2:8C:56:85:4A:CD Ethernet192 - 2 1000 A0:1B:5E:47:C9:76 Ethernet192 - 3 1000 AA:54:EF:2C:EE:30 Ethernet192 - 4 1000 A4:3F:F2:17:A3:FC Ethernet192 - 5 1000 0C:FC:01:72:29:91 Ethernet192 - 6 1000 48:6D:01:7E:C9:FD Ethernet192 - 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 - 8 1000 EE:81:D9:7B:93:A9 Ethernet192 - 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 - 10 1000 0A:52:B3:9C:FB:6C Ethernet192 - 11 1000 C6:E2:72:02:D1:23 Ethernet192 - 12 1000 8A:C9:5C:25:E9:28 Ethernet192 - 13 1000 5E:CD:34:E4:94:18 Ethernet192 - 14 1000 7E:49:1F:B5:91:B5 Ethernet192 - 15 1000 AE:DD:67:F3:09:5A Ethernet192 - 16 1000 DC:2F:D1:08:4B:DE Ethernet192 - 17 1000 50:96:23:AD:F1:65 Ethernet192 - 18 1000 C6:C9:5E:AE:24:42 Ethernet192 + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + 2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic + 3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic + 4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic + 5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic + 6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic + 7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic + 8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic + 9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic + 10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic + 11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic + 12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic + 13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic + 14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic + 15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic + 16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic + 17 1000 50:96:23:AD:F1:65 Ethernet192 Static + 18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static Total number of entries 18 ``` + ``` + admin@sonic:~$ show mac -a E2:8C:56:85:4A:CD + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic + Total number of entries 1 + ``` + ``` + admin@sonic:~$ show mac -t Static + No. Vlan MacAddress Port Type + ----- ------ ----------------- ----------- ------- + 2 1000 50:96:23:AD:F1:65 Ethernet192 Static + 2 1000 C6:C9:5E:AE:24:42 Ethernet192 Static + Total number of entries 2 + ``` + ``` + admin@sonic:~$ show mac -c + Total number of entries 18 + ``` + +**show mac aging-time** + +This command displays the default mac aging time on the switch + + ``` + admin@sonic:~$ show mac aging-time + Aging time for switch is 600 seconds + ``` **sonic-clear fdb all** diff --git a/scripts/fdbshow b/scripts/fdbshow index 80fd908de6..cbf8b40394 100755 --- a/scripts/fdbshow +++ b/scripts/fdbshow @@ -30,6 +30,7 @@ import argparse import json import sys import os +import re # mock the redis for unit test purposes # try: # pragma: no cover @@ -43,7 +44,9 @@ try: # pragma: no cover "2": 'asic_db_def_vlan', "3": 'asic_db_no_fdb', "4": 'asic_db_no_bridge', - "5": 'asic_db_fetch_except'} + "5": 'asic_db_fetch_except', + "6": 'asic_db_no_static', + "7": 'asic_db_mac_case'} mock_db_path = os.path.join(test_path, "fdbshow_input") file_name = mock_variants[os.environ["FDBSHOW_MOCK"]] jsonfile_asic = os.path.join(mock_db_path, file_name) @@ -53,7 +56,6 @@ try: # pragma: no cover except KeyError: # pragma: no cover pass -from natsort import natsorted from swsssdk import port_util from swsscommon.swsscommon import SonicV2Connector from tabulate import tabulate @@ -61,7 +63,6 @@ from tabulate import tabulate class FdbShow(object): HEADER = ['No.', 'Vlan', 'MacAddress', 'Port', 'Type'] - FDB_COUNT = 0 def __init__(self): super(FdbShow,self).__init__() @@ -135,18 +136,7 @@ class FdbShow(object): return - def get_iter_index(self, key_value, pos=0): - """ - Get the starting index of matched entry - """ - if pos != 0: - self.bridge_mac_list = natsorted(self.bridge_mac_list, key = lambda x: x[pos]) - - keys = [r[pos] for r in self.bridge_mac_list] - return keys.index(key_value) - - - def display(self, vlan, port): + def display(self, vlan, port, address, entry_type, count): """ Display the FDB entries for specified vlan/port. @todo: - PortChannel support @@ -154,22 +144,55 @@ class FdbShow(object): output = [] if vlan is not None: - vlan = int(vlan) - s_index = self.get_iter_index(vlan) - self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:] - if fdb[0] == vlan] - if port is not None: - s_index = self.get_iter_index(port, 2) - self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:] - if fdb[2] == port] + vlan_val = int(vlan) + + if address is not None: + address = address.upper() - for fdb in self.bridge_mac_list: - self.FDB_COUNT += 1 - output.append([self.FDB_COUNT, fdb[0], fdb[1], fdb[2], fdb[3]]) + if entry_type is not None: + entry_type = entry_type.capitalize() - print(tabulate(output, self.HEADER)) - print("Total number of entries {0}".format(self.FDB_COUNT)) + self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list + if (vlan is None or fdb[0] == vlan_val) and + (port is None or fdb[2] == port) and + (address is None or fdb[1] == address) and + (entry_type is None or fdb[3] == entry_type)] + if not count: + fdb_index = 1 + for fdb in self.bridge_mac_list: + output.append([fdb_index, fdb[0], fdb[1], fdb[2], fdb[3]]) + fdb_index += 1 + print(tabulate(output, self.HEADER)) + + print("Total number of entries {0}".format(len(self.bridge_mac_list))) + + def validate_params(self, vlan, port, address, entry_type): + if vlan is not None: + if not vlan.isnumeric(): + print("Error: Invalid vlan id {0}".format(vlan)) + return False + + vlan_val = int(vlan) + if (vlan_val not in range(1,4096)): + print("Error: Invalid vlan id {0}".format(vlan)) + return False + + if port is not None and port not in self.if_name_map: + print("Error: Invalid port {0}".format(port)) + return False + + if address is not None: + mac_addr_pattern ="^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$" + if not re.match(mac_addr_pattern, address): + print("Error: Invalid mac address {0}".format(address)) + return False + + if entry_type is not None and entry_type.capitalize() not in ["Static", "Dynamic"]: + print("Error: Invalid type {0}". format(entry_type)) + return False + + return True def main(): @@ -177,11 +200,17 @@ def main(): formatter_class=argparse.RawTextHelpFormatter) parser.add_argument('-p', '--port', type=str, help='FDB learned on specific port: Ethernet0', default=None) parser.add_argument('-v', '--vlan', type=str, help='FDB learned on specific Vlan: 1001', default=None) + parser.add_argument('-a', '--address', type=str, help='FDB display based on specific mac address', default=None) + parser.add_argument('-t', '--type', type=str, help='FDB display of specific type of mac address', default=None) + parser.add_argument('-c', '--count', action='store_true', help='FDB display count of mac address') args = parser.parse_args() try: fdb = FdbShow() - fdb.display(args.vlan, args.port) + if not fdb.validate_params(args.vlan, args.port, args.address, args.type): + sys.exit(1) + + fdb.display(args.vlan, args.port, args.address, args.type, args.count) except Exception as e: print(str(e)) sys.exit(1) diff --git a/show/main.py b/show/main.py index d016b6fbc2..528ad81e84 100755 --- a/show/main.py +++ b/show/main.py @@ -722,13 +722,20 @@ def pwm_headroom_pool(): # 'mac' command ("show mac ...") # -@cli.command() +@cli.group(cls=clicommon.AliasedGroup, invoke_without_command="true") +@click.pass_context @click.option('-v', '--vlan') @click.option('-p', '--port') +@click.option('-a', '--address') +@click.option('-t', '--type') +@click.option('-c', '--count', is_flag=True) @click.option('--verbose', is_flag=True, help="Enable verbose output") -def mac(vlan, port, verbose): +def mac(ctx, vlan, port, address, type, count, verbose): """Show MAC (FDB) entries""" + if ctx.invoked_subcommand is not None: + return + cmd = "fdbshow" if vlan is not None: @@ -737,8 +744,35 @@ def mac(vlan, port, verbose): if port is not None: cmd += " -p {}".format(port) + if address is not None: + cmd += " -a {}".format(address) + + if type is not None: + cmd += " -t {}".format(type) + + if count: + cmd += " -c" + run_command(cmd, display_cmd=verbose) +@mac.command('aging-time') +@click.pass_context +def aging_time(ctx): + app_db = SonicV2Connector() + app_db.connect(app_db.APPL_DB) + table = "SWITCH_TABLE*" + keys = app_db.keys(app_db.APPL_DB, table) + + if not keys: + click.echo("Aging time not configured for the switch") + return + + for key in keys: + fdb_aging_time = app_db.get(app_db.APPL_DB, key, 'fdb_aging_time') + if fdb_aging_time is not None: + click.echo("Aging time for {} is {} seconds".format(key.split(':')[-1], fdb_aging_time)) + else: + click.echo("Aging time not configured for the {}".format(key.split(':')[-1])) # # 'show route-map' command ("show route-map") # diff --git a/tests/fdbshow_input/appl_db.json b/tests/fdbshow_input/appl_db.json new file mode 100644 index 0000000000..d2e077a975 --- /dev/null +++ b/tests/fdbshow_input/appl_db.json @@ -0,0 +1,5 @@ +{ + "SWITCH_TABLE:switch": { + "fdb_aging_time" : "600" + } +} diff --git a/tests/fdbshow_input/appl_db_no_age.json b/tests/fdbshow_input/appl_db_no_age.json new file mode 100644 index 0000000000..2465b3a4d9 --- /dev/null +++ b/tests/fdbshow_input/appl_db_no_age.json @@ -0,0 +1,5 @@ +{ + "SWITCH_TABLE:switch": { + "ecmp_hash_seed" : "600" + } +} diff --git a/tests/fdbshow_input/asic_db_mac_case.json b/tests/fdbshow_input/asic_db_mac_case.json new file mode 100644 index 0000000000..944de57621 --- /dev/null +++ b/tests/fdbshow_input/asic_db_mac_case.json @@ -0,0 +1,20 @@ +{ + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000005cb": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000528", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000005c5\",\"mac\":\"34:5F:78:9A:BC:DE\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000005c5": { + "SAI_VLAN_ATTR_VLAN_ID": "2" + } +} diff --git a/tests/fdbshow_input/asic_db_no_static.json b/tests/fdbshow_input/asic_db_no_static.json new file mode 100644 index 0000000000..528a9ec479 --- /dev/null +++ b/tests/fdbshow_input/asic_db_no_static.json @@ -0,0 +1,65 @@ +{ + "ASIC_STATE:SAI_OBJECT_TYPE_SWITCH:oid:0x21000000000000": { + "SAI_SWITCH_ATTR_INIT_SWITCH": "true", + "SAI_SWITCH_ATTR_SRC_MAC_ADDRESS": "DE:AD:BE:EF:CA:FE" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000005cb": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000528", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000006cd": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000549", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT:oid:0x3a0000000007ef": { + "SAI_BRIDGE_PORT_ATTR_TYPE": "SAI_BRIDGE_PORT_TYPE_PORT", + "SAI_BRIDGE_PORT_ATTR_PORT_ID": "oid:0x1000000000fff", + "SAI_BRIDGE_PORT_ATTR_ADMIN_STATE": "true", + "SAI_BRIDGE_PORT_ATTR_FDB_LEARNING_MODE": "SAI_BRIDGE_PORT_FDB_LEARNING_MODE_HW" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000005c5\",\"mac\":\"11:22:33:44:55:66\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"66:55:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005cb", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000005ff", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"77:55:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a000000000fff", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"bvid\":\"oid:0x260000000007c7\",\"mac\":\"77:66:44:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000007ef", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"vlan\":\"5\",\"mac\":\"77:66:55:44:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000006cd", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY:{\"mac\":\"77:66:55:33:22:11\",\"switch_id\":\"oid:0x21000000000000\"}": { + "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID": "oid:0x3a0000000007ef", + "SAI_FDB_ENTRY_ATTR_TYPE": "SAI_FDB_ENTRY_TYPE_DYNAMIC", + "SAI_FDB_ENTRY_ATTR_PACKET_ACTION": "SAI_PACKET_ACTION_FORWARD" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000005c5": { + "SAI_VLAN_ATTR_VLAN_ID": "2" + }, + "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:oid:0x260000000007c7": { + "SAI_VLAN_ATTR_VLAN_ID": "4" + } +} diff --git a/tests/fdbshow_input/counters_db.json b/tests/fdbshow_input/counters_db.json index acf46e0395..14da634911 100644 --- a/tests/fdbshow_input/counters_db.json +++ b/tests/fdbshow_input/counters_db.json @@ -1,7 +1,8 @@ { "COUNTERS_PORT_NAME_MAP": { "Ethernet0": "oid:0x1000000000528", - "Ethernet4": "oid:0x1000000000549" + "Ethernet4": "oid:0x1000000000549", + "Ethernet8": "oid:0x1000000000550" }, "COUNTERS_LAG_NAME_MAP": { "": "" diff --git a/tests/fdbshow_test.py b/tests/fdbshow_test.py index 3da84879f5..8814a6b323 100755 --- a/tests/fdbshow_test.py +++ b/tests/fdbshow_test.py @@ -18,6 +18,14 @@ Total number of entries 2 """ +show_mac_aging_time_output = """\ +Aging time for switch is 600 seconds +""" + +show_mac_aging_time_not_present_output = """\ +Aging time not configured for the switch +""" + show_mac_output = """\ No. Vlan MacAddress Port Type ----- ------ ----------------- ------------- ------- @@ -29,6 +37,10 @@ Total number of entries 5 """ +show_mac_count_output = """\ +Total number of entries 5 +""" + show_mac__port_vlan_output = """\ No. Vlan MacAddress Port Type ----- ------ ----------------- --------- ------- @@ -36,20 +48,99 @@ Total number of entries 1 """ +show_mac__address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__address_case_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 2 34:5F:78:9A:BC:DE Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__port_address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 4 66:55:44:33:22:11 Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__vlan_address_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------- + 1 4 66:55:44:33:22:11 Ethernet0 Dynamic +Total number of entries 1 +""" + +show_mac__type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__type_case_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- ------------- ------- + 1 2 11:22:33:44:55:66 Ethernet0 Dynamic + 2 4 66:55:44:33:22:11 Ethernet0 Dynamic + 3 4 77:66:44:33:22:11 1000000000fff Dynamic + 4 5 77:66:55:44:22:11 Ethernet4 Dynamic +Total number of entries 4 +""" + +show_mac__port_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__vlan_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__address_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + +show_mac__port_vlan_address_type_output = """\ + No. Vlan MacAddress Port Type +----- ------ ----------------- --------- ------ + 1 3 11:22:33:66:55:44 Ethernet4 Static +Total number of entries 1 +""" + show_mac_no_results_output = """\ No. Vlan MacAddress Port Type ----- ------ ------------ ------ ------ Total number of entries 0 """ -show_mac_no_port_output = """\ -'Ethernet20' is not in list +show_mac_invalid_port_output= """\ +Error: Invalid port eth123 """ -show_mac_no_vlan_output = """\ -123 is not in list +show_mac_invalid_vlan_output= """\ +Error: Invalid vlan id 10000 """ +show_mac_invalid_type_output= """\ +Error: Invalid type both +""" +show_mac_invalid_address_output= """\ +Error: Invalid mac address 12:345:67:a9:bc:d +""" class TestFdbshow(): @pytest.fixture(scope="class", autouse=True) @@ -86,6 +177,36 @@ def test_show_mac_def_vlan(self): assert return_code == 0 assert result == show_mac_output_with_def_vlan + def test_show_mac_aging_time(self): + self.set_mock_variant("1") + from .mock_tables import dbconnector + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + mock_db_path = os.path.join(test_path, "fdbshow_input") + jsonfile_appl = os.path.join(mock_db_path, 'appl_db') + dbconnector.dedicated_dbs['APPL_DB'] = jsonfile_appl + result = self.runner.invoke(show.cli.commands["mac"].commands["aging-time"], []) + dbconnector.dedicated_dbs['APPL_DB'] = None + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_aging_time_output + + def test_show_mac_no_aging_time(self): + self.set_mock_variant("1") + from .mock_tables import dbconnector + modules_path = os.path.join(os.path.dirname(__file__), "..") + test_path = os.path.join(modules_path, "tests") + mock_db_path = os.path.join(test_path, "fdbshow_input") + jsonfile_appl = os.path.join(mock_db_path, 'appl_db_no_age') + dbconnector.dedicated_dbs['APPL_DB'] = jsonfile_appl + result = self.runner.invoke(show.cli.commands["mac"].commands["aging-time"], []) + dbconnector.dedicated_dbs['APPL_DB'] = None + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_aging_time_not_present_output + def test_show_mac(self): self.set_mock_variant("1") @@ -101,6 +222,21 @@ def test_show_mac(self): assert return_code == 0 assert result == show_mac_output + def test_show_mac_count(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], ["-c"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_count_output + + return_code, result = get_result_and_return_code('fdbshow -c') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_count_output + def test_show_mac_port_vlan(self): self.set_mock_variant("1") @@ -116,20 +252,170 @@ def test_show_mac_port_vlan(self): assert return_code == 0 assert result == show_mac__port_vlan_output + def test_show_mac_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 11:22:33:66:55:44") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_output + + return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_output + + def test_show_mac_address_case(self): + self.set_mock_variant("7") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 34:5f:78:9a:bc:de") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_case_output + + return_code, result = get_result_and_return_code('fdbshow -a 34:5f:78:9a:bc:de') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_case_output + + def test_show_mac_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__type_output + + return_code, result = get_result_and_return_code('fdbshow -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__type_output + + def test_show_mac_type_case(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t dynamic") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__type_case_output + + return_code, result = get_result_and_return_code('fdbshow -t DYNAMIC') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__type_case_output + + def test_show_mac_port_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 66:55:44:33:22:11 -p Ethernet0") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -p Ethernet0') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_address_output + + def test_show_mac_vlan_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 66:55:44:33:22:11 -v 4") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__vlan_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 66:55:44:33:22:11 -v 4') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__vlan_address_output + + def test_show_mac_port_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet4 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_type_output + + return_code, result = get_result_and_return_code('fdbshow -p Ethernet4 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_type_output + + def test_show_mac_vlan_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 3 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__vlan_type_output + + return_code, result = get_result_and_return_code('fdbshow -v 3 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__vlan_type_output + + def test_show_mac_address_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 11:22:33:66:55:44 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__address_type_output + + return_code, result = get_result_and_return_code('fdbshow -a 11:22:33:66:55:44 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__address_type_output + + def test_show_mac_port_vlan_address_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 3 -p Ethernet4 -a 11:22:33:66:55:44 -t Static") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac__port_vlan_address_type_output + + return_code, result = get_result_and_return_code('fdbshow -v 3 -p Ethernet4 -a 11:22:33:66:55:44 -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac__port_vlan_address_type_output + def test_show_mac_no_port(self): self.set_mock_variant("1") - result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet20") + result = self.runner.invoke(show.cli.commands["mac"], "-p Ethernet8") print(result.exit_code) print(result.output) - assert result.exit_code == 1 - assert result.output == show_mac_no_port_output + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output - return_code, result = get_result_and_return_code('fdbshow -p Ethernet20') + return_code, result = get_result_and_return_code('fdbshow -p Ethernet8') print("return_code: {}".format(return_code)) print("result = {}".format(result)) - assert return_code == 1 - assert result == show_mac_no_port_output.strip("\n") + assert return_code == 0 + assert result == show_mac_no_results_output def test_show_mac_no_vlan(self): self.set_mock_variant("1") @@ -137,14 +423,44 @@ def test_show_mac_no_vlan(self): result = self.runner.invoke(show.cli.commands["mac"], "-v 123") print(result.exit_code) print(result.output) - assert result.exit_code == 1 - assert result.output == show_mac_no_vlan_output + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output return_code, result = get_result_and_return_code('fdbshow -v 123') print("return_code: {}".format(return_code)) print("result = {}".format(result)) - assert return_code == 1 - assert result == show_mac_no_vlan_output.strip("\n") + assert return_code == 0 + assert result == show_mac_no_results_output + + def test_show_mac_no_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 12:34:56:78:9A:BC") + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output + + return_code, result = get_result_and_return_code('fdbshow -a 12:34:56:78:9A:BC') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_no_results_output + + def test_show_mac_no_type(self): + self.set_mock_variant("6") + + result = self.runner.invoke(show.cli.commands["mac"], ["-t Static"]) + print(result.exit_code) + print(result.output) + assert result.exit_code == 0 + assert result.output == show_mac_no_results_output + + return_code, result = get_result_and_return_code('fdbshow -t Static') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 0 + assert result == show_mac_no_results_output def test_show_mac_no_fdb(self): self.set_mock_variant("3") @@ -196,3 +512,63 @@ def test_show_fetch_except(self): print("result = {}".format(output)) assert return_code == 1 assert "Failed to get Vlan id for bvid oid:0x260000000007c7" in output + + def test_show_mac_invalid_port(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-p eth123") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_port_output + + return_code, result = get_result_and_return_code('fdbshow -p eth123') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_port_output.strip("\n") + + def test_show_mac_invalid_vlan(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-v 10000") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_vlan_output + + return_code, result = get_result_and_return_code('fdbshow -v 10000') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_vlan_output.strip("\n") + + def test_show_mac_invalid_type(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-t both") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_type_output + + return_code, result = get_result_and_return_code('fdbshow -t both') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_type_output.strip("\n") + + def test_show_mac_invalid_address(self): + self.set_mock_variant("1") + + result = self.runner.invoke(show.cli.commands["mac"], "-a 12:345:67:a9:bc:d") + print(result.exit_code) + print(result.output) + assert result.exit_code == 1 + assert result.output == show_mac_invalid_address_output + + return_code, result = get_result_and_return_code('fdbshow -a 12:345:67:a9:bc:d') + print("return_code: {}".format(return_code)) + print("result = {}".format(result)) + assert return_code == 1 + assert result == show_mac_invalid_address_output.strip("\n")