Skip to content

Commit d9f3afe

Browse files
authored
[fdbshow] Adding more options for fdbshow and show mac (sonic-net#1982)
#### What I did Added more options to filter output in show mac and fdbshow command. Introduced options for filter by address and filter by type. Added one more option to display only count. Introduced show command to display fdb aging time in the switch. #### How I did it Modifying fdbshow and show scripts to include the above-mentioned options #### How to verify it Added UT for all the newly introduced options and commands #### Previous command output (if the output of a command-line utility has changed) ``` show mac -h Usage: show mac [OPTIONS] Show MAC (FDB) entries Options: -v, --vlan TEXT -p, --port TEXT --verbose Enable verbose output -h, -?, --help Show this message and exit. ``` #### New command output (if the output of a command-line utility has changed) ``` show mac -h Usage: show mac [OPTIONS] COMMAND [ARGS]... Show MAC (FDB) entries Options: -v, --vlan TEXT -p, --port TEXT -a, --address TEXT -t, --type TEXT -c, --count --verbose Enable verbose output -h, -?, --help Show this message and exit. Commands: aging-time show mac No. Vlan MacAddress Port Type ----- ------ ----------------- ----------- ------- 1 10 98:03:9B:82:BB:5B Ethernet60 Dynamic 2 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic 3 10 EC:0D:9A:CD:91:73 Ethernet124 Dynamic Total number of entries 3 show mac --address EC:0D:9A:CD:91:72 No. Vlan MacAddress Port Type ----- ------ ----------------- ---------- ------- 1 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic show mac --count Total number of entries 3 show mac --type Dynamic No. Vlan MacAddress Port Type ----- ------ ----------------- ----------- ------- 1 10 98:03:9B:82:BB:5B Ethernet60 Dynamic 2 10 EC:0D:9A:CD:91:72 Ethernet64 Dynamic 3 10 EC:0D:9A:CD:91:73 Ethernet124 Dynamic Total number of entries 3 show mac aging-time Aging time for switch is 600 seconds ```
1 parent 902e14f commit d9f3afe

9 files changed

+675
-108
lines changed

doc/Command-Reference.md

+94-62
Original file line numberDiff line numberDiff line change
@@ -8920,90 +8920,122 @@ This command displays the MAC (FDB) entries either in full or partial as given b
89208920
1) show mac - displays the full table
89218921
2) show mac -v <vlanid> - displays the MACs learnt on the particular VLAN ID.
89228922
3) show mac -p <port> - displays the MACs learnt on the particular port.
8923+
4) show mac -a <mac-address> - display the MACs that match a specific mac-address
8924+
5) show mac -t <type> - display the MACs that match a specific type (static/dynamic)
8925+
6) show mac -c - display the count of MAC addresses
89238926
8927+
To show the default MAC address aging time on the switch.
89248928
89258929
- Usage:
89268930
```
8927-
show mac [-v <vlan_id>] [-p <port_name>]
8931+
show mac [-v <vlan_id>] [-p <port_name>] [-a <mac_address>] [-t <type>] [-c]
89288932
```
89298933
89308934
- Example:
89318935
```
89328936
admin@sonic:~$ show mac
8933-
No. Vlan MacAddress Port
8934-
----- ------ ----------------- -----------
8935-
1 1000 E2:8C:56:85:4A:CD Ethernet192
8936-
2 1000 A0:1B:5E:47:C9:76 Ethernet192
8937-
3 1000 AA:54:EF:2C:EE:30 Ethernet192
8938-
4 1000 A4:3F:F2:17:A3:FC Ethernet192
8939-
5 1000 0C:FC:01:72:29:91 Ethernet192
8940-
6 1000 48:6D:01:7E:C9:FD Ethernet192
8941-
7 1000 1C:6B:7E:34:5F:A6 Ethernet192
8942-
8 1000 EE:81:D9:7B:93:A9 Ethernet192
8943-
9 1000 CC:F8:8D:BB:85:E2 Ethernet192
8944-
10 1000 0A:52:B3:9C:FB:6C Ethernet192
8945-
11 1000 C6:E2:72:02:D1:23 Ethernet192
8946-
12 1000 8A:C9:5C:25:E9:28 Ethernet192
8947-
13 1000 5E:CD:34:E4:94:18 Ethernet192
8948-
14 1000 7E:49:1F:B5:91:B5 Ethernet192
8949-
15 1000 AE:DD:67:F3:09:5A Ethernet192
8950-
16 1000 DC:2F:D1:08:4B:DE Ethernet192
8951-
17 1000 50:96:23:AD:F1:65 Ethernet192
8952-
18 1000 C6:C9:5E:AE:24:42 Ethernet192
8937+
No. Vlan MacAddress Port Type
8938+
----- ------ ----------------- ----------- -------
8939+
1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic
8940+
2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic
8941+
3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic
8942+
4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic
8943+
5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic
8944+
6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic
8945+
7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic
8946+
8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic
8947+
9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic
8948+
10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic
8949+
11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic
8950+
12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic
8951+
13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic
8952+
14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic
8953+
15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic
8954+
16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic
8955+
17 1000 50:96:23:AD:F1:65 Ethernet192 Static
8956+
18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static
89538957
Total number of entries 18
89548958
```
89558959
8956-
Optionally, you can specify a VLAN ID or interface name in order to display only that particular entries
8960+
Optionally, you can specify a VLAN ID or interface name or type or mac-address in order to display only that particular entries
89578961
89588962
- Examples:
89598963
```
89608964
admin@sonic:~$ show mac -v 1000
8961-
No. Vlan MacAddress Port
8962-
----- ------ ----------------- -----------
8963-
1 1000 E2:8C:56:85:4A:CD Ethernet192
8964-
2 1000 A0:1B:5E:47:C9:76 Ethernet192
8965-
3 1000 AA:54:EF:2C:EE:30 Ethernet192
8966-
4 1000 A4:3F:F2:17:A3:FC Ethernet192
8967-
5 1000 0C:FC:01:72:29:91 Ethernet192
8968-
6 1000 48:6D:01:7E:C9:FD Ethernet192
8969-
7 1000 1C:6B:7E:34:5F:A6 Ethernet192
8970-
8 1000 EE:81:D9:7B:93:A9 Ethernet192
8971-
9 1000 CC:F8:8D:BB:85:E2 Ethernet192
8972-
10 1000 0A:52:B3:9C:FB:6C Ethernet192
8973-
11 1000 C6:E2:72:02:D1:23 Ethernet192
8974-
12 1000 8A:C9:5C:25:E9:28 Ethernet192
8975-
13 1000 5E:CD:34:E4:94:18 Ethernet192
8976-
14 1000 7E:49:1F:B5:91:B5 Ethernet192
8977-
15 1000 AE:DD:67:F3:09:5A Ethernet192
8978-
16 1000 DC:2F:D1:08:4B:DE Ethernet192
8979-
17 1000 50:96:23:AD:F1:65 Ethernet192
8980-
18 1000 C6:C9:5E:AE:24:42 Ethernet192
8965+
No. Vlan MacAddress Port Type
8966+
----- ------ ----------------- ----------- -------
8967+
1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic
8968+
2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic
8969+
3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic
8970+
4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic
8971+
5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic
8972+
6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic
8973+
7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic
8974+
8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic
8975+
9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic
8976+
10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic
8977+
11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic
8978+
12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic
8979+
13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic
8980+
14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic
8981+
15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic
8982+
16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic
8983+
17 1000 50:96:23:AD:F1:65 Ethernet192 Static
8984+
18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static
89818985
Total number of entries 18
89828986
```
89838987
```
89848988
admin@sonic:~$ show mac -p Ethernet192
8985-
No. Vlan MacAddress Port
8986-
----- ------ ----------------- -----------
8987-
1 1000 E2:8C:56:85:4A:CD Ethernet192
8988-
2 1000 A0:1B:5E:47:C9:76 Ethernet192
8989-
3 1000 AA:54:EF:2C:EE:30 Ethernet192
8990-
4 1000 A4:3F:F2:17:A3:FC Ethernet192
8991-
5 1000 0C:FC:01:72:29:91 Ethernet192
8992-
6 1000 48:6D:01:7E:C9:FD Ethernet192
8993-
7 1000 1C:6B:7E:34:5F:A6 Ethernet192
8994-
8 1000 EE:81:D9:7B:93:A9 Ethernet192
8995-
9 1000 CC:F8:8D:BB:85:E2 Ethernet192
8996-
10 1000 0A:52:B3:9C:FB:6C Ethernet192
8997-
11 1000 C6:E2:72:02:D1:23 Ethernet192
8998-
12 1000 8A:C9:5C:25:E9:28 Ethernet192
8999-
13 1000 5E:CD:34:E4:94:18 Ethernet192
9000-
14 1000 7E:49:1F:B5:91:B5 Ethernet192
9001-
15 1000 AE:DD:67:F3:09:5A Ethernet192
9002-
16 1000 DC:2F:D1:08:4B:DE Ethernet192
9003-
17 1000 50:96:23:AD:F1:65 Ethernet192
9004-
18 1000 C6:C9:5E:AE:24:42 Ethernet192
8989+
No. Vlan MacAddress Port Type
8990+
----- ------ ----------------- ----------- -------
8991+
1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic
8992+
2 1000 A0:1B:5E:47:C9:76 Ethernet192 Dynamic
8993+
3 1000 AA:54:EF:2C:EE:30 Ethernet192 Dynamic
8994+
4 1000 A4:3F:F2:17:A3:FC Ethernet192 Dynamic
8995+
5 1000 0C:FC:01:72:29:91 Ethernet192 Dynamic
8996+
6 1000 48:6D:01:7E:C9:FD Ethernet192 Dynamic
8997+
7 1000 1C:6B:7E:34:5F:A6 Ethernet192 Dynamic
8998+
8 1000 EE:81:D9:7B:93:A9 Ethernet192 Dynamic
8999+
9 1000 CC:F8:8D:BB:85:E2 Ethernet192 Dynamic
9000+
10 1000 0A:52:B3:9C:FB:6C Ethernet192 Dynamic
9001+
11 1000 C6:E2:72:02:D1:23 Ethernet192 Dynamic
9002+
12 1000 8A:C9:5C:25:E9:28 Ethernet192 Dynamic
9003+
13 1000 5E:CD:34:E4:94:18 Ethernet192 Dynamic
9004+
14 1000 7E:49:1F:B5:91:B5 Ethernet192 Dynamic
9005+
15 1000 AE:DD:67:F3:09:5A Ethernet192 Dynamic
9006+
16 1000 DC:2F:D1:08:4B:DE Ethernet192 Dynamic
9007+
17 1000 50:96:23:AD:F1:65 Ethernet192 Static
9008+
18 1000 C6:C9:5E:AE:24:42 Ethernet192 Static
90059009
Total number of entries 18
90069010
```
9011+
```
9012+
admin@sonic:~$ show mac -a E2:8C:56:85:4A:CD
9013+
No. Vlan MacAddress Port Type
9014+
----- ------ ----------------- ----------- -------
9015+
1 1000 E2:8C:56:85:4A:CD Ethernet192 Dynamic
9016+
Total number of entries 1
9017+
```
9018+
```
9019+
admin@sonic:~$ show mac -t Static
9020+
No. Vlan MacAddress Port Type
9021+
----- ------ ----------------- ----------- -------
9022+
2 1000 50:96:23:AD:F1:65 Ethernet192 Static
9023+
2 1000 C6:C9:5E:AE:24:42 Ethernet192 Static
9024+
Total number of entries 2
9025+
```
9026+
```
9027+
admin@sonic:~$ show mac -c
9028+
Total number of entries 18
9029+
```
9030+
9031+
**show mac aging-time**
9032+
9033+
This command displays the default mac aging time on the switch
9034+
9035+
```
9036+
admin@sonic:~$ show mac aging-time
9037+
Aging time for switch is 600 seconds
9038+
```
90079039
90089040
**sonic-clear fdb all**
90099041

scripts/fdbshow

+58-29
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ import argparse
3030
import json
3131
import sys
3232
import os
33+
import re
3334

3435
# mock the redis for unit test purposes #
3536
try: # pragma: no cover
@@ -43,7 +44,9 @@ try: # pragma: no cover
4344
"2": 'asic_db_def_vlan',
4445
"3": 'asic_db_no_fdb',
4546
"4": 'asic_db_no_bridge',
46-
"5": 'asic_db_fetch_except'}
47+
"5": 'asic_db_fetch_except',
48+
"6": 'asic_db_no_static',
49+
"7": 'asic_db_mac_case'}
4750
mock_db_path = os.path.join(test_path, "fdbshow_input")
4851
file_name = mock_variants[os.environ["FDBSHOW_MOCK"]]
4952
jsonfile_asic = os.path.join(mock_db_path, file_name)
@@ -53,15 +56,13 @@ try: # pragma: no cover
5356
except KeyError: # pragma: no cover
5457
pass
5558

56-
from natsort import natsorted
5759
from swsssdk import port_util
5860
from swsscommon.swsscommon import SonicV2Connector
5961
from tabulate import tabulate
6062

6163
class FdbShow(object):
6264

6365
HEADER = ['No.', 'Vlan', 'MacAddress', 'Port', 'Type']
64-
FDB_COUNT = 0
6566

6667
def __init__(self):
6768
super(FdbShow,self).__init__()
@@ -135,53 +136,81 @@ class FdbShow(object):
135136
return
136137

137138

138-
def get_iter_index(self, key_value, pos=0):
139-
"""
140-
Get the starting index of matched entry
141-
"""
142-
if pos != 0:
143-
self.bridge_mac_list = natsorted(self.bridge_mac_list, key = lambda x: x[pos])
144-
145-
keys = [r[pos] for r in self.bridge_mac_list]
146-
return keys.index(key_value)
147-
148-
149-
def display(self, vlan, port):
139+
def display(self, vlan, port, address, entry_type, count):
150140
"""
151141
Display the FDB entries for specified vlan/port.
152142
@todo: - PortChannel support
153143
"""
154144
output = []
155145

156146
if vlan is not None:
157-
vlan = int(vlan)
158-
s_index = self.get_iter_index(vlan)
159-
self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:]
160-
if fdb[0] == vlan]
161-
if port is not None:
162-
s_index = self.get_iter_index(port, 2)
163-
self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list[s_index:]
164-
if fdb[2] == port]
147+
vlan_val = int(vlan)
148+
149+
if address is not None:
150+
address = address.upper()
165151

166-
for fdb in self.bridge_mac_list:
167-
self.FDB_COUNT += 1
168-
output.append([self.FDB_COUNT, fdb[0], fdb[1], fdb[2], fdb[3]])
152+
if entry_type is not None:
153+
entry_type = entry_type.capitalize()
169154

170-
print(tabulate(output, self.HEADER))
171-
print("Total number of entries {0}".format(self.FDB_COUNT))
155+
self.bridge_mac_list = [fdb for fdb in self.bridge_mac_list
156+
if (vlan is None or fdb[0] == vlan_val) and
157+
(port is None or fdb[2] == port) and
158+
(address is None or fdb[1] == address) and
159+
(entry_type is None or fdb[3] == entry_type)]
172160

161+
if not count:
162+
fdb_index = 1
163+
for fdb in self.bridge_mac_list:
164+
output.append([fdb_index, fdb[0], fdb[1], fdb[2], fdb[3]])
165+
fdb_index += 1
166+
print(tabulate(output, self.HEADER))
167+
168+
print("Total number of entries {0}".format(len(self.bridge_mac_list)))
169+
170+
def validate_params(self, vlan, port, address, entry_type):
171+
if vlan is not None:
172+
if not vlan.isnumeric():
173+
print("Error: Invalid vlan id {0}".format(vlan))
174+
return False
175+
176+
vlan_val = int(vlan)
177+
if (vlan_val not in range(1,4096)):
178+
print("Error: Invalid vlan id {0}".format(vlan))
179+
return False
180+
181+
if port is not None and port not in self.if_name_map:
182+
print("Error: Invalid port {0}".format(port))
183+
return False
184+
185+
if address is not None:
186+
mac_addr_pattern ="^([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2})$"
187+
if not re.match(mac_addr_pattern, address):
188+
print("Error: Invalid mac address {0}".format(address))
189+
return False
190+
191+
if entry_type is not None and entry_type.capitalize() not in ["Static", "Dynamic"]:
192+
print("Error: Invalid type {0}". format(entry_type))
193+
return False
194+
195+
return True
173196

174197
def main():
175198

176199
parser = argparse.ArgumentParser(description='Display ASIC FDB entries',
177200
formatter_class=argparse.RawTextHelpFormatter)
178201
parser.add_argument('-p', '--port', type=str, help='FDB learned on specific port: Ethernet0', default=None)
179202
parser.add_argument('-v', '--vlan', type=str, help='FDB learned on specific Vlan: 1001', default=None)
203+
parser.add_argument('-a', '--address', type=str, help='FDB display based on specific mac address', default=None)
204+
parser.add_argument('-t', '--type', type=str, help='FDB display of specific type of mac address', default=None)
205+
parser.add_argument('-c', '--count', action='store_true', help='FDB display count of mac address')
180206
args = parser.parse_args()
181207

182208
try:
183209
fdb = FdbShow()
184-
fdb.display(args.vlan, args.port)
210+
if not fdb.validate_params(args.vlan, args.port, args.address, args.type):
211+
sys.exit(1)
212+
213+
fdb.display(args.vlan, args.port, args.address, args.type, args.count)
185214
except Exception as e:
186215
print(str(e))
187216
sys.exit(1)

show/main.py

+36-2
Original file line numberDiff line numberDiff line change
@@ -722,13 +722,20 @@ def pwm_headroom_pool():
722722
# 'mac' command ("show mac ...")
723723
#
724724

725-
@cli.command()
725+
@cli.group(cls=clicommon.AliasedGroup, invoke_without_command="true")
726+
@click.pass_context
726727
@click.option('-v', '--vlan')
727728
@click.option('-p', '--port')
729+
@click.option('-a', '--address')
730+
@click.option('-t', '--type')
731+
@click.option('-c', '--count', is_flag=True)
728732
@click.option('--verbose', is_flag=True, help="Enable verbose output")
729-
def mac(vlan, port, verbose):
733+
def mac(ctx, vlan, port, address, type, count, verbose):
730734
"""Show MAC (FDB) entries"""
731735

736+
if ctx.invoked_subcommand is not None:
737+
return
738+
732739
cmd = "fdbshow"
733740

734741
if vlan is not None:
@@ -737,8 +744,35 @@ def mac(vlan, port, verbose):
737744
if port is not None:
738745
cmd += " -p {}".format(port)
739746

747+
if address is not None:
748+
cmd += " -a {}".format(address)
749+
750+
if type is not None:
751+
cmd += " -t {}".format(type)
752+
753+
if count:
754+
cmd += " -c"
755+
740756
run_command(cmd, display_cmd=verbose)
741757

758+
@mac.command('aging-time')
759+
@click.pass_context
760+
def aging_time(ctx):
761+
app_db = SonicV2Connector()
762+
app_db.connect(app_db.APPL_DB)
763+
table = "SWITCH_TABLE*"
764+
keys = app_db.keys(app_db.APPL_DB, table)
765+
766+
if not keys:
767+
click.echo("Aging time not configured for the switch")
768+
return
769+
770+
for key in keys:
771+
fdb_aging_time = app_db.get(app_db.APPL_DB, key, 'fdb_aging_time')
772+
if fdb_aging_time is not None:
773+
click.echo("Aging time for {} is {} seconds".format(key.split(':')[-1], fdb_aging_time))
774+
else:
775+
click.echo("Aging time not configured for the {}".format(key.split(':')[-1]))
742776
#
743777
# 'show route-map' command ("show route-map")
744778
#

tests/fdbshow_input/appl_db.json

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"SWITCH_TABLE:switch": {
3+
"fdb_aging_time" : "600"
4+
}
5+
}
+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"SWITCH_TABLE:switch": {
3+
"ecmp_hash_seed" : "600"
4+
}
5+
}

0 commit comments

Comments
 (0)