|
| 1 | +from dump.match_infra import MatchRequest |
| 2 | +from dump.helper import create_template_dict |
| 3 | +from .executor import Executor |
| 4 | + |
| 5 | + |
| 6 | +class Fdb(Executor): |
| 7 | + """ |
| 8 | + Debug Dump Plugin for FDB Module |
| 9 | + """ |
| 10 | + ARG_NAME = "Vlan:fdb_entry" |
| 11 | + |
| 12 | + def __init__(self, match_engine=None): |
| 13 | + super().__init__(match_engine) |
| 14 | + |
| 15 | + def get_all_args(self, ns=""): |
| 16 | + req = MatchRequest(db="STATE_DB", table="FDB_TABLE", key_pattern="*", ns=ns) |
| 17 | + ret = self.match_engine.fetch(req) |
| 18 | + fdb_entries = ret["keys"] |
| 19 | + return [key.split("|")[-1] for key in fdb_entries] |
| 20 | + |
| 21 | + def execute(self, params): |
| 22 | + self.ret_temp = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"]) |
| 23 | + fdb_entry = params[Fdb.ARG_NAME] |
| 24 | + self.ns = params["namespace"] |
| 25 | + self.init_fdb_appl_info(fdb_entry) |
| 26 | + self.init_asic_fdb_info(fdb_entry) |
| 27 | + self.init_state_fdb_info(fdb_entry) |
| 28 | + return self.ret_temp |
| 29 | + |
| 30 | + def init_state_fdb_info(self, fdb_name): |
| 31 | + req = MatchRequest(db="STATE_DB", table="FDB_TABLE", key_pattern=fdb_name, ns=self.ns) |
| 32 | + ret = self.match_engine.fetch(req) |
| 33 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
| 34 | + |
| 35 | + def init_fdb_appl_info(self, fdb_name): |
| 36 | + req = MatchRequest(db="APPL_DB", table="FDB_TABLE", key_pattern=fdb_name, ns=self.ns) |
| 37 | + ret = self.match_engine.fetch(req) |
| 38 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) |
| 39 | + req = MatchRequest(db="APPL_DB", table="VXLAN_FDB_TABLE", key_pattern=fdb_name, ns=self.ns) |
| 40 | + ret = self.match_engine.fetch(req) |
| 41 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) |
| 42 | + req = MatchRequest(db="APPL_DB", table="MCLAG_FDB_TABLE", key_pattern=fdb_name, ns=self.ns) |
| 43 | + ret = self.match_engine.fetch(req) |
| 44 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"], False) |
| 45 | + |
| 46 | + def init_asic_fdb_info(self, fdb_name): |
| 47 | + # One colon between Vlan and MAC and 5 colons in mac address are expected in key |
| 48 | + if fdb_name.count(':') != 6: |
| 49 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") |
| 50 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") |
| 51 | + return |
| 52 | + |
| 53 | + key_split = fdb_name.split(":",1) |
| 54 | + vlan_name = key_split[0] |
| 55 | + mac = key_split[1] |
| 56 | + if vlan_name[0:4] != "Vlan" or not vlan_name[4:].isnumeric(): |
| 57 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") |
| 58 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") |
| 59 | + return |
| 60 | + |
| 61 | + vlan_num = int(vlan_name[4:]) |
| 62 | + # Find the table named "ASIC_STATE:SAI_OBJECT_TYPE_VLAN:*" in which SAI_VLAN_AT'TR_VLAN_ID = vlan_num |
| 63 | + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_VLAN", key_pattern="*", field="SAI_VLAN_ATTR_VLAN_ID", |
| 64 | + value=str(vlan_num), ns=self.ns) |
| 65 | + ret = self.match_engine.fetch(req) |
| 66 | + if not ret["error"] and len(ret["keys"]) == 1: |
| 67 | + vlan_obj = ret["keys"][0].split(":",2)[-1] |
| 68 | + else: |
| 69 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY") |
| 70 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") |
| 71 | + return |
| 72 | + |
| 73 | + # ASIC_DB FDB format is bvid:vlan_obj + mac:mac_address + switch id which is wildcard here |
| 74 | + fdb_key = '{"bvid":"' + vlan_obj + '","mac":"' + mac.upper() + '"*}' |
| 75 | + req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_FDB_ENTRY", key_pattern=fdb_key, |
| 76 | + return_fields=["SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"], ns=self.ns) |
| 77 | + ret = self.match_engine.fetch(req) |
| 78 | + bridge_port_id = "" |
| 79 | + if not ret["error"] and len(ret["keys"]) != 0: |
| 80 | + asic_fdb_key = ret["keys"][0] |
| 81 | + if asic_fdb_key in ret["return_values"] and "SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID" in ret["return_values"][asic_fdb_key]: |
| 82 | + bridge_port_id = ret["return_values"][asic_fdb_key]["SAI_FDB_ENTRY_ATTR_BRIDGE_PORT_ID"] |
| 83 | + else: |
| 84 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") |
| 85 | + |
| 86 | + if bridge_port_id: |
| 87 | + bridge_port_req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT", |
| 88 | + key_pattern = bridge_port_id, ns = self.ns) |
| 89 | + bridge_ret = self.match_engine.fetch(bridge_port_req) |
| 90 | + if not bridge_ret["error"] and len(bridge_ret["keys"]) != 0: |
| 91 | + self.ret_temp[bridge_port_req.db]["keys"].append(bridge_ret["keys"][0]) |
| 92 | + else: |
| 93 | + self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_BRIDGE_PORT") |
| 94 | + |
| 95 | + |
| 96 | + self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"]) |
0 commit comments