blob: b8053f41dd4800000b706fc60743c153c629dd9f [file] [log] [blame]
Abhilash S.L7f17e402019-03-15 17:40:41 +05301/*
Joey Armstrong11f5a572024-01-12 19:11:32 -05002 * Copyright 2019-2024 Open Networking Foundation (ONF) and the ONF Contributors
Abhilash S.L7f17e402019-03-15 17:40:41 +05303
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Joey Armstrong3f0e2422023-07-05 18:25:41 -040017// Package resourcemanager provides the utility for managing resources
manikkaraj kbf256be2019-03-25 00:13:48 +053018package resourcemanager
Abhilash S.L7f17e402019-03-15 17:40:41 +053019
20import (
npujarec5762e2020-01-01 14:08:48 +053021 "context"
Girish Gowdru0c588b22019-04-23 23:24:56 -040022 "encoding/json"
23 "errors"
24 "fmt"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070025 "strings"
Girish Gowdra38d533d2020-03-30 20:38:51 -070026 "sync"
Neha Sharmacc656962020-04-14 14:26:11 +000027 "time"
Abhilash S.L7f17e402019-03-15 17:40:41 +053028
khenaidoo106c61a2021-08-11 18:05:46 -040029 tp "github.com/opencord/voltha-lib-go/v7/pkg/techprofile"
30
31 "github.com/opencord/voltha-lib-go/v7/pkg/db"
32 "github.com/opencord/voltha-lib-go/v7/pkg/db/kvstore"
33 "github.com/opencord/voltha-lib-go/v7/pkg/log"
34 ponrmgr "github.com/opencord/voltha-lib-go/v7/pkg/ponresourcemanager"
35 ofp "github.com/opencord/voltha-protos/v5/go/openflow_13"
36 "github.com/opencord/voltha-protos/v5/go/openolt"
Abhilash S.L7f17e402019-03-15 17:40:41 +053037)
38
salmansiddiqui7ac62132019-08-22 03:58:50 +000039const (
40 // KvstoreTimeout specifies the time out for KV Store Connection
Neha Sharmacc656962020-04-14 14:26:11 +000041 KvstoreTimeout = 5 * time.Second
Matteo Scandolodfa7a972020-11-06 13:03:40 -080042 // BasePathKvStore - <pathPrefix>/openolt/<device_id>
43 BasePathKvStore = "%s/openolt/{%s}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070044 // tpIDPathSuffix - <(pon_id, onu_id, uni_id)>/tp_id
45 tpIDPathSuffix = "{%d,%d,%d}/tp_id"
Gamze Abakafee36392019-10-03 11:17:24 +000046 //MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
47 MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
Girish Gowdra950326e2021-11-05 12:43:24 -070048
49 // OnuPacketInPathPrefix - path prefix where ONU packet-in vlanID/PCP is stored
Girish Gowdraa09aeab2020-09-14 16:30:52 -070050 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}
Girish Gowdra950326e2021-11-05 12:43:24 -070051 OnuPacketInPathPrefix = "onu_packetin/{%d,%d,%d}"
52 // OnuPacketInPath path on the kvstore to store packetin gemport,which will be used for packetin, packetout
Girish Gowdraa09aeab2020-09-14 16:30:52 -070053 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}/{<vlanId>,<priority>}
Girish Gowdra950326e2021-11-05 12:43:24 -070054 OnuPacketInPath = OnuPacketInPathPrefix + "/{%d,%d}"
55
56 //FlowIDsForGemPathPrefix format: flowids_for_gem/<intfid>
57 FlowIDsForGemPathPrefix = "flowids_per_gem/{%d}"
58 //FlowIDsForGem flowids_for_gem/<intfid>/<gemport-id>
59 FlowIDsForGem = FlowIDsForGemPathPrefix + "/{%d}"
60
Esin Karamanccb714b2019-11-29 15:02:06 +000061 //McastQueuesForIntf multicast queues for pon interfaces
62 McastQueuesForIntf = "mcast_qs_for_int"
63 //FlowGroup flow_groups/<flow_group_id>
64 // A group is stored under this path on the KV store after it has been installed to the device.
65 // It should also be deleted after it has been removed from the device accordingly.
66 FlowGroup = "flow_groups/{%d}"
67 //FlowGroupCached flow_groups_cached/<flow_group_id>
68 // When a group add request received, we create the group without setting any members to it since we cannot
69 // set any members to a group until it is associated with a multicast flow. It is a BAL limitation.
70 // When the related multicast flow has been created we perform set members operation for the group.
71 // That is why we need to keep the members of a group until the multicast flow creation request comes.
72 // We preserve the groups under "FlowGroupsCached" directory in the KV store temporarily. Having set members,
73 // we remove the group from the cached group store.
74 FlowGroupCached = "flow_groups_cached/{%d}"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070075
76 //FlowIDPath - Path on the KV store for storing list of Flow IDs for a given subscriber
77 //Format: BasePathKvStore/<(pon_intf_id, onu_id, uni_id)>/flow_ids
78 FlowIDPath = "{%s}/flow_ids"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070079
Girish Gowdra950326e2021-11-05 12:43:24 -070080 //OnuGemInfoPathPathPrefix format: onu_gem_info/<intfid>
81 OnuGemInfoPathPathPrefix = "onu_gem_info/{%d}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070082 //OnuGemInfoPath is path on the kvstore to store onugem info map
Girish Gowdra950326e2021-11-05 12:43:24 -070083 //format: onu_gem_info/<intfid>/<onu_id>
84 OnuGemInfoPath = OnuGemInfoPathPathPrefix + "/{%d}"
yasin saplid0566272021-12-21 09:10:30 +000085
86 // NNI uint32 version of -1 which represents the NNI port
87 NNI = 4294967295
salmansiddiqui7ac62132019-08-22 03:58:50 +000088)
Abhilash S.L7f17e402019-03-15 17:40:41 +053089
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090// FlowInfo holds the flow information
Abhilash S.L8ee90712019-04-29 16:24:22 +053091type FlowInfo struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -070092 Flow *openolt.Flow
93 IsSymmtricFlow bool
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053094}
95
96// OnuGemInfo holds onu information along with gem port list and uni port list
97type OnuGemInfo struct {
98 OnuID uint32
99 SerialNumber string
100 IntfID uint32
101 GemPorts []uint32
102 UniPorts []uint32
103}
104
105// PacketInInfoKey is the key for packet in gemport
106type PacketInInfoKey struct {
107 IntfID uint32
108 OnuID uint32
109 LogicalPort uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000110 VlanID uint16
111 Priority uint8
Abhilash S.L8ee90712019-04-29 16:24:22 +0530112}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113
Esin Karamanccb714b2019-11-29 15:02:06 +0000114// GroupInfo holds group information
115type GroupInfo struct {
116 GroupID uint32
117 OutPorts []uint32
118}
119
Girish Gowdraa482f272021-03-24 23:04:19 -0700120// MeterInfo store meter information at path <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
121type MeterInfo struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700122 RefCnt uint8 // number of flow references for this meter. When RefCnt is 0, the MeterInfo should be deleted.
123 MeterID uint32
Girish Gowdraa482f272021-03-24 23:04:19 -0700124}
125
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700126// OpenOltResourceMgr holds resource related information as provided below for each field
Abhilash S.L7f17e402019-03-15 17:40:41 +0530127type OpenOltResourceMgr struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700128 PonIntfID uint32
Neha Sharma3f221ae2020-04-29 19:02:12 +0000129 DeviceID string // OLT device id
130 Address string // Host and port of the kv store to connect to
131 Args string // args
132 KVStore *db.Backend // backend kv store connection handle
133 DeviceType string
134 DevInfo *openolt.DeviceInfo // device information
Girish Gowdru0c588b22019-04-23 23:24:56 -0400135 // array of pon resource managers per interface technology
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700136 PonRsrMgr *ponrmgr.PONResourceManager
Girish Gowdra38d533d2020-03-30 20:38:51 -0700137
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700138 // Local maps used for write-through-cache - start
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700139 allocIDsForOnu map[string][]uint32
140 allocIDsForOnuLock sync.RWMutex
141
142 gemPortIDsForOnu map[string][]uint32
143 gemPortIDsForOnuLock sync.RWMutex
144
145 techProfileIDsForOnu map[string][]uint32
146 techProfileIDsForOnuLock sync.RWMutex
147
148 meterInfoForOnu map[string]*MeterInfo
149 meterInfoForOnuLock sync.RWMutex
150
151 onuGemInfo map[string]*OnuGemInfo
152 onuGemInfoLock sync.RWMutex
153
154 gemPortForPacketInInfo map[string]uint32
155 gemPortForPacketInInfoLock sync.RWMutex
156
157 flowIDsForGem map[uint32][]uint64
158 flowIDsForGemLock sync.RWMutex
159
160 mcastQueueForIntf map[uint32][]uint32
161 mcastQueueForIntfLock sync.RWMutex
162 mcastQueueForIntfLoadedFromKvStore bool
163
164 groupInfo map[string]*GroupInfo
165 groupInfoLock sync.RWMutex
166 // Local maps used for write-through-cache - end
Girish Gowdra4c3d4602021-07-22 16:33:37 -0700167
Girish Gowdra76a1b092021-07-28 10:07:04 -0700168 TechprofileRef tp.TechProfileIf
Abhilash S.L7f17e402019-03-15 17:40:41 +0530169}
170
Neha Sharma96b7bf22020-06-15 10:37:32 +0000171func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
172 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400173 switch storeType {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400174 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000175 return kvstore.NewEtcdClient(ctx, address, timeout, log.FatalLevel)
Abhay Kumar9bcfeb22024-07-12 09:14:25 +0530176 case "redis":
177 return kvstore.NewRedisClient(address, timeout, false)
178 case "redis-sentinel":
179 return kvstore.NewRedisClient(address, timeout, true)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400180 }
181 return nil, errors.New("unsupported-kv-store")
Abhilash S.L7f17e402019-03-15 17:40:41 +0530182}
183
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700184// SetKVClient sets the KV client and return a kv backend
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800185func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400186 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
187 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000188 kvClient, err := newKVClient(ctx, backend, addr, KvstoreTimeout)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400189 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000190 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400191 return nil
192 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700193 // return db.NewBackend(ctx, backend, addr, KvstoreTimeout, fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID))
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700194
sbarbaria8910ba2019-11-05 10:12:23 -0500195 kvbackend := &db.Backend{
Girish Gowdru0c588b22019-04-23 23:24:56 -0400196 Client: kvClient,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700197 StoreType: backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000198 Address: addr,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700199 Timeout: KvstoreTimeout,
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800200 PathPrefix: fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID)}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530201
Girish Gowdru0c588b22019-04-23 23:24:56 -0400202 return kvbackend
Abhilash S.L7f17e402019-03-15 17:40:41 +0530203}
204
Holger Hildebrandt143b5be2023-02-10 08:28:15 +0000205// CloseKVClient closes open KV clients
206func (rsrcMgr *OpenOltResourceMgr) CloseKVClient(ctx context.Context) {
207 if rsrcMgr.KVStore != nil {
208 rsrcMgr.KVStore.Client.Close(ctx)
209 rsrcMgr.KVStore = nil
210 }
211 if rsrcMgr.PonRsrMgr != nil {
212 rsrcMgr.PonRsrMgr.CloseKVClient(ctx)
213 }
214}
215
Gamze Abakafee36392019-10-03 11:17:24 +0000216// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700217// instances according to technology. Initializes the default resource ranges for all
218// the resources.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700219func NewResourceMgr(ctx context.Context, PonIntfID uint32, deviceID string, KVStoreAddress string, kvStoreType string, deviceType string, devInfo *openolt.DeviceInfo, basePathKvStore string) *OpenOltResourceMgr {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400220 var ResourceMgr OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700221 logger.Debugf(ctx, "Init new resource manager , ponIf: %v, address: %s, device-id: %s", PonIntfID, KVStoreAddress, deviceID)
222 ResourceMgr.PonIntfID = PonIntfID
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700223 ResourceMgr.DeviceID = deviceID
Neha Sharma3f221ae2020-04-29 19:02:12 +0000224 ResourceMgr.Address = KVStoreAddress
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700225 ResourceMgr.DeviceType = deviceType
226 ResourceMgr.DevInfo = devInfo
Abhilash S.L7f17e402019-03-15 17:40:41 +0530227
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700228 Backend := kvStoreType
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800229 ResourceMgr.KVStore = SetKVClient(ctx, Backend, ResourceMgr.Address, deviceID, basePathKvStore)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400230 if ResourceMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000231 logger.Error(ctx, "Failed to setup KV store")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400232 }
Girish Gowdra38d533d2020-03-30 20:38:51 -0700233
Girish Gowdru0c588b22019-04-23 23:24:56 -0400234 // TODO self.args = registry('main').get_args()
Abhilash S.L7f17e402019-03-15 17:40:41 +0530235
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700236 // Create a separate Resource Manager instance for each range. This assumes that
Girish Gowdru0c588b22019-04-23 23:24:56 -0400237 // each technology is represented by only a single range
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700238 for _, TechRange := range devInfo.Ranges {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700239 for _, intfID := range TechRange.IntfIds {
240 if intfID == PonIntfID {
241 technology := TechRange.Technology
242 logger.Debugf(ctx, "Device info technology %s, intf-id %v", technology, PonIntfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000243
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700244 rsrMgr, err := ponrmgr.NewPONResourceManager(ctx, technology, deviceType, deviceID,
245 Backend, ResourceMgr.Address, basePathKvStore)
246 if err != nil {
247 logger.Errorf(ctx, "Failed to create pon resource manager instance for technology %s", technology)
248 return nil
249 }
250 ResourceMgr.PonRsrMgr = rsrMgr
251 // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
252 InitializeDeviceResourceRangeAndPool(ctx, rsrMgr, TechRange, devInfo)
253 if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(ctx, intfID); err != nil {
254 logger.Fatal(ctx, "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.PonIntfID, ResourceMgr.DeviceID)
255 return nil
256 }
257 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400258 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400259 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700260
261 ResourceMgr.InitLocalCache()
yasin saplibddc2d72022-02-08 13:10:17 +0000262 if err := ResourceMgr.LoadLocalCacheFromKVStore(ctx); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +0000263 logger.Error(ctx, "failed-to-load-local-cache-from-kvstore")
264 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000265 logger.Info(ctx, "Initialization of resource manager success!")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400266 return &ResourceMgr
Abhilash S.L7f17e402019-03-15 17:40:41 +0530267}
268
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400269// InitLocalCache initializes local maps used for write-through-cache
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700270func (rsrcMgr *OpenOltResourceMgr) InitLocalCache() {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700271 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
272 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
273 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
274 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
275 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
276 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
277 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
278 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
279 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
280}
281
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400282// LoadLocalCacheFromKVStore loads local maps
yasin saplibddc2d72022-02-08 13:10:17 +0000283func (rsrcMgr *OpenOltResourceMgr) LoadLocalCacheFromKVStore(ctx context.Context) error {
yasin sapli9e4c5092022-02-01 13:52:33 +0000284
285 //List all the keys for OnuGemInfo
yasin saplibddc2d72022-02-08 13:10:17 +0000286 prefixPath := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
yasin sapli9e4c5092022-02-01 13:52:33 +0000287 keys, err := rsrcMgr.KVStore.List(ctx, prefixPath)
288 logger.Debug(ctx, "load-local-cache-from-KV-store-started")
289 if err != nil {
290 logger.Errorf(ctx, "failed-to-list-keys-from-path-%s", prefixPath)
291 return err
292 }
293 for path := range keys {
294 var Val []byte
295 var onugem OnuGemInfo
296 // Get rid of the path prefix
297 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
298 replacedWith := ""
299 path = strings.Replace(path, stringToBeReplaced, replacedWith, 1)
300
301 value, err := rsrcMgr.KVStore.Get(ctx, path)
302 if err != nil {
303 logger.Errorw(ctx, "failed-to-get-from-kv-store", log.Fields{"path": path})
304 return err
305 } else if value == nil {
306 logger.Debug(ctx, "no-onugeminfo-for-path", log.Fields{"path": path})
307 continue
308 }
309 if Val, err = kvstore.ToByte(value.Value); err != nil {
310 logger.Error(ctx, "failed-to-covert-to-byte-array")
311 return err
312 }
313 if err = json.Unmarshal(Val, &onugem); err != nil {
314 logger.Error(ctx, "failed-to-unmarshall")
315 return err
316 }
317 logger.Debugw(ctx, "found-onugeminfo-from-path", log.Fields{"path": path, "onuGemInfo": onugem})
318
319 rsrcMgr.onuGemInfoLock.Lock()
320 rsrcMgr.onuGemInfo[path] = &onugem
321 rsrcMgr.onuGemInfoLock.Unlock()
322
323 }
324 logger.Debug(ctx, "load-local-cache-from-KV-store-finished")
325 return nil
326}
327
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700328// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
329// device specific information. If KV doesn't exist
330// or is broader than the device, the device's information will
331// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700332func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700333 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700334 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
335 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
336 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
337
338 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
339 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
340 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
341 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
342 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530343
Girish Gowdru0c588b22019-04-23 23:24:56 -0400344 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700345 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
346 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
347 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
348 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
349 "intf_ids": techRange.IntfIds,
350 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700351 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700352 // FIXME: Remove hardcoding
Girish Gowdru0c588b22019-04-23 23:24:56 -0400353 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
354 ONUIDStart = RangePool.Start
355 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700356 ONUIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400357 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
358 AllocIDStart = RangePool.Start
359 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700360 AllocIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400361 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
362 GEMPortIDStart = RangePool.Start
363 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700364 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400365 }
366 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530367
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700368 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
369 AllocIDStart, AllocIDEnd, AllocIDShared,
370 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
371 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700372 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530373
Abhilash S.L7f17e402019-03-15 17:40:41 +0530374}
375
Devmalya Paul495b94a2019-08-27 19:42:00 -0400376// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700377func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
378 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
379 logger.Debug(ctx, "Failed to clear device resource pool")
380 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400381 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000382 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400383 return nil
384}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530385
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700386// GetONUID returns the available onuID for the given pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000387func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400388 // Get ONU id for a provided pon interface ID.
yasin saplibddc2d72022-02-08 13:10:17 +0000389 onuID, err := rsrcMgr.TechprofileRef.GetResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400390 ponrmgr.ONU_ID, 1)
391 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000392 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
yasin saplibddc2d72022-02-08 13:10:17 +0000393 rsrcMgr.PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200394 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400395 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700396 if len(onuID) > 0 {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700397 return onuID[0], err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400398 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530399
Girish Gowdra950326e2021-11-05 12:43:24 -0700400 return 0, fmt.Errorf("no-onu-id-allocated")
Abhilash S.L8ee90712019-04-29 16:24:22 +0530401}
402
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700403// UpdateAllocIdsForOnu updates alloc ids in kv store for a given pon interface id, onu id and uni id
yasin saplibddc2d72022-02-08 13:10:17 +0000404func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, onuID uint32, uniID uint32, allocIDs []uint32) error {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530405
yasin saplibddc2d72022-02-08 13:10:17 +0000406 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000407
408 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
409 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
410 if err := rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID, allocIDs); err != nil {
411 logger.Errorw(ctx, "Failed to update alloc ids for onu", log.Fields{"err": err})
412 return err
413 }
414
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700415 // update cache
416 rsrcMgr.allocIDsForOnuLock.Lock()
417 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
418 rsrcMgr.allocIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000419 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530420}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700421
422// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
yasin saplibddc2d72022-02-08 13:10:17 +0000423func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, onuID uint32,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700424 uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530425
yasin saplibddc2d72022-02-08 13:10:17 +0000426 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530427
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700428 // fetch from cache
429 rsrcMgr.gemPortIDsForOnuLock.RLock()
430 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
431 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
432 if ok {
433 return gemIDs
434 }
435 /* Get gem ports for given pon interface , onu id and uni id. */
436 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
437
438 // update cache
439 rsrcMgr.gemPortIDsForOnuLock.Lock()
440 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
441 rsrcMgr.gemPortIDsForOnuLock.Unlock()
442
443 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530444}
445
Gamze Abakafee36392019-10-03 11:17:24 +0000446// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000447func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530448
yasin saplibddc2d72022-02-08 13:10:17 +0000449 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700450 // fetch from cache
451 rsrcMgr.allocIDsForOnuLock.RLock()
452 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
453 rsrcMgr.allocIDsForOnuLock.RUnlock()
454 if ok {
455 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400456 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700457 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
458
459 // update cache
460 rsrcMgr.allocIDsForOnuLock.Lock()
461 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
462 rsrcMgr.allocIDsForOnuLock.Unlock()
463
464 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000465}
466
467// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
yasin saplibddc2d72022-02-08 13:10:17 +0000468func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, onuID uint32, uniID uint32, allocID uint32) {
469 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000470 for i := 0; i < len(allocIDs); i++ {
471 if allocIDs[i] == allocID {
472 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
473 break
474 }
475 }
yasin saplibddc2d72022-02-08 13:10:17 +0000476 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000477 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700478 logger.Errorf(ctx, "Failed to Remove Alloc Id For Onu. intfID %d onuID %d uniID %d allocID %d",
yasin saplibddc2d72022-02-08 13:10:17 +0000479 rsrcMgr.PonIntfID, onuID, uniID, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000480 }
481}
482
483// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
yasin saplibddc2d72022-02-08 13:10:17 +0000484func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, onuID uint32, uniID uint32, gemPortID uint32) {
485 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000486 for i := 0; i < len(gemPortIDs); i++ {
487 if gemPortIDs[i] == gemPortID {
488 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
489 break
490 }
491 }
yasin saplibddc2d72022-02-08 13:10:17 +0000492 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000493 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700494 logger.Errorf(ctx, "Failed to Remove Gem Id For Onu. intfID %d onuID %d uniID %d gemPortId %d",
yasin saplibddc2d72022-02-08 13:10:17 +0000495 rsrcMgr.PonIntfID, onuID, uniID, gemPortID)
Gamze Abakafee36392019-10-03 11:17:24 +0000496 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530497}
498
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700499// UpdateGEMPortIDsForOnu updates gemport ids on to the kv store for a given pon port, onu id and uni id
yasin saplibddc2d72022-02-08 13:10:17 +0000500func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700501 uniID uint32, gemIDs []uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000502 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000503
504 if err := rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID, gemIDs); err != nil {
505 logger.Errorw(ctx, "Failed to update gem port ids for onu", log.Fields{"err": err})
506 return err
507 }
508
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700509 // update cache
510 rsrcMgr.gemPortIDsForOnuLock.Lock()
511 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
512 rsrcMgr.gemPortIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000513 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530514}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700515
516// FreeonuID releases(make free) onu id for a particular pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000517func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700518 if len(onuID) == 0 {
519 logger.Info(ctx, "onu id slice is nil, nothing to free")
520 return
521 }
yasin saplibddc2d72022-02-08 13:10:17 +0000522 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700523 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000524 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700525 "onu-id": onuID,
526 "err": err.Error(),
527 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700528 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000529 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700530 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530531}
532
Gamze Abakafee36392019-10-03 11:17:24 +0000533// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
534// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700535// The caller should ensure that this is a blocking call and this operation is serialized for
536// the ONU so as not cause resource corruption since there are no mutexes used here.
Girish Gowdraf3728b12022-02-02 21:46:51 -0800537// Setting freeFromResourcePool to false will not clear it from the resource pool but only
538// clear it for the given pon/onu/uni
yasin saplibddc2d72022-02-08 13:10:17 +0000539func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, onuID uint32,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800540 uniID uint32, allocID uint32, freeFromResourcePool bool) {
Girish Gowdrab77ded92020-04-08 11:45:05 -0700541
yasin saplibddc2d72022-02-08 13:10:17 +0000542 rsrcMgr.RemoveAllocIDForOnu(ctx, onuID, uniID, allocID)
Girish Gowdraf3728b12022-02-02 21:46:51 -0800543 if freeFromResourcePool {
544 allocIDs := make([]uint32, 0)
545 allocIDs = append(allocIDs, allocID)
yasin saplibddc2d72022-02-08 13:10:17 +0000546 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
Girish Gowdraf3728b12022-02-02 21:46:51 -0800547 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000548 "intf-id": rsrcMgr.PonIntfID,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800549 "onu-id": onuID,
550 "err": err.Error(),
551 })
552 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700553 }
Gamze Abakafee36392019-10-03 11:17:24 +0000554}
555
556// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
557// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700558// The caller should ensure that this is a blocking call and this operation is serialized for
559// the ONU so as not cause resource corruption since there are no mutexes used here.
yasin saplibddc2d72022-02-08 13:10:17 +0000560func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000561 uniID uint32, gemPortID uint32) {
yasin saplibddc2d72022-02-08 13:10:17 +0000562 rsrcMgr.RemoveGemPortIDForOnu(ctx, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700563
Gamze Abakafee36392019-10-03 11:17:24 +0000564 gemPortIDs := make([]uint32, 0)
565 gemPortIDs = append(gemPortIDs, gemPortID)
yasin saplibddc2d72022-02-08 13:10:17 +0000566 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700567 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000568 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700569 "onu-id": onuID,
570 "err": err.Error(),
571 })
572 }
Gamze Abakafee36392019-10-03 11:17:24 +0000573}
574
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700575// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000576func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, onuID uint32, uniID uint32) {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530577
yasin saplibddc2d72022-02-08 13:10:17 +0000578 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530579
Sridhar Ravindra92c9b0d2025-01-16 00:15:54 +0530580 if rsrcMgr.PonRsrMgr == nil || rsrcMgr.TechprofileRef == nil {
581 logger.Warn(ctx, "PonRsrMgr or TechprofileRef is nil")
582 return
583 }
584
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700585 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700586
yasin saplibddc2d72022-02-08 13:10:17 +0000587 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400588 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700589 AllocIDs); err != nil {
590 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000591 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700592 "onu-id": onuID,
593 "err": err.Error(),
594 })
595 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530596
Gamze Abaka745ccb72021-11-18 11:29:58 +0000597 //update cache
598 rsrcMgr.allocIDsForOnuLock.Lock()
599 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
600 rsrcMgr.allocIDsForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700601
Gamze Abaka745ccb72021-11-18 11:29:58 +0000602 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700603
yasin saplibddc2d72022-02-08 13:10:17 +0000604 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400605 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700606 GEMPortIDs); err != nil {
607 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000608 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700609 "onu-id": onuID,
610 "err": err.Error(),
611 })
612 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530613
Gamze Abaka745ccb72021-11-18 11:29:58 +0000614 // update cache
615 rsrcMgr.gemPortIDsForOnuLock.Lock()
616 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
617 rsrcMgr.gemPortIDsForOnuLock.Unlock()
618
Girish Gowdru0c588b22019-04-23 23:24:56 -0400619 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700620 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530621}
622
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700623// IsFlowOnKvStore checks if the given flowID is present on the kv store
624// Returns true if the flowID is found, otherwise it returns false
yasin saplibddc2d72022-02-08 13:10:17 +0000625func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, onuID int32, flowID uint64) (bool, error) {
yasin saplid0566272021-12-21 09:10:30 +0000626 var anyError error
Abhilash S.L7f17e402019-03-15 17:40:41 +0530627
yasin saplid0566272021-12-21 09:10:30 +0000628 // In case of nni trap flow
629 if onuID == -1 {
yasin saplibddc2d72022-02-08 13:10:17 +0000630 nniTrapflowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, NNI)
yasin saplid0566272021-12-21 09:10:30 +0000631 if err != nil {
632 logger.Warnw(ctx, "failed-to-get-nni-trap-flowIDs", log.Fields{"err": err})
633 return false, err
634 }
635 for _, id := range nniTrapflowIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700636 if flowID == id {
yasin saplid0566272021-12-21 09:10:30 +0000637 return true, nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400638 }
639 }
640 }
yasin saplid0566272021-12-21 09:10:30 +0000641
yasin saplibddc2d72022-02-08 13:10:17 +0000642 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin saplid0566272021-12-21 09:10:30 +0000643 rsrcMgr.onuGemInfoLock.RLock()
644 val, ok := rsrcMgr.onuGemInfo[path]
645 rsrcMgr.onuGemInfoLock.RUnlock()
646
647 if ok {
648 for _, gem := range val.GemPorts {
yasin saplibddc2d72022-02-08 13:10:17 +0000649 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gem)
yasin saplid0566272021-12-21 09:10:30 +0000650 if err != nil {
651 anyError = err
652 logger.Warnw(ctx, "failed-to-get-flowIDs-for-gem", log.Fields{"err": err, "onuID": onuID, "gem": gem})
653 } else {
654 for _, id := range flowIDs {
655 if flowID == id {
656 return true, nil
657 }
658 }
659 }
660 }
661 }
662 return false, anyError
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400663}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400664
salmansiddiqui7ac62132019-08-22 03:58:50 +0000665// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700666// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000667func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
668 Path := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700669 // fetch from cache
670 rsrcMgr.techProfileIDsForOnuLock.RLock()
671 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
672 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
673 if ok {
674 return tpIDs
675 }
676 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400677 if err == nil {
678 if Value != nil {
679 Val, err := kvstore.ToByte(Value.Value)
680 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700681 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
682 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400683 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700684 if err = json.Unmarshal(Val, &tpIDs); err != nil {
685 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
686 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400687 }
688 }
689 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000690 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400691 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700692 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
693
694 // update cache
695 rsrcMgr.techProfileIDsForOnuLock.Lock()
696 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
697 rsrcMgr.techProfileIDsForOnuLock.Unlock()
698
699 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400700
701}
702
Gamze Abakafee36392019-10-03 11:17:24 +0000703// RemoveTechProfileIDsForOnu deletes all tech profile ids from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700704// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000705func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) error {
706 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700707
708 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
709 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400710 return err
711 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000712
713 // update cache
714 rsrcMgr.techProfileIDsForOnuLock.Lock()
715 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
716 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400717 return nil
718}
719
Gamze Abakafee36392019-10-03 11:17:24 +0000720// RemoveTechProfileIDForOnu deletes a specific tech profile id from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700721// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000722func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32, tpID uint32) error {
723 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000724 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700725 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000726 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
727 }
728 }
yasin saplibddc2d72022-02-08 13:10:17 +0000729 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700730
Gamze Abakafee36392019-10-03 11:17:24 +0000731 Value, err := json.Marshal(tpIDList)
732 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000733 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000734 return err
735 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700736 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
737 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000738 return err
739 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000740
741 // update cache
742 rsrcMgr.techProfileIDsForOnuLock.Lock()
743 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
744 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Gamze Abakafee36392019-10-03 11:17:24 +0000745 return err
746}
747
748// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700749// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000750func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700751 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400752 var Value []byte
753 var err error
754
yasin saplibddc2d72022-02-08 13:10:17 +0000755 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000756
yasin saplibddc2d72022-02-08 13:10:17 +0000757 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000758 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700759 if value == tpID {
760 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000761 return err
762 }
763 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700764 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
765 tpIDList = append(tpIDList, tpID)
766
Gamze Abakafee36392019-10-03 11:17:24 +0000767 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400768 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000769 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400770 return err
771 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700772 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
773 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400774 return err
775 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000776
777 // update cache
778 rsrcMgr.techProfileIDsForOnuLock.Lock()
779 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
780 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400781 return err
782}
783
Girish Gowdraa482f272021-03-24 23:04:19 -0700784// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000785// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000786func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700787 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400788 var Value []byte
789 var err error
yasin saplibddc2d72022-02-08 13:10:17 +0000790 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700791
Girish Gowdraa482f272021-03-24 23:04:19 -0700792 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400793 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000794 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400795 return err
796 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700797 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
798 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400799 return err
800 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000801
802 // update cache
803 rsrcMgr.meterInfoForOnuLock.Lock()
804 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
805 rsrcMgr.meterInfoForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700806 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400807 return err
808}
809
Girish Gowdraa482f272021-03-24 23:04:19 -0700810// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000811// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000812func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700813 uniID uint32, tpID uint32) (*MeterInfo, error) {
yasin saplibddc2d72022-02-08 13:10:17 +0000814 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700815
816 // get from cache
817 rsrcMgr.meterInfoForOnuLock.RLock()
818 val, ok := rsrcMgr.meterInfoForOnu[Path]
819 rsrcMgr.meterInfoForOnuLock.RUnlock()
820 if ok {
821 return val, nil
822 }
823
Girish Gowdraa482f272021-03-24 23:04:19 -0700824 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700825 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400826 if err == nil {
827 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700828 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000829 Val, er := kvstore.ToByte(Value.Value)
830 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700831 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000832 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400833 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700834 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700835 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000836 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400837 }
838 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400840 return nil, err
841 }
842 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000843 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400844
845 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700846 // update cache
847 rsrcMgr.meterInfoForOnuLock.Lock()
848 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
849 rsrcMgr.meterInfoForOnuLock.Unlock()
850
Girish Gowdraa482f272021-03-24 23:04:19 -0700851 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400852}
853
Girish Gowdraa482f272021-03-24 23:04:19 -0700854// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
855// When reference count becomes 0, it clears the meter information from the kv store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700856func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, Direction string,
yasin saplibddc2d72022-02-08 13:10:17 +0000857 onuID uint32, uniID uint32, tpID uint32, increment bool) error {
858 meterInfo, err := rsrcMgr.GetMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID)
Girish Gowdra82c80982021-03-26 16:22:02 -0700859 if err != nil {
860 return err
861 } else if meterInfo == nil {
862 // If we are increasing the reference count, we expect the meter information to be present on KV store.
863 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
864 if increment {
yasin saplibddc2d72022-02-08 13:10:17 +0000865 logger.Errorf(ctx, "error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
866 return fmt.Errorf("error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra82c80982021-03-26 16:22:02 -0700867 }
868 logger.Warnw(ctx, "meter is already cleared",
yasin saplibddc2d72022-02-08 13:10:17 +0000869 log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700870 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700871 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700872
Girish Gowdraa482f272021-03-24 23:04:19 -0700873 if increment {
874 meterInfo.RefCnt++
875 } else {
876 meterInfo.RefCnt--
Girish Gowdraa482f272021-03-24 23:04:19 -0700877 }
yasin saplibddc2d72022-02-08 13:10:17 +0000878 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700879 return err
880 }
881 return nil
882}
883
884// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000885// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
yasin saplibddc2d72022-02-08 13:10:17 +0000886func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700887 uniID uint32, tpID uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000888 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700889
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700890 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000891 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400892 return err
893 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000894
895 // update cache
896 rsrcMgr.meterInfoForOnuLock.Lock()
897 delete(rsrcMgr.meterInfoForOnu, Path)
898 rsrcMgr.meterInfoForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400899 return nil
900}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000901
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400902// AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
yasin saplibddc2d72022-02-08 13:10:17 +0000903func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, onuID uint32, gemPort uint32) error {
904 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700905 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000906 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530907 return err
908 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700909 if onugem.OnuID == onuID {
910 for _, gem := range onugem.GemPorts {
911 if gem == gemPort {
912 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
913 return nil
914 }
915 }
916 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
917 onugem.GemPorts = append(onugem.GemPorts, gemPort)
918 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000919 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": rsrcMgr.PonIntfID, "onuGemInfoOnuID": onugem.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700920 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530921 }
922
yasin saplibddc2d72022-02-08 13:10:17 +0000923 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530924 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000925 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530926 return err
927 }
928 return err
929}
930
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400931// RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
yasin saplibddc2d72022-02-08 13:10:17 +0000932func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, onuID uint32, gemPort uint32) error {
933 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700934 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000935 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700936 return err
937 }
938 updated := false
939 if onugem.OnuID == onuID {
940 for i, gem := range onugem.GemPorts {
941 if gem == gemPort {
942 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
943 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
944 updated = true
945 break
946 }
947 }
948 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000949 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": rsrcMgr.PonIntfID, "onuGemInfoOnuID": onugem.OnuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700950 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
951 }
952 if updated {
yasin saplibddc2d72022-02-08 13:10:17 +0000953 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700954 if err != nil {
955 logger.Error(ctx, "Failed to add onugem to kv store")
956 return err
957 }
958 } else {
959 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
960 }
961 return nil
962}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530963
Joey Armstrong3f0e2422023-07-05 18:25:41 -0400964// GetOnuGemInfo gets onu gem info from the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +0000965func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, onuID uint32) (*OnuGemInfo, error) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700966 var err error
967 var Val []byte
968 var onugem OnuGemInfo
969
yasin saplibddc2d72022-02-08 13:10:17 +0000970 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700971
972 rsrcMgr.onuGemInfoLock.RLock()
973 val, ok := rsrcMgr.onuGemInfo[path]
974 rsrcMgr.onuGemInfoLock.RUnlock()
975 if ok {
976 return val, nil
977 }
978 value, err := rsrcMgr.KVStore.Get(ctx, path)
979 if err != nil {
980 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
981 return nil, err
982 } else if value == nil {
983 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
984 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
985 }
986 if Val, err = kvstore.ToByte(value.Value); err != nil {
987 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530988 return nil, err
989 }
990
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700991 if err = json.Unmarshal(Val, &onugem); err != nil {
992 logger.Error(ctx, "Failed to unmarshall")
993 return nil, err
994 }
995 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
996 rsrcMgr.onuGemInfoLock.Lock()
997 rsrcMgr.onuGemInfo[path] = &onugem
998 rsrcMgr.onuGemInfoLock.Unlock()
999
1000 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301001}
1002
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001003// AddNewOnuGemInfoToCacheAndKvStore function adds a new onu gem info to cache and kvstore
yasin saplibddc2d72022-02-08 13:10:17 +00001004func (rsrcMgr *OpenOltResourceMgr) AddNewOnuGemInfoToCacheAndKvStore(ctx context.Context, onuID uint32, serialNum string) error {
yasin sapli9e4c5092022-02-01 13:52:33 +00001005
yasin saplibddc2d72022-02-08 13:10:17 +00001006 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin sapli9e4c5092022-02-01 13:52:33 +00001007
1008 rsrcMgr.onuGemInfoLock.Lock()
1009 _, ok := rsrcMgr.onuGemInfo[Path]
1010 rsrcMgr.onuGemInfoLock.Unlock()
1011
1012 // If the ONU already exists in onuGemInfo list, nothing to do
1013 if ok {
1014 logger.Debugw(ctx, "onu-id-already-exists-in-cache", log.Fields{"onuID": onuID, "serialNum": serialNum})
1015 return nil
1016 }
1017
yasin saplibddc2d72022-02-08 13:10:17 +00001018 onuGemInfo := OnuGemInfo{OnuID: onuID, SerialNumber: serialNum, IntfID: rsrcMgr.PonIntfID}
yasin sapli9e4c5092022-02-01 13:52:33 +00001019
yasin saplibddc2d72022-02-08 13:10:17 +00001020 if err := rsrcMgr.AddOnuGemInfo(ctx, onuID, onuGemInfo); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +00001021 return err
1022 }
1023 logger.Infow(ctx, "added-onuinfo",
1024 log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +00001025 "intf-id": rsrcMgr.PonIntfID,
yasin sapli9e4c5092022-02-01 13:52:33 +00001026 "onu-id": onuID,
1027 "serial-num": serialNum,
1028 "onu": onuGemInfo,
1029 "device-id": rsrcMgr.DeviceID})
1030 return nil
1031}
1032
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001033// AddOnuGemInfo adds onu info on to the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +00001034func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, onuID uint32, onuGem OnuGemInfo) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001035
1036 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301037 var err error
yasin saplibddc2d72022-02-08 13:10:17 +00001038 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301039
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001040 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301041 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001042 logger.Error(ctx, "failed to Marshal")
1043 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301044 }
1045
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001046 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
1047 logger.Errorf(ctx, "Failed to update resource %s", Path)
1048 return err
1049 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001050 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem, "Path": Path})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001051
1052 //update cache
1053 rsrcMgr.onuGemInfoLock.Lock()
1054 rsrcMgr.onuGemInfo[Path] = &onuGem
1055 rsrcMgr.onuGemInfoLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001056 return err
1057}
1058
1059// DelOnuGemInfo deletes the onugem info from kvstore per ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001060func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, onuID uint32) error {
1061 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001062
1063 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1064 logger.Errorf(ctx, "failed to remove resource %s", path)
1065 return err
1066 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001067
1068 //update cache
1069 rsrcMgr.onuGemInfoLock.Lock()
1070 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
1071 delete(rsrcMgr.onuGemInfo, path)
1072 rsrcMgr.onuGemInfoLock.Unlock()
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001073 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301074}
1075
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001076// DeleteAllOnuGemInfoForIntf deletes all the all onu gem info on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001077func (rsrcMgr *OpenOltResourceMgr) DeleteAllOnuGemInfoForIntf(ctx context.Context) error {
Girish Gowdra950326e2021-11-05 12:43:24 -07001078
yasin saplibddc2d72022-02-08 13:10:17 +00001079 path := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001080
yasin saplibddc2d72022-02-08 13:10:17 +00001081 logger.Debugw(ctx, "delete-all-onu-gem-info-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001082 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1083 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1084 return err
1085 }
1086
1087 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1088 rsrcMgr.onuGemInfoLock.Lock()
1089 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
1090 rsrcMgr.onuGemInfoLock.Unlock()
1091 return nil
1092}
1093
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301094// AddUniPortToOnuInfo adds uni port to the onuinfo kvstore. check if the uni is already present if not update the kv store.
yasin saplibddc2d72022-02-08 13:10:17 +00001095func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, onuID uint32, portNo uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301096
yasin saplibddc2d72022-02-08 13:10:17 +00001097 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001098 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +00001099 logger.Warnf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301100 return
1101 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001102
1103 if onugem.OnuID == onuID {
1104 for _, uni := range onugem.UniPorts {
1105 if uni == portNo {
1106 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
1107 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301108 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301109 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001110 onugem.UniPorts = append(onugem.UniPorts, portNo)
1111 } else {
yasin saplibddc2d72022-02-08 13:10:17 +00001112 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001113 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301114 }
yasin saplibddc2d72022-02-08 13:10:17 +00001115 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301116 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001117 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301118 return
1119 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301120}
1121
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001122// UpdateGemPortForPktIn updates gemport for pkt in path to kvstore, path being intfid, onuid, portno, vlan id, priority bit
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001123func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301124
Girish Gowdra950326e2021-11-05 12:43:24 -07001125 path := fmt.Sprintf(OnuPacketInPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001126
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301127 Value, err := json.Marshal(gemPort)
1128 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001129 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301130 return
1131 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001132 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001133 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301134 return
1135 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001136
1137 // update cache
1138 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1139 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1140 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +00001141 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301142}
1143
Esin Karaman7fb80c22020-07-16 14:23:33 +00001144// GetGemPortFromOnuPktIn gets the gem port from onu pkt in path, path being intfid, onuid, portno, vlan id, priority bit
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001145func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301146
1147 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301148
Girish Gowdra950326e2021-11-05 12:43:24 -07001149 path := fmt.Sprintf(OnuPacketInPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
Esin Karaman7fb80c22020-07-16 14:23:33 +00001150 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001151 // get from cache
1152 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1153 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1154 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1155 if ok {
1156 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1157 return gemPort, nil
1158 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301159
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001160 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301161 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001162 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301163 return uint32(0), err
1164 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001165 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301166 return uint32(0), nil
1167 }
1168
1169 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301171 return uint32(0), err
1172 }
1173 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001174 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301175 return uint32(0), err
1176 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001177 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001178 // update cache
1179 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1180 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1181 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301182
1183 return gemPort, nil
1184}
1185
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001186// DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001187func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, onuID uint32, logicalPort uint32) error {
1188 path := fmt.Sprintf(OnuPacketInPathPrefix, rsrcMgr.PonIntfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001189 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001190 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001191 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1192 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001193 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001194
Gamze Abaka745ccb72021-11-18 11:29:58 +00001195 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1196 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1197 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1198 return err
1199 }
1200
Esin Karaman7fb80c22020-07-16 14:23:33 +00001201 //remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001202 for key := range value {
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001203 // Remove the PathPrefix from the path on KV key.
Girish Gowdra950326e2021-11-05 12:43:24 -07001204 // gemPortForPacketInInfo cache uses OnuPacketInPath as the key
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001205 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001206 replacedWith := ""
1207 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001208 // update cache
1209 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1210 delete(rsrcMgr.gemPortForPacketInInfo, key)
1211 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001212
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001213 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1214 }
1215
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301216 return nil
1217}
1218
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001219// GetFlowIDsForGem gets the list of FlowIDs for the given gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001220func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, gem uint32) ([]uint64, error) {
1221 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001222
1223 // get from cache
1224 rsrcMgr.flowIDsForGemLock.RLock()
1225 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1226 rsrcMgr.flowIDsForGemLock.RUnlock()
1227 if ok {
1228 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301229 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301230
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001231 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301232 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001233 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1234 return nil, err
yasin saplid0566272021-12-21 09:10:30 +00001235 } else if value == nil || value.Value == nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001236 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1237 return nil, nil
1238 }
1239 Val, err := kvstore.ToByte(value.Value)
1240 if err != nil {
1241 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301242 return nil, err
1243 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301244
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001245 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1246 logger.Error(ctx, "Failed to unmarshall")
1247 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301248 }
1249
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001250 // update cache
1251 rsrcMgr.flowIDsForGemLock.Lock()
1252 rsrcMgr.flowIDsForGem[gem] = flowIDs
1253 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301254
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001255 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301256}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301257
yasin sapli9e4c5092022-02-01 13:52:33 +00001258// IsGemPortUsedByAnotherFlow returns true if given gem is used by another flow
Girish Gowdrab4c33302022-03-18 15:07:38 -07001259func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(ctx context.Context, gemPortID uint32, flowID uint64) (bool, error) {
1260 flowIDList, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1261 if err != nil {
1262 return false, err
1263 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001264 for _, id := range flowIDList {
1265 if flowID != id {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001266 return true, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001267 }
1268 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001269 return false, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001270}
1271
1272// RegisterFlowIDForGem updates both cache and KV store for flowIDsForGem map
yasin saplibddc2d72022-02-08 13:10:17 +00001273func (rsrcMgr *OpenOltResourceMgr) RegisterFlowIDForGem(ctx context.Context, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001274 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1275 if err != nil {
1276 return err
yasin sapli9e4c5092022-02-01 13:52:33 +00001277 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001278
1279 flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
yasin sapli9e4c5092022-02-01 13:52:33 +00001280 // update the flowids for a gem to the KVstore
yasin saplibddc2d72022-02-08 13:10:17 +00001281 return rsrcMgr.UpdateFlowIDsForGem(ctx, gemPortID, flowIDs)
yasin sapli9e4c5092022-02-01 13:52:33 +00001282}
1283
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001284// UpdateFlowIDsForGem updates flow id per gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001285func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301286 var val []byte
yasin saplibddc2d72022-02-08 13:10:17 +00001287 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301288
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001289 if flowIDs == nil {
Girish Gowdra950326e2021-11-05 12:43:24 -07001290 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1291 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1292 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001293 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301294 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001295 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301296 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001297 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301298 return err
1299 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001300
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001301 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1302 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301303 return err
1304 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001305 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001306
1307 // update cache
1308 rsrcMgr.flowIDsForGemLock.Lock()
1309 rsrcMgr.flowIDsForGem[gem] = flowIDs
1310 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301311 return nil
1312}
1313
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001314// DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
yasin saplibddc2d72022-02-08 13:10:17 +00001315func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, gem uint32) error {
1316 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Gamze Abaka745ccb72021-11-18 11:29:58 +00001317 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1318 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1319 return err
1320 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001321 // update cache
1322 rsrcMgr.flowIDsForGemLock.Lock()
1323 delete(rsrcMgr.flowIDsForGem, gem)
1324 rsrcMgr.flowIDsForGemLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +00001325 return nil
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301326}
Esin Karamanccb714b2019-11-29 15:02:06 +00001327
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001328// DeleteAllFlowIDsForGemForIntf deletes all the flow ids associated for all the gems on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001329func (rsrcMgr *OpenOltResourceMgr) DeleteAllFlowIDsForGemForIntf(ctx context.Context) error {
1330 path := fmt.Sprintf(FlowIDsForGemPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001331
yasin saplibddc2d72022-02-08 13:10:17 +00001332 logger.Debugw(ctx, "delete-flow-ids-for-gem-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001333 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1334 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1335 return err
1336 }
1337
1338 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1339 rsrcMgr.flowIDsForGemLock.Lock()
1340 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
1341 rsrcMgr.flowIDsForGemLock.Unlock()
1342 return nil
1343}
1344
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001345// GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001346func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001347 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001348 var val []byte
1349
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001350 rsrcMgr.mcastQueueForIntfLock.RLock()
1351 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1352 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1353 return rsrcMgr.mcastQueueForIntf, nil
1354 }
1355 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1356
1357 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001358 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001359 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001360 return nil, err
1361 }
1362 if kvPair != nil && kvPair.Value != nil {
1363 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001364 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001365 return nil, err
1366 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001367 rsrcMgr.mcastQueueForIntfLock.Lock()
1368 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1369 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1370 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001371 return nil, err
1372 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001373 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001374 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001375 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001376}
1377
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001378// AddMcastQueueForIntf adds multicast queue for pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001379func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001380 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001381 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001382
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001383 // Load local cache from kv store the first time
1384 rsrcMgr.mcastQueueForIntfLock.RLock()
1385 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1386 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1387 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1388 if err != nil {
yasin saplibddc2d72022-02-08 13:10:17 +00001389 logger.Errorw(ctx, "Failed to get multicast queue info for interface", log.Fields{"err": err, "intf": rsrcMgr.PonIntfID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001390 return err
1391 }
1392 } else {
1393 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1394 }
1395
1396 // Update KV store
1397 rsrcMgr.mcastQueueForIntfLock.Lock()
yasin saplibddc2d72022-02-08 13:10:17 +00001398 rsrcMgr.mcastQueueForIntf[rsrcMgr.PonIntfID] = []uint32{gem, servicePriority}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001399 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001400 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001401 rsrcMgr.mcastQueueForIntfLock.Unlock()
1402 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001403 return err
1404 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001405 rsrcMgr.mcastQueueForIntfLock.Unlock()
1406
1407 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1408 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001409 return err
1410 }
yasin saplibddc2d72022-02-08 13:10:17 +00001411 logger.Debugw(ctx, "added multicast queue info to KV store successfully", log.Fields{"path": path, "interfaceId": rsrcMgr.PonIntfID, "gem": gem, "svcPrior": servicePriority})
Esin Karamanccb714b2019-11-29 15:02:06 +00001412 return nil
1413}
1414
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001415// DeleteMcastQueueForIntf deletes multicast queue info for the current pon interface from kvstore
Gustavo Silva41af9122022-10-11 11:05:13 -03001416func (rsrcMgr *OpenOltResourceMgr) DeleteMcastQueueForIntf(ctx context.Context) error {
Girish Gowdraf3728b12022-02-02 21:46:51 -08001417 path := McastQueuesForIntf
1418
1419 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1420 logger.Errorw(ctx, "Failed to delete multicast queue info from kvstore", log.Fields{"err": err, "interfaceId": rsrcMgr.PonIntfID})
Gustavo Silva41af9122022-10-11 11:05:13 -03001421 return err
Girish Gowdraf3728b12022-02-02 21:46:51 -08001422 }
1423 logger.Debugw(ctx, "deleted multicast queue info from KV store successfully", log.Fields{"interfaceId": rsrcMgr.PonIntfID})
Gustavo Silva41af9122022-10-11 11:05:13 -03001424 return nil
Girish Gowdraf3728b12022-02-02 21:46:51 -08001425}
1426
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001427// AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001428func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001429 var Value []byte
1430 var err error
1431 var path string
1432 if cached {
1433 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1434 } else {
1435 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1436 }
1437 //build group info object
1438 var outPorts []uint32
1439 for _, ofBucket := range groupEntry.Desc.Buckets {
1440 for _, ofAction := range ofBucket.Actions {
1441 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1442 outPorts = append(outPorts, ofAction.GetOutput().Port)
1443 }
1444 }
1445 }
1446 groupInfo := GroupInfo{
1447 GroupID: groupEntry.Desc.GroupId,
1448 OutPorts: outPorts,
1449 }
1450
1451 Value, err = json.Marshal(groupInfo)
1452
1453 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001454 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001455 return err
1456 }
1457
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001458 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001459 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001460 return err
1461 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001462
1463 // update cache
1464 rsrcMgr.groupInfoLock.Lock()
1465 rsrcMgr.groupInfo[path] = &groupInfo
1466 rsrcMgr.groupInfoLock.Unlock()
Esin Karamanccb714b2019-11-29 15:02:06 +00001467 return nil
1468}
1469
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001470// RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001471func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001472 var path string
1473 if cached {
1474 path = fmt.Sprintf(FlowGroupCached, groupID)
1475 } else {
1476 path = fmt.Sprintf(FlowGroup, groupID)
1477 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001478
1479 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001480 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001481 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001482 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001483
1484 // update cache
1485 rsrcMgr.groupInfoLock.Lock()
1486 delete(rsrcMgr.groupInfo, path)
1487 rsrcMgr.groupInfoLock.Unlock()
Esin Karamand519bbf2020-07-01 11:16:03 +00001488 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001489}
1490
Joey Armstrong3f0e2422023-07-05 18:25:41 -04001491// GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1492// fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
Esin Karamanccb714b2019-11-29 15:02:06 +00001493// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001494func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001495 var groupInfo GroupInfo
1496 var path string
1497 if cached {
1498 path = fmt.Sprintf(FlowGroupCached, groupID)
1499 } else {
1500 path = fmt.Sprintf(FlowGroup, groupID)
1501 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001502
1503 // read from cache
1504 rsrcMgr.groupInfoLock.RLock()
1505 gi, ok := rsrcMgr.groupInfo[path]
1506 rsrcMgr.groupInfoLock.RUnlock()
1507 if ok {
1508 return true, *gi, nil
1509 }
1510
1511 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001512 if err != nil {
1513 return false, groupInfo, err
1514 }
1515 if kvPair != nil && kvPair.Value != nil {
1516 Val, err := kvstore.ToByte(kvPair.Value)
1517 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001518 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001519 return false, groupInfo, err
1520 }
1521 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001522 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001523 return false, groupInfo, err
1524 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001525 // update cache
1526 rsrcMgr.groupInfoLock.Lock()
1527 rsrcMgr.groupInfo[path] = &groupInfo
1528 rsrcMgr.groupInfoLock.Unlock()
1529
Esin Karamanccb714b2019-11-29 15:02:06 +00001530 return true, groupInfo, nil
1531 }
1532 return false, groupInfo, nil
1533}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001534
yasin sapli9e4c5092022-02-01 13:52:33 +00001535// GetOnuGemInfoList returns all gems in the onuGemInfo map
1536func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfoList(ctx context.Context) []OnuGemInfo {
1537 var onuGemInfoLst []OnuGemInfo
1538 rsrcMgr.onuGemInfoLock.RLock()
1539 defer rsrcMgr.onuGemInfoLock.RUnlock()
1540 for _, v := range rsrcMgr.onuGemInfo {
1541 onuGemInfoLst = append(onuGemInfoLst, *v)
1542 }
1543 return onuGemInfoLst
1544}
1545
yasin sapli9e4c5092022-02-01 13:52:33 +00001546func appendUnique64bit(slice []uint64, item uint64) []uint64 {
1547 for _, sliceElement := range slice {
1548 if sliceElement == item {
1549 return slice
1550 }
1551 }
1552 return append(slice, item)
1553}