Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added logic to create sairedis.rec aliases #223

Merged
merged 3 commits into from
Oct 27, 2023
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 71 additions & 5 deletions common/sai.py
Original file line number Diff line number Diff line change
Expand Up @@ -180,7 +180,6 @@ def __init__(self, cfg):
self.sku = cfg.get("sku")
self.asic_dir = cfg.get("asic_dir")
self._switch_oid = None
self.cache = {}
self.rec2vid = {}

cfg["client"]["config"]["saivs"] = self.libsaivs
Expand Down Expand Up @@ -219,7 +218,7 @@ def cleanup(self):
if dut:
dut.cleanup()
self.sai_client.cleanup()
self.cache = {}
self.command_processor.objects_registry = {}
self.rec2vid = {}

def set_loglevel(self, sai_api, loglevel):
Expand Down Expand Up @@ -485,7 +484,14 @@ def objects_discovery(self):
["SAI_SWITCH_ATTR_PORT_LIST", self.make_list(port_num, "oid:0x0")]).oids()
for idx, oid in enumerate(port_oids):
self.create_alias(f"PORT_{idx}", 'SAI_OBJECT_TYPE_PORT', oid)

status, data = self.get(oid, ["SAI_PORT_ATTR_TYPE"], False)
if status == "SAI_STATUS_SUCCESS" and data.value() != "SAI_PORT_TYPE_LOGICAL":
continue
status, data = self.get(oid, ["SAI_PORT_ATTR_HW_LANE_LIST"], False)
if status != "SAI_STATUS_SUCCESS":
continue
# Create port alias by lane
self.create_alias(f"port{data.to_list()[0]}", 'SAI_OBJECT_TYPE_PORT', oid)

status, data = self.get(dot1q_br_oid, ["SAI_BRIDGE_ATTR_PORT_LIST", "1:oid:0x0"], False)
bport_num = data.uint32()
Expand All @@ -497,6 +503,56 @@ def objects_discovery(self):
for idx, oid in enumerate(dot1q_bp_oids):
self.create_alias(f"BRIDGE_PORT_{idx}", 'SAI_OBJECT_TYPE_BRIDGE_PORT', oid)

def get_attr_by_name(self, name, attrs):
for i in range(0, len(attrs), 2):
if attrs[i] == name:
return attrs[i + 1]
return None

def get_alias_by_key(self, obj_key):
for key, value in self.command_processor.objects_registry.items():
if (value["oid"] == obj_key or value["key"] == obj_key) and key[0].islower():
return key
return ""

def get_key_by_alias(self, alias):
return self.command_processor.objects_registry.get(alias)

def create_rec_alias(self, obj_type, attrs, key=None):
if obj_type == "SAI_OBJECT_TYPE_SWITCH":
self.create_alias(f"switch", obj_type, key)
# Discover objects implicitly created
# during switch object creation
self.objects_discovery()
elif obj_type == "SAI_OBJECT_TYPE_PORT":
lanes = self.get_attr_by_name("SAI_PORT_ATTR_HW_LANE_LIST", attrs).split(':')[1].split(',')
# Create port alias by lane
self.create_alias(f"port{lanes[0]}", obj_type, key)
elif obj_type == "SAI_OBJECT_TYPE_VLAN":
vlan_id = self.get_attr_by_name("SAI_VLAN_ATTR_VLAN_ID", attrs)
self.create_alias(f"vlan{vlan_id}", obj_type, key)
elif obj_type == "SAI_OBJECT_TYPE_ROUTER_INTERFACE":
port_oid = self.get_attr_by_name("SAI_ROUTER_INTERFACE_ATTR_PORT_ID", attrs)
if port_oid:
port_alias = self.get_alias_by_key(port_oid)
self.create_alias(f"rif_{port_alias}", obj_type, key)
else:
vlan_oid = self.get_attr_by_name("SAI_ROUTER_INTERFACE_ATTR_VLAN_ID", attrs)
if vlan_oid:
vlan_alias = self.get_alias_by_key(vlan_oid)
self.create_alias(f"rif_vlan{vlan_alias}", obj_type, key)
elif obj_type == "SAI_OBJECT_TYPE_ROUTE_ENTRY":
nh_oid = self.get_attr_by_name("SAI_ROUTE_ENTRY_ATTR_NEXT_HOP_ID", attrs)
if nh_oid and nh_oid != "oid:0x0":
nh_type = self.vid_to_type(nh_oid)
if nh_type == "SAI_OBJECT_TYPE_ROUTER_INTERFACE":
# Directly connected route
rif_alias = self.get_alias_by_key(nh_oid)
self.create_alias(f"route_{rif_alias}", obj_type, oid=None, key=key)

def remove_rec_alias(self, obj_key):
self.remove_alias(self.get_alias_by_key(obj_key))

def apply_rec(self, fname):
# Since it's expected that sairedis.rec file contains a full configuration,
# before we start, we must flush both RPC backend (Redis or Thrift server) and NPU state.
Expand All @@ -519,13 +575,17 @@ def apply_rec(self, fname):
if "oid:" in attrs[idx]:
attrs[idx] = self.rec2vid[attrs[idx]]

status, key = self.create(self.__update_key(rec[0], rec[1]), attrs, False)
obj_key = self.__update_key(rec[0], rec[1])
status, key = self.create(obj_key, attrs, False)
if status != "SAI_STATUS_SUCCESS":
continue
if "{" not in key:
key_list = rec[1].split(":", 1)
self.rec2vid[key_list[1]] = key

obj_type = obj_key.split(":")[0]
self.create_rec_alias(obj_type, attrs, key)

elif rec[0] == 'C':
# record = [["action", "sai-object-type"], ["key", "attr1", "attr2"], ..., [key-n", "attr1", "attr2"]]
bulk_keys = []
Expand Down Expand Up @@ -554,6 +614,8 @@ def apply_rec(self, fname):
bulk_attrs.append(attrs)

self.bulk_create(record[0][1], bulk_keys, bulk_attrs)
for idx in range(len(bulk_keys)):
self.create_rec_alias(record[0][1], bulk_attrs[idx], bulk_keys[idx])

elif rec[0] == 's':
data = rec[2].split('=')
Expand Down Expand Up @@ -586,7 +648,9 @@ def apply_rec(self, fname):
self.bulk_set(record[0][1], bulk_keys, bulk_attrs)

elif rec[0] == 'r':
self.remove(self.__update_key(rec[0], rec[1]))
obj_key = self.__update_key(rec[0], rec[1])
self.remove(obj_key)
self.remove_rec_alias(obj_key)

elif rec[0] == 'R':
# record = [["action", "sai-object-type"], ["key"], ..., [key-n"]]
Expand All @@ -604,6 +668,8 @@ def apply_rec(self, fname):
bulk_keys.append(key)

self.bulk_remove(record[0][1], bulk_keys)
for key in bulk_keys:
self.remove_rec_alias(key)

elif rec[0] == 'g':
attrs = []
Expand Down