Skip to content

Commit a395e28

Browse files
authored
[debug dump util] Changes for EVPN and VxLAN dump module (#1892)
*Added dump utility for EVPN and VxLAN related modules Signed-off-by: Sudharsan Dhamal Gopalarathnam <[email protected]>
1 parent 02a98ef commit a395e28

File tree

10 files changed

+1009
-0
lines changed

10 files changed

+1009
-0
lines changed

dump/plugins/evpn.py

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from dump.match_infra import MatchRequest
2+
from dump.helper import create_template_dict
3+
from .executor import Executor
4+
5+
6+
class Evpn(Executor):
7+
"""
8+
Debug Dump Plugin for EVPN Module
9+
"""
10+
ARG_NAME = "Remote VNI"
11+
12+
def __init__(self, match_engine=None):
13+
super().__init__(match_engine)
14+
self.ret_temp = {}
15+
self.ns = ''
16+
self.remote_ip = ''
17+
self.vlan = ''
18+
self.tunnel_obj = ''
19+
self.encap_mappers = []
20+
self.decap_mappers = []
21+
self.asic_tunnel_cache = {}
22+
self.asic_tunnel_term_cache = {}
23+
self.asic_tunnel_map_cache = {}
24+
25+
def get_all_args(self, ns=""):
26+
req = MatchRequest(db="APPL_DB", table="VXLAN_REMOTE_VNI_TABLE", key_pattern="*", ns=ns)
27+
ret = self.match_engine.fetch(req)
28+
evpns = ret["keys"]
29+
return [key.split(":", 1)[-1] for key in evpns]
30+
31+
def execute(self, params):
32+
self.ret_temp = create_template_dict(dbs=["APPL_DB", "ASIC_DB", "STATE_DB"])
33+
evpn_name = params[Evpn.ARG_NAME]
34+
self.remote_ip = evpn_name.split(':')[-1]
35+
self.remote_vlan = evpn_name.split(':')[0]
36+
self.ns = params["namespace"]
37+
self.init_evpn_appl_info(evpn_name)
38+
self.init_asic_evpn_info()
39+
self.init_asic_evpn_map_info()
40+
self.init_asic_evpn_term_info()
41+
self.init_state_evpn_info(evpn_name)
42+
return self.ret_temp
43+
44+
def add_to_ret_template(self, table, db, keys, err):
45+
if not err and keys:
46+
self.ret_temp[db]["keys"].extend(keys)
47+
return True
48+
else:
49+
self.ret_temp[db]["tables_not_found"].extend([table])
50+
return False
51+
52+
def init_evpn_appl_info(self, evpn_name):
53+
req = MatchRequest(db="APPL_DB", table="VXLAN_REMOTE_VNI_TABLE", key_pattern=evpn_name, ns=self.ns)
54+
ret = self.match_engine.fetch(req)
55+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
56+
57+
def init_state_evpn_info(self, evpn_name):
58+
state_key = "EVPN_" + self.remote_ip
59+
req = MatchRequest(db="STATE_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=state_key, ns=self.ns)
60+
ret = self.match_engine.fetch(req)
61+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
62+
63+
def init_asic_evpn_info(self):
64+
if not self.remote_ip:
65+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL")
66+
return None
67+
if self.remote_ip in self.asic_tunnel_cache:
68+
ret = self.asic_tunnel_cache[self.remote_ip]
69+
else:
70+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL",
71+
field="SAI_TUNNEL_ATTR_ENCAP_DST_IP", value=self.remote_ip, ns=self.ns,
72+
return_fields=["SAI_TUNNEL_ATTR_TYPE", "SAI_TUNNEL_ATTR_ENCAP_MAPPERS",
73+
"SAI_TUNNEL_ATTR_DECAP_MAPPERS"])
74+
ret = self.match_engine.fetch(req)
75+
self.asic_tunnel_cache[self.remote_ip] = ret
76+
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_ATTR_TYPE"] == "SAI_TUNNEL_TYPE_VXLAN"]
77+
if ret["keys"]:
78+
asic_key = ret["keys"][0]
79+
self.tunnel_obj = asic_key.replace("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL:", "")
80+
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"]:
81+
self.encap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"].split(':', 1)[-1].split(',')
82+
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"]:
83+
self.decap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"].split(':', 1)[-1].split(',')
84+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
85+
86+
def init_asic_evpn_term_info(self):
87+
if not self.tunnel_obj:
88+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY")
89+
return None
90+
if self.tunnel_obj in self.asic_tunnel_term_cache:
91+
ret = self.asic_tunnel_term_cache[self.tunnel_obj]
92+
else:
93+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY",
94+
field="SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID", value=self.tunnel_obj, ns=self.ns)
95+
ret = self.match_engine.fetch(req)
96+
self.asic_tunnel_term_cache[self.tunnel_obj] = ret
97+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
98+
99+
def init_asic_evpn_map_info(self):
100+
if not (self.encap_mappers or self.decap_mappers):
101+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
102+
return None
103+
for key in self.encap_mappers:
104+
if key in self.asic_tunnel_map_cache:
105+
ret = self.asic_tunnel_map_cache[key]
106+
else:
107+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
108+
key_pattern=key, ns=self.ns)
109+
ret = self.match_engine.fetch(req)
110+
self.asic_tunnel_map_cache[key] = ret
111+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
112+
for key in self.decap_mappers:
113+
if key in self.asic_tunnel_map_cache:
114+
ret = self.asic_tunnel_map_cache[key]
115+
else:
116+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
117+
key_pattern=key, ns=self.ns)
118+
ret = self.match_engine.fetch(req)
119+
self.asic_tunnel_map_cache[key] = ret
120+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

dump/plugins/vxlan_tunnel.py

+110
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
from dump.match_infra import MatchRequest
2+
from dump.helper import create_template_dict
3+
from .executor import Executor
4+
5+
6+
class Vxlan_tunnel(Executor):
7+
"""
8+
Debug Dump Plugin for Vxlan Tunnel Module
9+
"""
10+
ARG_NAME = "vxlan_tunnel_name"
11+
12+
def __init__(self, match_engine=None):
13+
super().__init__(match_engine)
14+
self.ret_temp = {}
15+
self.ns = ''
16+
self.src_ip = ''
17+
self.dst_ip = ''
18+
self.tunnel_obj = ''
19+
self.encap_mappers = []
20+
self.decap_mappers = []
21+
22+
def get_all_args(self, ns=""):
23+
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL", key_pattern="*", ns=ns)
24+
ret = self.match_engine.fetch(req)
25+
vxlan_tunnels = ret["keys"]
26+
return [key.split("|")[-1] for key in vxlan_tunnels]
27+
28+
def execute(self, params):
29+
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB", "STATE_DB"])
30+
vxlan_tunnel_name = params[Vxlan_tunnel.ARG_NAME]
31+
self.ns = params["namespace"]
32+
self.init_vxlan_tunnel_config_info(vxlan_tunnel_name)
33+
self.init_vxlan_tunnel_appl_info(vxlan_tunnel_name)
34+
self.init_asic_vxlan_tunnel_info()
35+
self.init_asic_vxlan_tunnel_map_info()
36+
self.init_asic_vxlan_tunnel_term_info()
37+
self.init_state_vxlan_tunnel_info(vxlan_tunnel_name)
38+
return self.ret_temp
39+
40+
def add_to_ret_template(self, table, db, keys, err):
41+
if not err and keys:
42+
self.ret_temp[db]["keys"].extend(keys)
43+
return True
44+
else:
45+
self.ret_temp[db]["tables_not_found"].extend([table])
46+
return False
47+
48+
def init_vxlan_tunnel_config_info(self, vxlan_tunnel_name):
49+
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL", key_pattern=vxlan_tunnel_name, ns=self.ns)
50+
ret = self.match_engine.fetch(req)
51+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
52+
53+
def init_vxlan_tunnel_appl_info(self, vxlan_tunnel_name):
54+
req = MatchRequest(db="APPL_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=vxlan_tunnel_name, ns=self.ns,
55+
return_fields=["src_ip", "dst_ip"])
56+
ret = self.match_engine.fetch(req)
57+
if ret["keys"]:
58+
app_key = ret["keys"][0]
59+
self.src_ip = ret["return_values"][app_key]["src_ip"]
60+
self.dst_ip = ret["return_values"][app_key]["dst_ip"]
61+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
62+
63+
def init_state_vxlan_tunnel_info(self, vxlan_tunnel_name):
64+
req = MatchRequest(db="STATE_DB", table="VXLAN_TUNNEL_TABLE", key_pattern=vxlan_tunnel_name, ns=self.ns)
65+
ret = self.match_engine.fetch(req)
66+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
67+
68+
def init_asic_vxlan_tunnel_info(self):
69+
if not self.src_ip:
70+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL")
71+
return None
72+
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,
73+
return_fields=["SAI_TUNNEL_ATTR_TYPE", "SAI_TUNNEL_ATTR_ENCAP_DST_IP",
74+
"SAI_TUNNEL_ATTR_ENCAP_MAPPERS", "SAI_TUNNEL_ATTR_DECAP_MAPPERS"])
75+
ret = self.match_engine.fetch(req)
76+
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_ATTR_TYPE"] == "SAI_TUNNEL_TYPE_VXLAN"]
77+
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
78+
ret["return_values"][x]["SAI_TUNNEL_ATTR_ENCAP_DST_IP"] == self.dst_ip]
79+
if ret["keys"]:
80+
asic_key = ret["keys"][0]
81+
self.tunnel_obj = asic_key.replace("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL:", "")
82+
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"]:
83+
self.encap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_ENCAP_MAPPERS"].split(':', 1)[-1].split(',')
84+
if ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"]:
85+
self.decap_mappers = ret["return_values"][asic_key]["SAI_TUNNEL_ATTR_DECAP_MAPPERS"].split(':', 1)[-1].split(',')
86+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
87+
88+
def init_asic_vxlan_tunnel_term_info(self):
89+
if not self.tunnel_obj:
90+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY")
91+
return None
92+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_TERM_TABLE_ENTRY",
93+
field="SAI_TUNNEL_TERM_TABLE_ENTRY_ATTR_ACTION_TUNNEL_ID", value=self.tunnel_obj, ns=self.ns)
94+
ret = self.match_engine.fetch(req)
95+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
96+
97+
def init_asic_vxlan_tunnel_map_info(self):
98+
if not (self.encap_mappers or self.decap_mappers):
99+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
100+
return None
101+
for key in self.encap_mappers:
102+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
103+
key_pattern=key, ns=self.ns)
104+
ret = self.match_engine.fetch(req)
105+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
106+
for key in self.decap_mappers:
107+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
108+
key_pattern=key, ns=self.ns)
109+
ret = self.match_engine.fetch(req)
110+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

dump/plugins/vxlan_tunnel_map.py

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
from dump.match_infra import MatchRequest
2+
from dump.helper import create_template_dict
3+
from .executor import Executor
4+
5+
6+
class Vxlan_tunnel_map(Executor):
7+
"""
8+
Debug Dump Plugin for Vxlan Tunnel Map Module
9+
"""
10+
ARG_NAME = "vxlan_tunnel_map_name"
11+
12+
def __init__(self, match_engine=None):
13+
super().__init__(match_engine)
14+
self.ret_temp = {}
15+
self.ns = ''
16+
self.vlan = ''
17+
self.vni = ''
18+
self.tunnel_map_obj = ''
19+
self.encap_mappers = []
20+
self.decap_mappers = []
21+
22+
def get_all_args(self, ns=""):
23+
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL_MAP", key_pattern="*", ns=ns)
24+
ret = self.match_engine.fetch(req)
25+
vxlan_tunnel_maps = ret["keys"]
26+
return [key.split("|", 1)[-1] for key in vxlan_tunnel_maps]
27+
28+
def execute(self, params):
29+
self.ret_temp = create_template_dict(dbs=["CONFIG_DB", "APPL_DB", "ASIC_DB"])
30+
vxlan_tunnel_map_name = params[Vxlan_tunnel_map.ARG_NAME]
31+
self.ns = params["namespace"]
32+
self.init_vxlan_tunnel_map_config_info(vxlan_tunnel_map_name)
33+
self.init_vxlan_tunnel_map_appl_info(vxlan_tunnel_map_name)
34+
self.init_asic_vxlan_tunnel_map_entry_info()
35+
self.init_asic_vxlan_tunnel_map_info()
36+
return self.ret_temp
37+
38+
def add_to_ret_template(self, table, db, keys, err):
39+
if not err and keys:
40+
self.ret_temp[db]["keys"].extend(keys)
41+
return True
42+
else:
43+
self.ret_temp[db]["tables_not_found"].extend([table])
44+
return False
45+
46+
def init_vxlan_tunnel_map_config_info(self, vxlan_tunnel_map_name):
47+
req = MatchRequest(db="CONFIG_DB", table="VXLAN_TUNNEL_MAP", key_pattern=vxlan_tunnel_map_name, ns=self.ns,
48+
return_fields=["vlan", "vni"])
49+
ret = self.match_engine.fetch(req)
50+
if ret["keys"]:
51+
cfg_key = ret["keys"][0]
52+
self.vlan = ret["return_values"][cfg_key]["vlan"].replace("Vlan", "")
53+
self.vni = ret["return_values"][cfg_key]["vni"]
54+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
55+
56+
def init_vxlan_tunnel_map_appl_info(self, vxlan_tunnel_map_name):
57+
app_vxlan_tunnel_map_name = vxlan_tunnel_map_name.replace('|', ':')
58+
req = MatchRequest(db="APPL_DB", table="VXLAN_TUNNEL_MAP_TABLE", key_pattern=app_vxlan_tunnel_map_name, ns=self.ns)
59+
ret = self.match_engine.fetch(req)
60+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
61+
62+
def init_asic_vxlan_tunnel_map_entry_info(self):
63+
if not self.vlan:
64+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP_ENTRY")
65+
return None
66+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP_ENTRY",
67+
field="SAI_TUNNEL_MAP_ENTRY_ATTR_VLAN_ID_VALUE", value=self.vlan, ns=self.ns,
68+
return_fields=["SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP_TYPE",
69+
"SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY",
70+
"SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP"])
71+
ret = self.match_engine.fetch(req)
72+
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"]
73+
ret["keys"] = [x for x in ret["keys"] if ret["return_values"][x]["SAI_TUNNEL_MAP_ENTRY_ATTR_VNI_ID_KEY"] == self.vni]
74+
if ret["keys"]:
75+
self.tunnel_map_obj = ret["return_values"][ret["keys"][0]]["SAI_TUNNEL_MAP_ENTRY_ATTR_TUNNEL_MAP"]
76+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])
77+
78+
def init_asic_vxlan_tunnel_map_info(self):
79+
if not self.tunnel_map_obj:
80+
self.ret_temp["ASIC_DB"]["tables_not_found"].append("ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP")
81+
return None
82+
req = MatchRequest(db="ASIC_DB", table="ASIC_STATE:SAI_OBJECT_TYPE_TUNNEL_MAP",
83+
key_pattern=self.tunnel_map_obj, value=self.vlan, ns=self.ns)
84+
ret = self.match_engine.fetch(req)
85+
self.add_to_ret_template(req.table, req.db, ret["keys"], ret["error"])

tests/dump_input/vxlan/appl_db.json

+34
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
{
2+
"VXLAN_TUNNEL_MAP_TABLE:vtep_1336:map_1336_Vlan2345": {
3+
"vlan": "Vlan2345",
4+
"vni": "1336"
5+
},
6+
"VXLAN_TUNNEL_MAP_TABLE:vtep_1336:map_1337_Vlan2346": {
7+
"vlan": "Vlan2346",
8+
"vni": "1337"
9+
},
10+
"VXLAN_TUNNEL_TABLE:vtep_1111": {
11+
"src_ip": "10.1.0.31"
12+
},
13+
"VXLAN_TUNNEL_TABLE:vtep_1336": {
14+
"src_ip": "10.1.0.32"
15+
},
16+
"VXLAN_TUNNEL_TABLE:vtep_2312": {
17+
"src_ip": "10.1.0.33"
18+
},
19+
"VXLAN_TUNNEL_TABLE:vtep_1000": {
20+
"src_ip": "10.1.0.34"
21+
},
22+
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.32": {
23+
"vni": "1336"
24+
},
25+
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.33": {
26+
"vni": "1336"
27+
},
28+
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.34": {
29+
"vni": "1336"
30+
},
31+
"VXLAN_REMOTE_VNI_TABLE:Vlan2345:11.1.0.35": {
32+
"vni": "1336"
33+
}
34+
}

0 commit comments

Comments
 (0)