Skip to content

Commit

Permalink
[debug dump util] Changes for EVPN and VxLAN dump module (#1892)
Browse files Browse the repository at this point in the history
*Added dump utility for EVPN and VxLAN related modules
Signed-off-by: Sudharsan Dhamal Gopalarathnam <sudharsand@nvidia.com>
  • Loading branch information
dgsudharsan authored Nov 22, 2021
1 parent 02a98ef commit a395e28
Show file tree
Hide file tree
Showing 10 changed files with 1,009 additions and 0 deletions.
120 changes: 120 additions & 0 deletions dump/plugins/evpn.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from dump.match_infra import MatchRequest
from dump.helper import create_template_dict
from .executor import Executor


class Evpn(Executor):
"""
Debug Dump Plugin for EVPN Module
"""
ARG_NAME = "Remote VNI"

def __init__(self, match_engine=None):
super().__init__(match_engine)
self.ret_temp = {}
self.ns = ''
self.remote_ip = ''
self.vlan = ''
self.tunnel_obj = ''
self.encap_mappers = []
self.decap_mappers = []
self.asic_tunnel_cache = {}
self.asic_tunnel_term_cache = {}
self.asic_tunnel_map_cache = {}

def get_all_args(self, ns=""):
req = MatchRequest(db="APPL_DB", table="VXLAN_REMOTE_VNI_TABLE", key_pattern="*", ns=ns)
ret = self.match_engine.fetch(req)
evpns = ret["keys"]
return [key.split(":", 1)[-1] for key in evpns]

def execute(self, params):
self.ret_temp = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"])
evpn_name = params[Evpn.ARG_NAME]
self.remote_ip = evpn_name.split(':')[-1]
self.remote_vlan = evpn_name.split(':')[0]
self.ns = params["namespace"]
self.init_evpn_appl_info(evpn_name)
self.init_asic_evpn_info()
self.init_asic_evpn_map_info()
self.init_asic_evpn_term_info()
self.init_state_evpn_info(evpn_name)
return self.ret_temp

def add_to_ret_template(self, table, db, keys, err):
if not err and keys:
self.ret_temp[db]["keys"].extend(keys)
return True
else:
self.ret_temp[db]["tables_not_found"].extend([table])
return False

def init_evpn_appl_info(self, evpn_name):
req = MatchRequest(db="APPL_DB", table="VXLAN_REMOTE_VNI_TABLE", key_pattern=evpn_name, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_state_evpn_info(self, evpn_name):
state_key = "EVPN_" + self.remote_ip
req = MatchRequest(db="STATE_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=state_key, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_evpn_info(self):
if not self.remote_ip:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL")
return None
if self.remote_ip in self.asic_tunnel_cache:
ret = self.asic_tunnel_cache[self.remote_ip]
else:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL",
field="SAI_TUNNEL_ATTR_ENCAP_DST_IP", value=self.remote_ip, ns=self.ns,
return_fields=["SAI_TUNNEL_ATTR_TYPE", "SAI_TUNNEL_ATTR_ENCAP_MAPPERS",
"SAI_TUNNEL_ATTR_DECAP_MAPPERS"])
ret = self.match_engine.fetch(req)
self.asic_tunnel_cache[self.remote_ip] = ret
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_ATTR_TYPE"] == "SAI_TUNNEL_TYPE_VXLAN"]
if ret["keys"]:
asic_key = ret["keys"][0]
self.tunnel_obj = asic_key.replace("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL:", "")
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"]:
self.encap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"].split(':', 1)[-1].split(',')
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"]:
self.decap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"].split(':', 1)[-1].split(',')
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_evpn_term_info(self):
if not self.tunnel_obj:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY")
return None
if self.tunnel_obj in self.asic_tunnel_term_cache:
ret = self.asic_tunnel_term_cache[self.tunnel_obj]
else:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY",
field="SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID", value=self.tunnel_obj, ns=self.ns)
ret = self.match_engine.fetch(req)
self.asic_tunnel_term_cache[self.tunnel_obj] = ret
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_evpn_map_info(self):
if not (self.encap_mappers or self.decap_mappers):
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
return None
for key in self.encap_mappers:
if key in self.asic_tunnel_map_cache:
ret = self.asic_tunnel_map_cache[key]
else:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
key_pattern=key, ns=self.ns)
ret = self.match_engine.fetch(req)
self.asic_tunnel_map_cache[key] = ret
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
for key in self.decap_mappers:
if key in self.asic_tunnel_map_cache:
ret = self.asic_tunnel_map_cache[key]
else:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
key_pattern=key, ns=self.ns)
ret = self.match_engine.fetch(req)
self.asic_tunnel_map_cache[key] = ret
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
110 changes: 110 additions & 0 deletions dump/plugins/vxlan_tunnel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
from dump.match_infra import MatchRequest
from dump.helper import create_template_dict
from .executor import Executor


class Vxlan_tunnel(Executor):
"""
Debug Dump Plugin for Vxlan Tunnel Module
"""
ARG_NAME = "vxlan_tunnel_name"

def __init__(self, match_engine=None):
super().__init__(match_engine)
self.ret_temp = {}
self.ns = ''
self.src_ip = ''
self.dst_ip = ''
self.tunnel_obj = ''
self.encap_mappers = []
self.decap_mappers = []

def get_all_args(self, ns=""):
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL", key_pattern="*", ns=ns)
ret = self.match_engine.fetch(req)
vxlan_tunnels = ret["keys"]
return [key.split("|")[-1] for key in vxlan_tunnels]

def execute(self, params):
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB", "STATE_DB"])
vxlan_tunnel_name = params[Vxlan_tunnel.ARG_NAME]
self.ns = params["namespace"]
self.init_vxlan_tunnel_config_info(vxlan_tunnel_name)
self.init_vxlan_tunnel_appl_info(vxlan_tunnel_name)
self.init_asic_vxlan_tunnel_info()
self.init_asic_vxlan_tunnel_map_info()
self.init_asic_vxlan_tunnel_term_info()
self.init_state_vxlan_tunnel_info(vxlan_tunnel_name)
return self.ret_temp

def add_to_ret_template(self, table, db, keys, err):
if not err and keys:
self.ret_temp[db]["keys"].extend(keys)
return True
else:
self.ret_temp[db]["tables_not_found"].extend([table])
return False

def init_vxlan_tunnel_config_info(self, vxlan_tunnel_name):
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL", key_pattern=vxlan_tunnel_name, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_vxlan_tunnel_appl_info(self, vxlan_tunnel_name):
req = MatchRequest(db="APPL_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=vxlan_tunnel_name, ns=self.ns,
return_fields=["src_ip", "dst_ip"])
ret = self.match_engine.fetch(req)
if ret["keys"]:
app_key = ret["keys"][0]
self.src_ip = ret["return_values"][app_key]["src_ip"]
self.dst_ip = ret["return_values"][app_key]["dst_ip"]
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_state_vxlan_tunnel_info(self, vxlan_tunnel_name):
req = MatchRequest(db="STATE_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=vxlan_tunnel_name, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_vxlan_tunnel_info(self):
if not self.src_ip:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL")
return None
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL", field="SAI_TUNNEL_ATTR_ENCAP_SRC_IP", value=self.src_ip, ns=self.ns,
return_fields=["SAI_TUNNEL_ATTR_TYPE", "SAI_TUNNEL_ATTR_ENCAP_DST_IP",
"SAI_TUNNEL_ATTR_ENCAP_MAPPERS", "SAI_TUNNEL_ATTR_DECAP_MAPPERS"])
ret = self.match_engine.fetch(req)
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_ATTR_TYPE"] == "SAI_TUNNEL_TYPE_VXLAN"]
ret["keys"] = [x for x in ret["keys"] if not self.dst_ip and ret["return_values"][x]["SAI_TUNNEL_ATTR_ENCAP_DST_IP"] == "" or
ret["return_values"][x]["SAI_TUNNEL_ATTR_ENCAP_DST_IP"] == self.dst_ip]
if ret["keys"]:
asic_key = ret["keys"][0]
self.tunnel_obj = asic_key.replace("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL:", "")
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"]:
self.encap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"].split(':', 1)[-1].split(',')
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"]:
self.decap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"].split(':', 1)[-1].split(',')
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_vxlan_tunnel_term_info(self):
if not self.tunnel_obj:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY")
return None
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY",
field="SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID", value=self.tunnel_obj, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_vxlan_tunnel_map_info(self):
if not (self.encap_mappers or self.decap_mappers):
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
return None
for key in self.encap_mappers:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
key_pattern=key, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
for key in self.decap_mappers:
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
key_pattern=key, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
85 changes: 85 additions & 0 deletions dump/plugins/vxlan_tunnel_map.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
from dump.match_infra import MatchRequest
from dump.helper import create_template_dict
from .executor import Executor


class Vxlan_tunnel_map(Executor):
"""
Debug Dump Plugin for Vxlan Tunnel Map Module
"""
ARG_NAME = "vxlan_tunnel_map_name"

def __init__(self, match_engine=None):
super().__init__(match_engine)
self.ret_temp = {}
self.ns = ''
self.vlan = ''
self.vni = ''
self.tunnel_map_obj = ''
self.encap_mappers = []
self.decap_mappers = []

def get_all_args(self, ns=""):
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL_MAP", key_pattern="*", ns=ns)
ret = self.match_engine.fetch(req)
vxlan_tunnel_maps = ret["keys"]
return [key.split("|", 1)[-1] for key in vxlan_tunnel_maps]

def execute(self, params):
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB"])
vxlan_tunnel_map_name = params[Vxlan_tunnel_map.ARG_NAME]
self.ns = params["namespace"]
self.init_vxlan_tunnel_map_config_info(vxlan_tunnel_map_name)
self.init_vxlan_tunnel_map_appl_info(vxlan_tunnel_map_name)
self.init_asic_vxlan_tunnel_map_entry_info()
self.init_asic_vxlan_tunnel_map_info()
return self.ret_temp

def add_to_ret_template(self, table, db, keys, err):
if not err and keys:
self.ret_temp[db]["keys"].extend(keys)
return True
else:
self.ret_temp[db]["tables_not_found"].extend([table])
return False

def init_vxlan_tunnel_map_config_info(self, vxlan_tunnel_map_name):
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL_MAP", key_pattern=vxlan_tunnel_map_name, ns=self.ns,
return_fields=["vlan", "vni"])
ret = self.match_engine.fetch(req)
if ret["keys"]:
cfg_key = ret["keys"][0]
self.vlan = ret["return_values"][cfg_key]["vlan"].replace("Vlan", "")
self.vni = ret["return_values"][cfg_key]["vni"]
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_vxlan_tunnel_map_appl_info(self, vxlan_tunnel_map_name):
app_vxlan_tunnel_map_name = vxlan_tunnel_map_name.replace('|', ':')
req = MatchRequest(db="APPL_DB", table="VXLAN_TUNNEL_MAP_TABLE", key_pattern=app_vxlan_tunnel_map_name, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_vxlan_tunnel_map_entry_info(self):
if not self.vlan:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP_ENTRY")
return None
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP_ENTRY",
field="SAI_TUNNEL_MAP_ENTRY_ATTR_VLAN_ID_VALUE", value=self.vlan, ns=self.ns,
return_fields=["SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE",
"SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY",
"SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP"])
ret = self.match_engine.fetch(req)
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE"] == "SAI_TUNNEL_MAP_TYPE_VNI_TO_VLAN_ID"]
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY"] == self.vni]
if ret["keys"]:
self.tunnel_map_obj = ret["return_values"][ret["keys"][0]]["SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP"]
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

def init_asic_vxlan_tunnel_map_info(self):
if not self.tunnel_map_obj:
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
return None
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
key_pattern=self.tunnel_map_obj, value=self.vlan, ns=self.ns)
ret = self.match_engine.fetch(req)
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
34 changes: 34 additions & 0 deletions tests/dump_input/vxlan/appl_db.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
{
"VXLAN_TUNNEL_MAP_TABLE:vtep_1336:map_1336_Vlan2345": {
"vlan": "Vlan2345",
"vni": "1336"
},
"VXLAN_TUNNEL_MAP_TABLE:vtep_1336:map_1337_Vlan2346": {
"vlan": "Vlan2346",
"vni": "1337"
},
"VXLAN_TUNNEL_TABLE:vtep_1111": {
"src_ip": "10.1.0.31"
},
"VXLAN_TUNNEL_TABLE:vtep_1336": {
"src_ip": "10.1.0.32"
},
"VXLAN_TUNNEL_TABLE:vtep_2312": {
"src_ip": "10.1.0.33"
},
"VXLAN_TUNNEL_TABLE:vtep_1000": {
"src_ip": "10.1.0.34"
},
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.32": {
"vni": "1336"
},
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.33": {
"vni": "1336"
},
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.34": {
"vni": "1336"
},
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.35": {
"vni": "1336"
}
}
Loading

0 comments on commit a395e28

Please sign in to comment.