Skip to content

Commit

Permalink
Added logic to create sairedis.rec aliases (#223)
Browse files Browse the repository at this point in the history
Signed-off-by: Andriy Kokhan <[email protected]>
  • Loading branch information
andriy-kokhan authored Oct 27, 2023
1 parent af1b15d commit f225c9c
Showing 1 changed file with 71 additions and 5 deletions.
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

0 comments on commit f225c9c

Please sign in to comment.