diff --git a/doc/swss-schema.md b/doc/swss-schema.md index ec28eb6c0f3b..74bfd687b824 100644 --- a/doc/swss-schema.md +++ b/doc/swss-schema.md @@ -233,6 +233,7 @@ and reflects the LAG ports into the redis under: `LAG_TABLE::port` key = ROUTE_TABLE:segment ; SRV6 segment name ; field = value path = STRING ; Comma-separated list of IPV6 prefixes for a SRV6 segment + type = STRING ; SRV6 segment list type like "insert", "encaps.red"; If not provided, default type will be "encaps.red" --------------------------------------------- ### SRV6_MY_SID_TABLE diff --git a/orchagent/srv6orch.cpp b/orchagent/srv6orch.cpp index 3d81163b2a2d..7aced45d27f8 100644 --- a/orchagent/srv6orch.cpp +++ b/orchagent/srv6orch.cpp @@ -52,6 +52,14 @@ const map end_flavor_map = {"ua", SAI_MY_SID_ENTRY_ENDPOINT_BEHAVIOR_FLAVOR_PSP_AND_USD} }; +const map sidlist_type_map = +{ + {"insert", SAI_SRV6_SIDLIST_TYPE_INSERT}, + {"insert.red", SAI_SRV6_SIDLIST_TYPE_INSERT_RED}, + {"encaps", SAI_SRV6_SIDLIST_TYPE_ENCAPS}, + {"encaps.red", SAI_SRV6_SIDLIST_TYPE_ENCAPS_RED} +}; + void Srv6Orch::srv6TunnelUpdateNexthops(const string srv6_source, const NextHopKey nhkey, bool insert) { if (insert) @@ -267,7 +275,7 @@ bool Srv6Orch::srv6Nexthops(const NextHopGroupKey &nhgKey, sai_object_id_t &next return true; } -bool Srv6Orch::createUpdateSidList(const string sid_name, const string sid_list) +bool Srv6Orch::createUpdateSidList(const string sid_name, const string sid_list, const string sidlist_type) { SWSS_LOG_ENTER(); bool exists = (sid_table_.find(sid_name) != sid_table_.end()); @@ -303,7 +311,16 @@ bool Srv6Orch::createUpdateSidList(const string sid_name, const string sid_list) attributes.push_back(attr); attr.id = SAI_SRV6_SIDLIST_ATTR_TYPE; - attr.value.s32 = SAI_SRV6_SIDLIST_TYPE_ENCAPS_RED; + if (sidlist_type_map.find(sidlist_type) == sidlist_type_map.end()) + { + SWSS_LOG_INFO("Use default sidlist type: ENCAPS_RED"); + attr.value.s32 = SAI_SRV6_SIDLIST_TYPE_ENCAPS_RED; + } + else + { + SWSS_LOG_INFO("sidlist type: %s", sidlist_type.c_str()); + attr.value.s32 = sidlist_type_map.at(sidlist_type); + } attributes.push_back(attr); status = sai_srv6_api->create_srv6_sidlist(&segment_oid, gSwitchId, (uint32_t) attributes.size(), attributes.data()); if (status != SAI_STATUS_SUCCESS) @@ -365,7 +382,7 @@ void Srv6Orch::doTaskSidTable(const KeyOpFieldsValuesTuple & tuple) SWSS_LOG_ENTER(); string sid_name = kfvKey(tuple); string op = kfvOp(tuple); - string sid_list; + string sid_list, sidlist_type; for (auto i : kfvFieldsValues(tuple)) { @@ -373,10 +390,14 @@ void Srv6Orch::doTaskSidTable(const KeyOpFieldsValuesTuple & tuple) { sid_list = fvValue(i); } + if (fvField(i) == "type") + { + sidlist_type = fvValue(i); + } } if (op == SET_COMMAND) { - if (!createUpdateSidList(sid_name, sid_list)) + if (!createUpdateSidList(sid_name, sid_list, sidlist_type)) { SWSS_LOG_ERROR("Failed to process sid %s", sid_name.c_str()); } diff --git a/orchagent/srv6orch.h b/orchagent/srv6orch.h index 989737a99842..e24f5e00f5de 100644 --- a/orchagent/srv6orch.h +++ b/orchagent/srv6orch.h @@ -76,7 +76,7 @@ class Srv6Orch : public Orch void doTask(Consumer &consumer); void doTaskSidTable(const KeyOpFieldsValuesTuple &tuple); void doTaskMySidTable(const KeyOpFieldsValuesTuple &tuple); - bool createUpdateSidList(const string seg_name, const string ips); + bool createUpdateSidList(const string seg_name, const string ips, const string sidlist_type); bool deleteSidList(const string seg_name); bool createSrv6Tunnel(const string srv6_source); bool createSrv6Nexthop(const NextHopKey &nh); diff --git a/tests/test_srv6.py b/tests/test_srv6.py index dddb10153bc5..29d498780fc6 100644 --- a/tests/test_srv6.py +++ b/tests/test_srv6.py @@ -121,11 +121,14 @@ def setup_db(self, dvs): self.adb = dvs.get_asic_db() self.cdb = dvs.get_config_db() - def create_sidlist(self, segname, ips): + def create_sidlist(self, segname, ips, type=None): table = "ASIC_STATE:SAI_OBJECT_TYPE_SRV6_SIDLIST" existed_entries = get_exist_entries(self.adb.db_connection, table) - fvs=swsscommon.FieldValuePairs([('path', ips)]) + if type is None: + fvs=swsscommon.FieldValuePairs([('path', ips)]) + else: + fvs=swsscommon.FieldValuePairs([('path', ips), ('type', type)]) segtbl = swsscommon.ProducerStateTable(self.pdb.db_connection, "SRV6_SID_LIST_TABLE") segtbl.set(segname, fvs) @@ -239,9 +242,30 @@ def test_srv6(self, dvs, testlog): # create 2nd seg lists - self.create_sidlist('seg2', 'baba:2002:10::,baba:2002:20::') - # create 3rd seg lists - self.create_sidlist('seg3', 'baba:2003:10::,baba:2003:20::') + sidlist_id = self.create_sidlist('seg2', 'baba:2002:10::,baba:2002:20::', 'insert.red') + + # check ASIC SAI_OBJECT_TYPE_SRV6_SIDLIST database + tbl = swsscommon.Table(self.adb.db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_SRV6_SIDLIST") + (status, fvs) = tbl.get(sidlist_id) + assert status == True + for fv in fvs: + if fv[0] == "SAI_SRV6_SIDLIST_ATTR_SEGMENT_LIST": + assert fv[1] == "2:baba:2002:10::,baba:2002:20::" + elif fv[0] == "SAI_SRV6_SIDLIST_ATTR_TYPE": + assert fv[1] == "SAI_SRV6_SIDLIST_TYPE_INSERT_RED" + + # create 3rd seg lists with unsupported or wrong naming of sid list type, for this case, it will use default type: ENCAPS_RED + sidlist_id = self.create_sidlist('seg3', 'baba:2003:10::,baba:2003:20::', 'reduced') + + # check ASIC SAI_OBJECT_TYPE_SRV6_SIDLIST database + tbl = swsscommon.Table(self.adb.db_connection, "ASIC_STATE:SAI_OBJECT_TYPE_SRV6_SIDLIST") + (status, fvs) = tbl.get(sidlist_id) + assert status == True + for fv in fvs: + if fv[0] == "SAI_SRV6_SIDLIST_ATTR_SEGMENT_LIST": + assert fv[1] == "2:baba:2003:10::,baba:2003:20::" + elif fv[0] == "SAI_SRV6_SIDLIST_ATTR_TYPE": + assert fv[1] == "SAI_SRV6_SIDLIST_TYPE_ENCAPS_RED" # create 2nd v4 route with single sidlists self.create_srv6_route('20.20.20.21/32','seg2','1001:2000::1')