blob: af281f49ef3f5b2ec0783c816b62302b10ae0161 [file] [log] [blame]
Abhilash S.L7f17e402019-03-15 17:40:41 +05301/*
2 * Copyright 2019-present Open Networking Foundation
3
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
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070017//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)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400176 }
177 return nil, errors.New("unsupported-kv-store")
Abhilash S.L7f17e402019-03-15 17:40:41 +0530178}
179
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700180// SetKVClient sets the KV client and return a kv backend
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800181func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400182 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
183 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000184 kvClient, err := newKVClient(ctx, backend, addr, KvstoreTimeout)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400185 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000186 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400187 return nil
188 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700189 // return db.NewBackend(ctx, backend, addr, KvstoreTimeout, fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID))
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700190
sbarbaria8910ba2019-11-05 10:12:23 -0500191 kvbackend := &db.Backend{
Girish Gowdru0c588b22019-04-23 23:24:56 -0400192 Client: kvClient,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700193 StoreType: backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000194 Address: addr,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700195 Timeout: KvstoreTimeout,
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800196 PathPrefix: fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID)}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530197
Girish Gowdru0c588b22019-04-23 23:24:56 -0400198 return kvbackend
Abhilash S.L7f17e402019-03-15 17:40:41 +0530199}
200
Gamze Abakafee36392019-10-03 11:17:24 +0000201// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700202// instances according to technology. Initializes the default resource ranges for all
203// the resources.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700204func 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 -0400205 var ResourceMgr OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700206 logger.Debugf(ctx, "Init new resource manager , ponIf: %v, address: %s, device-id: %s", PonIntfID, KVStoreAddress, deviceID)
207 ResourceMgr.PonIntfID = PonIntfID
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700208 ResourceMgr.DeviceID = deviceID
Neha Sharma3f221ae2020-04-29 19:02:12 +0000209 ResourceMgr.Address = KVStoreAddress
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700210 ResourceMgr.DeviceType = deviceType
211 ResourceMgr.DevInfo = devInfo
Abhilash S.L7f17e402019-03-15 17:40:41 +0530212
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700213 Backend := kvStoreType
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800214 ResourceMgr.KVStore = SetKVClient(ctx, Backend, ResourceMgr.Address, deviceID, basePathKvStore)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400215 if ResourceMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Error(ctx, "Failed to setup KV store")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400217 }
Girish Gowdra38d533d2020-03-30 20:38:51 -0700218
Girish Gowdru0c588b22019-04-23 23:24:56 -0400219 // TODO self.args = registry('main').get_args()
Abhilash S.L7f17e402019-03-15 17:40:41 +0530220
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700221 // Create a separate Resource Manager instance for each range. This assumes that
Girish Gowdru0c588b22019-04-23 23:24:56 -0400222 // each technology is represented by only a single range
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700223 for _, TechRange := range devInfo.Ranges {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700224 for _, intfID := range TechRange.IntfIds {
225 if intfID == PonIntfID {
226 technology := TechRange.Technology
227 logger.Debugf(ctx, "Device info technology %s, intf-id %v", technology, PonIntfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000228
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700229 rsrMgr, err := ponrmgr.NewPONResourceManager(ctx, technology, deviceType, deviceID,
230 Backend, ResourceMgr.Address, basePathKvStore)
231 if err != nil {
232 logger.Errorf(ctx, "Failed to create pon resource manager instance for technology %s", technology)
233 return nil
234 }
235 ResourceMgr.PonRsrMgr = rsrMgr
236 // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
237 InitializeDeviceResourceRangeAndPool(ctx, rsrMgr, TechRange, devInfo)
238 if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(ctx, intfID); err != nil {
239 logger.Fatal(ctx, "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.PonIntfID, ResourceMgr.DeviceID)
240 return nil
241 }
242 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400243 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400244 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700245
246 ResourceMgr.InitLocalCache()
yasin saplibddc2d72022-02-08 13:10:17 +0000247 if err := ResourceMgr.LoadLocalCacheFromKVStore(ctx); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +0000248 logger.Error(ctx, "failed-to-load-local-cache-from-kvstore")
249 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000250 logger.Info(ctx, "Initialization of resource manager success!")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400251 return &ResourceMgr
Abhilash S.L7f17e402019-03-15 17:40:41 +0530252}
253
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700254//InitLocalCache initializes local maps used for write-through-cache
255func (rsrcMgr *OpenOltResourceMgr) InitLocalCache() {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700256 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
257 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
258 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
259 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
260 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
261 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
262 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
263 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
264 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
265}
266
yasin sapli9e4c5092022-02-01 13:52:33 +0000267//LoadLocalCacheFromKVStore loads local maps
yasin saplibddc2d72022-02-08 13:10:17 +0000268func (rsrcMgr *OpenOltResourceMgr) LoadLocalCacheFromKVStore(ctx context.Context) error {
yasin sapli9e4c5092022-02-01 13:52:33 +0000269
270 //List all the keys for OnuGemInfo
yasin saplibddc2d72022-02-08 13:10:17 +0000271 prefixPath := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
yasin sapli9e4c5092022-02-01 13:52:33 +0000272 keys, err := rsrcMgr.KVStore.List(ctx, prefixPath)
273 logger.Debug(ctx, "load-local-cache-from-KV-store-started")
274 if err != nil {
275 logger.Errorf(ctx, "failed-to-list-keys-from-path-%s", prefixPath)
276 return err
277 }
278 for path := range keys {
279 var Val []byte
280 var onugem OnuGemInfo
281 // Get rid of the path prefix
282 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
283 replacedWith := ""
284 path = strings.Replace(path, stringToBeReplaced, replacedWith, 1)
285
286 value, err := rsrcMgr.KVStore.Get(ctx, path)
287 if err != nil {
288 logger.Errorw(ctx, "failed-to-get-from-kv-store", log.Fields{"path": path})
289 return err
290 } else if value == nil {
291 logger.Debug(ctx, "no-onugeminfo-for-path", log.Fields{"path": path})
292 continue
293 }
294 if Val, err = kvstore.ToByte(value.Value); err != nil {
295 logger.Error(ctx, "failed-to-covert-to-byte-array")
296 return err
297 }
298 if err = json.Unmarshal(Val, &onugem); err != nil {
299 logger.Error(ctx, "failed-to-unmarshall")
300 return err
301 }
302 logger.Debugw(ctx, "found-onugeminfo-from-path", log.Fields{"path": path, "onuGemInfo": onugem})
303
304 rsrcMgr.onuGemInfoLock.Lock()
305 rsrcMgr.onuGemInfo[path] = &onugem
306 rsrcMgr.onuGemInfoLock.Unlock()
307
308 }
309 logger.Debug(ctx, "load-local-cache-from-KV-store-finished")
310 return nil
311}
312
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700313// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
314// device specific information. If KV doesn't exist
315// or is broader than the device, the device's information will
316// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700317func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700318 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700319 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
320 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
321 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
322
323 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
324 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
325 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
326 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
327 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530328
Girish Gowdru0c588b22019-04-23 23:24:56 -0400329 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700330 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
331 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
332 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
333 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
334 "intf_ids": techRange.IntfIds,
335 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700336 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700337 // FIXME: Remove hardcoding
Girish Gowdru0c588b22019-04-23 23:24:56 -0400338 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
339 ONUIDStart = RangePool.Start
340 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700341 ONUIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400342 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
343 AllocIDStart = RangePool.Start
344 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700345 AllocIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400346 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
347 GEMPortIDStart = RangePool.Start
348 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700349 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400350 }
351 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530352
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700353 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
354 AllocIDStart, AllocIDEnd, AllocIDShared,
355 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
356 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700357 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530358
Abhilash S.L7f17e402019-03-15 17:40:41 +0530359}
360
Devmalya Paul495b94a2019-08-27 19:42:00 -0400361// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700362func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
363 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
364 logger.Debug(ctx, "Failed to clear device resource pool")
365 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400366 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000367 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400368 return nil
369}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530370
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700371// GetONUID returns the available onuID for the given pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000372func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400373 // Get ONU id for a provided pon interface ID.
yasin saplibddc2d72022-02-08 13:10:17 +0000374 onuID, err := rsrcMgr.TechprofileRef.GetResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400375 ponrmgr.ONU_ID, 1)
376 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000377 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
yasin saplibddc2d72022-02-08 13:10:17 +0000378 rsrcMgr.PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200379 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400380 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700381 if len(onuID) > 0 {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700382 return onuID[0], err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400383 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530384
Girish Gowdra950326e2021-11-05 12:43:24 -0700385 return 0, fmt.Errorf("no-onu-id-allocated")
Abhilash S.L8ee90712019-04-29 16:24:22 +0530386}
387
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700388// 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 +0000389func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, onuID uint32, uniID uint32, allocIDs []uint32) error {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530390
yasin saplibddc2d72022-02-08 13:10:17 +0000391 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000392
393 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
394 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
395 if err := rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID, allocIDs); err != nil {
396 logger.Errorw(ctx, "Failed to update alloc ids for onu", log.Fields{"err": err})
397 return err
398 }
399
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700400 // update cache
401 rsrcMgr.allocIDsForOnuLock.Lock()
402 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
403 rsrcMgr.allocIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000404 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530405}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700406
407// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
yasin saplibddc2d72022-02-08 13:10:17 +0000408func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, onuID uint32,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700409 uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530410
yasin saplibddc2d72022-02-08 13:10:17 +0000411 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530412
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700413 // fetch from cache
414 rsrcMgr.gemPortIDsForOnuLock.RLock()
415 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
416 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
417 if ok {
418 return gemIDs
419 }
420 /* Get gem ports for given pon interface , onu id and uni id. */
421 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
422
423 // update cache
424 rsrcMgr.gemPortIDsForOnuLock.Lock()
425 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
426 rsrcMgr.gemPortIDsForOnuLock.Unlock()
427
428 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530429}
430
Gamze Abakafee36392019-10-03 11:17:24 +0000431// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000432func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530433
yasin saplibddc2d72022-02-08 13:10:17 +0000434 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700435 // fetch from cache
436 rsrcMgr.allocIDsForOnuLock.RLock()
437 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
438 rsrcMgr.allocIDsForOnuLock.RUnlock()
439 if ok {
440 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400441 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700442 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
443
444 // update cache
445 rsrcMgr.allocIDsForOnuLock.Lock()
446 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
447 rsrcMgr.allocIDsForOnuLock.Unlock()
448
449 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000450}
451
452// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
yasin saplibddc2d72022-02-08 13:10:17 +0000453func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, onuID uint32, uniID uint32, allocID uint32) {
454 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000455 for i := 0; i < len(allocIDs); i++ {
456 if allocIDs[i] == allocID {
457 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
458 break
459 }
460 }
yasin saplibddc2d72022-02-08 13:10:17 +0000461 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000462 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700463 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 +0000464 rsrcMgr.PonIntfID, onuID, uniID, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000465 }
466}
467
468// 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 +0000469func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, onuID uint32, uniID uint32, gemPortID uint32) {
470 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000471 for i := 0; i < len(gemPortIDs); i++ {
472 if gemPortIDs[i] == gemPortID {
473 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
474 break
475 }
476 }
yasin saplibddc2d72022-02-08 13:10:17 +0000477 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000478 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700479 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 +0000480 rsrcMgr.PonIntfID, onuID, uniID, gemPortID)
Gamze Abakafee36392019-10-03 11:17:24 +0000481 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530482}
483
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700484// 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 +0000485func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700486 uniID uint32, gemIDs []uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000487 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000488
489 if err := rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID, gemIDs); err != nil {
490 logger.Errorw(ctx, "Failed to update gem port ids for onu", log.Fields{"err": err})
491 return err
492 }
493
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700494 // update cache
495 rsrcMgr.gemPortIDsForOnuLock.Lock()
496 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
497 rsrcMgr.gemPortIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000498 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530499}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700500
501// FreeonuID releases(make free) onu id for a particular pon-port
yasin saplibddc2d72022-02-08 13:10:17 +0000502func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700503 if len(onuID) == 0 {
504 logger.Info(ctx, "onu id slice is nil, nothing to free")
505 return
506 }
yasin saplibddc2d72022-02-08 13:10:17 +0000507 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700508 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000509 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700510 "onu-id": onuID,
511 "err": err.Error(),
512 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700513 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000514 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700515 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530516}
517
Gamze Abakafee36392019-10-03 11:17:24 +0000518// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
519// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700520// The caller should ensure that this is a blocking call and this operation is serialized for
521// the ONU so as not cause resource corruption since there are no mutexes used here.
Girish Gowdraf3728b12022-02-02 21:46:51 -0800522// Setting freeFromResourcePool to false will not clear it from the resource pool but only
523// clear it for the given pon/onu/uni
yasin saplibddc2d72022-02-08 13:10:17 +0000524func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, onuID uint32,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800525 uniID uint32, allocID uint32, freeFromResourcePool bool) {
Girish Gowdrab77ded92020-04-08 11:45:05 -0700526
yasin saplibddc2d72022-02-08 13:10:17 +0000527 rsrcMgr.RemoveAllocIDForOnu(ctx, onuID, uniID, allocID)
Girish Gowdraf3728b12022-02-02 21:46:51 -0800528 if freeFromResourcePool {
529 allocIDs := make([]uint32, 0)
530 allocIDs = append(allocIDs, allocID)
yasin saplibddc2d72022-02-08 13:10:17 +0000531 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
Girish Gowdraf3728b12022-02-02 21:46:51 -0800532 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000533 "intf-id": rsrcMgr.PonIntfID,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800534 "onu-id": onuID,
535 "err": err.Error(),
536 })
537 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700538 }
Gamze Abakafee36392019-10-03 11:17:24 +0000539}
540
541// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
542// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700543// The caller should ensure that this is a blocking call and this operation is serialized for
544// the ONU so as not cause resource corruption since there are no mutexes used here.
yasin saplibddc2d72022-02-08 13:10:17 +0000545func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000546 uniID uint32, gemPortID uint32) {
yasin saplibddc2d72022-02-08 13:10:17 +0000547 rsrcMgr.RemoveGemPortIDForOnu(ctx, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700548
Gamze Abakafee36392019-10-03 11:17:24 +0000549 gemPortIDs := make([]uint32, 0)
550 gemPortIDs = append(gemPortIDs, gemPortID)
yasin saplibddc2d72022-02-08 13:10:17 +0000551 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700552 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000553 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700554 "onu-id": onuID,
555 "err": err.Error(),
556 })
557 }
Gamze Abakafee36392019-10-03 11:17:24 +0000558}
559
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700560// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
yasin saplibddc2d72022-02-08 13:10:17 +0000561func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, onuID uint32, uniID uint32) {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530562
yasin saplibddc2d72022-02-08 13:10:17 +0000563 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", rsrcMgr.PonIntfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530564
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700565 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700566
yasin saplibddc2d72022-02-08 13:10:17 +0000567 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400568 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700569 AllocIDs); err != nil {
570 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000571 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700572 "onu-id": onuID,
573 "err": err.Error(),
574 })
575 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530576
Gamze Abaka745ccb72021-11-18 11:29:58 +0000577 //update cache
578 rsrcMgr.allocIDsForOnuLock.Lock()
579 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
580 rsrcMgr.allocIDsForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700581
Gamze Abaka745ccb72021-11-18 11:29:58 +0000582 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700583
yasin saplibddc2d72022-02-08 13:10:17 +0000584 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, rsrcMgr.PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400585 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700586 GEMPortIDs); err != nil {
587 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +0000588 "intf-id": rsrcMgr.PonIntfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700589 "onu-id": onuID,
590 "err": err.Error(),
591 })
592 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530593
Gamze Abaka745ccb72021-11-18 11:29:58 +0000594 // update cache
595 rsrcMgr.gemPortIDsForOnuLock.Lock()
596 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
597 rsrcMgr.gemPortIDsForOnuLock.Unlock()
598
Girish Gowdru0c588b22019-04-23 23:24:56 -0400599 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700600 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530601}
602
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700603// IsFlowOnKvStore checks if the given flowID is present on the kv store
604// Returns true if the flowID is found, otherwise it returns false
yasin saplibddc2d72022-02-08 13:10:17 +0000605func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, onuID int32, flowID uint64) (bool, error) {
yasin saplid0566272021-12-21 09:10:30 +0000606 var anyError error
Abhilash S.L7f17e402019-03-15 17:40:41 +0530607
yasin saplid0566272021-12-21 09:10:30 +0000608 // In case of nni trap flow
609 if onuID == -1 {
yasin saplibddc2d72022-02-08 13:10:17 +0000610 nniTrapflowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, NNI)
yasin saplid0566272021-12-21 09:10:30 +0000611 if err != nil {
612 logger.Warnw(ctx, "failed-to-get-nni-trap-flowIDs", log.Fields{"err": err})
613 return false, err
614 }
615 for _, id := range nniTrapflowIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700616 if flowID == id {
yasin saplid0566272021-12-21 09:10:30 +0000617 return true, nil
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400618 }
619 }
620 }
yasin saplid0566272021-12-21 09:10:30 +0000621
yasin saplibddc2d72022-02-08 13:10:17 +0000622 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin saplid0566272021-12-21 09:10:30 +0000623 rsrcMgr.onuGemInfoLock.RLock()
624 val, ok := rsrcMgr.onuGemInfo[path]
625 rsrcMgr.onuGemInfoLock.RUnlock()
626
627 if ok {
628 for _, gem := range val.GemPorts {
yasin saplibddc2d72022-02-08 13:10:17 +0000629 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gem)
yasin saplid0566272021-12-21 09:10:30 +0000630 if err != nil {
631 anyError = err
632 logger.Warnw(ctx, "failed-to-get-flowIDs-for-gem", log.Fields{"err": err, "onuID": onuID, "gem": gem})
633 } else {
634 for _, id := range flowIDs {
635 if flowID == id {
636 return true, nil
637 }
638 }
639 }
640 }
641 }
642 return false, anyError
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400643}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400644
salmansiddiqui7ac62132019-08-22 03:58:50 +0000645// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700646// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000647func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32) []uint32 {
648 Path := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700649 // fetch from cache
650 rsrcMgr.techProfileIDsForOnuLock.RLock()
651 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
652 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
653 if ok {
654 return tpIDs
655 }
656 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400657 if err == nil {
658 if Value != nil {
659 Val, err := kvstore.ToByte(Value.Value)
660 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700661 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
662 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400663 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700664 if err = json.Unmarshal(Val, &tpIDs); err != nil {
665 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
666 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400667 }
668 }
669 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000670 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400671 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700672 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
673
674 // update cache
675 rsrcMgr.techProfileIDsForOnuLock.Lock()
676 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
677 rsrcMgr.techProfileIDsForOnuLock.Unlock()
678
679 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400680
681}
682
Gamze Abakafee36392019-10-03 11:17:24 +0000683// 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 -0700684// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000685func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, onuID uint32, uniID uint32) error {
686 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700687
688 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
689 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400690 return err
691 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000692
693 // update cache
694 rsrcMgr.techProfileIDsForOnuLock.Lock()
695 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
696 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400697 return nil
698}
699
Gamze Abakafee36392019-10-03 11:17:24 +0000700// 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 -0700701// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000702func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, onuID uint32, uniID uint32, tpID uint32) error {
703 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000704 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700705 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000706 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
707 }
708 }
yasin saplibddc2d72022-02-08 13:10:17 +0000709 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700710
Gamze Abakafee36392019-10-03 11:17:24 +0000711 Value, err := json.Marshal(tpIDList)
712 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000713 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000714 return err
715 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700716 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
717 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000718 return err
719 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000720
721 // update cache
722 rsrcMgr.techProfileIDsForOnuLock.Lock()
723 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
724 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Gamze Abakafee36392019-10-03 11:17:24 +0000725 return err
726}
727
728// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700729// This path is formed as the following: {intfID, onuID, uniID}/tp_id
yasin saplibddc2d72022-02-08 13:10:17 +0000730func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700731 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400732 var Value []byte
733 var err error
734
yasin saplibddc2d72022-02-08 13:10:17 +0000735 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000736
yasin saplibddc2d72022-02-08 13:10:17 +0000737 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000738 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700739 if value == tpID {
740 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000741 return err
742 }
743 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700744 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
745 tpIDList = append(tpIDList, tpID)
746
Gamze Abakafee36392019-10-03 11:17:24 +0000747 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400748 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000749 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400750 return err
751 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700752 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
753 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400754 return err
755 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000756
757 // update cache
758 rsrcMgr.techProfileIDsForOnuLock.Lock()
759 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
760 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400761 return err
762}
763
Girish Gowdraa482f272021-03-24 23:04:19 -0700764// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000765// 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 +0000766func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700767 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400768 var Value []byte
769 var err error
yasin saplibddc2d72022-02-08 13:10:17 +0000770 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700771
Girish Gowdraa482f272021-03-24 23:04:19 -0700772 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400773 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000774 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400775 return err
776 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700777 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
778 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400779 return err
780 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000781
782 // update cache
783 rsrcMgr.meterInfoForOnuLock.Lock()
784 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
785 rsrcMgr.meterInfoForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700786 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400787 return err
788}
789
Girish Gowdraa482f272021-03-24 23:04:19 -0700790// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000791// 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 +0000792func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700793 uniID uint32, tpID uint32) (*MeterInfo, error) {
yasin saplibddc2d72022-02-08 13:10:17 +0000794 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700795
796 // get from cache
797 rsrcMgr.meterInfoForOnuLock.RLock()
798 val, ok := rsrcMgr.meterInfoForOnu[Path]
799 rsrcMgr.meterInfoForOnuLock.RUnlock()
800 if ok {
801 return val, nil
802 }
803
Girish Gowdraa482f272021-03-24 23:04:19 -0700804 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700805 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400806 if err == nil {
807 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700808 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000809 Val, er := kvstore.ToByte(Value.Value)
810 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700811 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000812 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400813 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700814 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700815 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000816 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400817 }
818 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400820 return nil, err
821 }
822 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000823 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400824
825 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700826 // update cache
827 rsrcMgr.meterInfoForOnuLock.Lock()
828 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
829 rsrcMgr.meterInfoForOnuLock.Unlock()
830
Girish Gowdraa482f272021-03-24 23:04:19 -0700831 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400832}
833
Girish Gowdraa482f272021-03-24 23:04:19 -0700834// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
835// When reference count becomes 0, it clears the meter information from the kv store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700836func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, Direction string,
yasin saplibddc2d72022-02-08 13:10:17 +0000837 onuID uint32, uniID uint32, tpID uint32, increment bool) error {
838 meterInfo, err := rsrcMgr.GetMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID)
Girish Gowdra82c80982021-03-26 16:22:02 -0700839 if err != nil {
840 return err
841 } else if meterInfo == nil {
842 // If we are increasing the reference count, we expect the meter information to be present on KV store.
843 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
844 if increment {
yasin saplibddc2d72022-02-08 13:10:17 +0000845 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)
846 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 -0700847 }
848 logger.Warnw(ctx, "meter is already cleared",
yasin saplibddc2d72022-02-08 13:10:17 +0000849 log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700850 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700851 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700852
Girish Gowdraa482f272021-03-24 23:04:19 -0700853 if increment {
854 meterInfo.RefCnt++
855 } else {
856 meterInfo.RefCnt--
Girish Gowdraa482f272021-03-24 23:04:19 -0700857 }
yasin saplibddc2d72022-02-08 13:10:17 +0000858 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700859 return err
860 }
861 return nil
862}
863
864// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000865// 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 +0000866func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, onuID uint32,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700867 uniID uint32, tpID uint32) error {
yasin saplibddc2d72022-02-08 13:10:17 +0000868 Path := fmt.Sprintf(MeterIDPathSuffix, rsrcMgr.PonIntfID, onuID, uniID, tpID, Direction)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700869
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700870 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000871 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400872 return err
873 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000874
875 // update cache
876 rsrcMgr.meterInfoForOnuLock.Lock()
877 delete(rsrcMgr.meterInfoForOnu, Path)
878 rsrcMgr.meterInfoForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400879 return nil
880}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000881
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700882//AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
yasin saplibddc2d72022-02-08 13:10:17 +0000883func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, onuID uint32, gemPort uint32) error {
884 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700885 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000886 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530887 return err
888 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700889 if onugem.OnuID == onuID {
890 for _, gem := range onugem.GemPorts {
891 if gem == gemPort {
892 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
893 return nil
894 }
895 }
896 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
897 onugem.GemPorts = append(onugem.GemPorts, gemPort)
898 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000899 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 -0700900 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530901 }
902
yasin saplibddc2d72022-02-08 13:10:17 +0000903 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530904 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530906 return err
907 }
908 return err
909}
910
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700911//RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
yasin saplibddc2d72022-02-08 13:10:17 +0000912func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, onuID uint32, gemPort uint32) error {
913 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700914 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +0000915 logger.Errorf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700916 return err
917 }
918 updated := false
919 if onugem.OnuID == onuID {
920 for i, gem := range onugem.GemPorts {
921 if gem == gemPort {
922 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
923 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
924 updated = true
925 break
926 }
927 }
928 } else {
yasin saplibddc2d72022-02-08 13:10:17 +0000929 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 -0700930 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
931 }
932 if updated {
yasin saplibddc2d72022-02-08 13:10:17 +0000933 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700934 if err != nil {
935 logger.Error(ctx, "Failed to add onugem to kv store")
936 return err
937 }
938 } else {
939 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
940 }
941 return nil
942}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530943
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700944//GetOnuGemInfo gets onu gem info from the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +0000945func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, onuID uint32) (*OnuGemInfo, error) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700946 var err error
947 var Val []byte
948 var onugem OnuGemInfo
949
yasin saplibddc2d72022-02-08 13:10:17 +0000950 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700951
952 rsrcMgr.onuGemInfoLock.RLock()
953 val, ok := rsrcMgr.onuGemInfo[path]
954 rsrcMgr.onuGemInfoLock.RUnlock()
955 if ok {
956 return val, nil
957 }
958 value, err := rsrcMgr.KVStore.Get(ctx, path)
959 if err != nil {
960 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
961 return nil, err
962 } else if value == nil {
963 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
964 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
965 }
966 if Val, err = kvstore.ToByte(value.Value); err != nil {
967 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530968 return nil, err
969 }
970
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700971 if err = json.Unmarshal(Val, &onugem); err != nil {
972 logger.Error(ctx, "Failed to unmarshall")
973 return nil, err
974 }
975 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
976 rsrcMgr.onuGemInfoLock.Lock()
977 rsrcMgr.onuGemInfo[path] = &onugem
978 rsrcMgr.onuGemInfoLock.Unlock()
979
980 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530981}
982
yasin sapli9e4c5092022-02-01 13:52:33 +0000983//AddNewOnuGemInfoToCacheAndKvStore function adds a new onu gem info to cache and kvstore
yasin saplibddc2d72022-02-08 13:10:17 +0000984func (rsrcMgr *OpenOltResourceMgr) AddNewOnuGemInfoToCacheAndKvStore(ctx context.Context, onuID uint32, serialNum string) error {
yasin sapli9e4c5092022-02-01 13:52:33 +0000985
yasin saplibddc2d72022-02-08 13:10:17 +0000986 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
yasin sapli9e4c5092022-02-01 13:52:33 +0000987
988 rsrcMgr.onuGemInfoLock.Lock()
989 _, ok := rsrcMgr.onuGemInfo[Path]
990 rsrcMgr.onuGemInfoLock.Unlock()
991
992 // If the ONU already exists in onuGemInfo list, nothing to do
993 if ok {
994 logger.Debugw(ctx, "onu-id-already-exists-in-cache", log.Fields{"onuID": onuID, "serialNum": serialNum})
995 return nil
996 }
997
yasin saplibddc2d72022-02-08 13:10:17 +0000998 onuGemInfo := OnuGemInfo{OnuID: onuID, SerialNumber: serialNum, IntfID: rsrcMgr.PonIntfID}
yasin sapli9e4c5092022-02-01 13:52:33 +0000999
yasin saplibddc2d72022-02-08 13:10:17 +00001000 if err := rsrcMgr.AddOnuGemInfo(ctx, onuID, onuGemInfo); err != nil {
yasin sapli9e4c5092022-02-01 13:52:33 +00001001 return err
1002 }
1003 logger.Infow(ctx, "added-onuinfo",
1004 log.Fields{
yasin saplibddc2d72022-02-08 13:10:17 +00001005 "intf-id": rsrcMgr.PonIntfID,
yasin sapli9e4c5092022-02-01 13:52:33 +00001006 "onu-id": onuID,
1007 "serial-num": serialNum,
1008 "onu": onuGemInfo,
1009 "device-id": rsrcMgr.DeviceID})
1010 return nil
1011}
1012
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001013// AddOnuGemInfo adds onu info on to the kvstore per interface
yasin saplibddc2d72022-02-08 13:10:17 +00001014func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, onuID uint32, onuGem OnuGemInfo) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001015
1016 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301017 var err error
yasin saplibddc2d72022-02-08 13:10:17 +00001018 Path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301019
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001020 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301021 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001022 logger.Error(ctx, "failed to Marshal")
1023 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301024 }
1025
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001026 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
1027 logger.Errorf(ctx, "Failed to update resource %s", Path)
1028 return err
1029 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001030 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem, "Path": Path})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001031
1032 //update cache
1033 rsrcMgr.onuGemInfoLock.Lock()
1034 rsrcMgr.onuGemInfo[Path] = &onuGem
1035 rsrcMgr.onuGemInfoLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001036 return err
1037}
1038
1039// DelOnuGemInfo deletes the onugem info from kvstore per ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001040func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, onuID uint32) error {
1041 path := fmt.Sprintf(OnuGemInfoPath, rsrcMgr.PonIntfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001042
1043 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1044 logger.Errorf(ctx, "failed to remove resource %s", path)
1045 return err
1046 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001047
1048 //update cache
1049 rsrcMgr.onuGemInfoLock.Lock()
1050 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
1051 delete(rsrcMgr.onuGemInfo, path)
1052 rsrcMgr.onuGemInfoLock.Unlock()
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001053 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301054}
1055
Girish Gowdra950326e2021-11-05 12:43:24 -07001056//DeleteAllOnuGemInfoForIntf deletes all the all onu gem info on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001057func (rsrcMgr *OpenOltResourceMgr) DeleteAllOnuGemInfoForIntf(ctx context.Context) error {
Girish Gowdra950326e2021-11-05 12:43:24 -07001058
yasin saplibddc2d72022-02-08 13:10:17 +00001059 path := fmt.Sprintf(OnuGemInfoPathPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001060
yasin saplibddc2d72022-02-08 13:10:17 +00001061 logger.Debugw(ctx, "delete-all-onu-gem-info-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001062 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1063 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1064 return err
1065 }
1066
1067 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1068 rsrcMgr.onuGemInfoLock.Lock()
1069 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
1070 rsrcMgr.onuGemInfoLock.Unlock()
1071 return nil
1072}
1073
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301074// 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 +00001075func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, onuID uint32, portNo uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301076
yasin saplibddc2d72022-02-08 13:10:17 +00001077 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001078 if err != nil || onugem == nil || onugem.SerialNumber == "" {
yasin saplibddc2d72022-02-08 13:10:17 +00001079 logger.Warnf(ctx, "failed to get onuifo for intfid %d", rsrcMgr.PonIntfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301080 return
1081 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001082
1083 if onugem.OnuID == onuID {
1084 for _, uni := range onugem.UniPorts {
1085 if uni == portNo {
1086 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
1087 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301088 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301089 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001090 onugem.UniPorts = append(onugem.UniPorts, portNo)
1091 } else {
yasin saplibddc2d72022-02-08 13:10:17 +00001092 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": rsrcMgr.PonIntfID, "onuID": onuID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001093 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301094 }
yasin saplibddc2d72022-02-08 13:10:17 +00001095 err = rsrcMgr.AddOnuGemInfo(ctx, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301096 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001097 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301098 return
1099 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301100}
1101
Esin Karaman7fb80c22020-07-16 14:23:33 +00001102//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 -07001103func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301104
Girish Gowdra950326e2021-11-05 12:43:24 -07001105 path := fmt.Sprintf(OnuPacketInPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001106
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301107 Value, err := json.Marshal(gemPort)
1108 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001109 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301110 return
1111 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001112 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001113 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301114 return
1115 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001116
1117 // update cache
1118 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1119 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1120 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +00001121 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301122}
1123
Esin Karaman7fb80c22020-07-16 14:23:33 +00001124// 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 -07001125func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301126
1127 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301128
Girish Gowdra950326e2021-11-05 12:43:24 -07001129 path := fmt.Sprintf(OnuPacketInPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
Esin Karaman7fb80c22020-07-16 14:23:33 +00001130 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001131 // get from cache
1132 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1133 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1134 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1135 if ok {
1136 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1137 return gemPort, nil
1138 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301139
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001140 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301141 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001142 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301143 return uint32(0), err
1144 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001145 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301146 return uint32(0), nil
1147 }
1148
1149 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001150 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301151 return uint32(0), err
1152 }
1153 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001154 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301155 return uint32(0), err
1156 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001157 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001158 // update cache
1159 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1160 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1161 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301162
1163 return gemPort, nil
1164}
1165
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001166//DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
yasin saplibddc2d72022-02-08 13:10:17 +00001167func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, onuID uint32, logicalPort uint32) error {
1168 path := fmt.Sprintf(OnuPacketInPathPrefix, rsrcMgr.PonIntfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001169 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001170 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001171 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1172 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001173 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001174
Gamze Abaka745ccb72021-11-18 11:29:58 +00001175 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1176 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1177 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1178 return err
1179 }
1180
Esin Karaman7fb80c22020-07-16 14:23:33 +00001181 //remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001182 for key := range value {
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001183 // Remove the PathPrefix from the path on KV key.
Girish Gowdra950326e2021-11-05 12:43:24 -07001184 // gemPortForPacketInInfo cache uses OnuPacketInPath as the key
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001185 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001186 replacedWith := ""
1187 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001188 // update cache
1189 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1190 delete(rsrcMgr.gemPortForPacketInInfo, key)
1191 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001192
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001193 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1194 }
1195
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301196 return nil
1197}
1198
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001199//GetFlowIDsForGem gets the list of FlowIDs for the given gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001200func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, gem uint32) ([]uint64, error) {
1201 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001202
1203 // get from cache
1204 rsrcMgr.flowIDsForGemLock.RLock()
1205 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1206 rsrcMgr.flowIDsForGemLock.RUnlock()
1207 if ok {
1208 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301209 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301210
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001211 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301212 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001213 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1214 return nil, err
yasin saplid0566272021-12-21 09:10:30 +00001215 } else if value == nil || value.Value == nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001216 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1217 return nil, nil
1218 }
1219 Val, err := kvstore.ToByte(value.Value)
1220 if err != nil {
1221 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301222 return nil, err
1223 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301224
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001225 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1226 logger.Error(ctx, "Failed to unmarshall")
1227 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301228 }
1229
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001230 // update cache
1231 rsrcMgr.flowIDsForGemLock.Lock()
1232 rsrcMgr.flowIDsForGem[gem] = flowIDs
1233 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301234
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001235 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301236}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301237
yasin sapli9e4c5092022-02-01 13:52:33 +00001238// IsGemPortUsedByAnotherFlow returns true if given gem is used by another flow
Girish Gowdrab4c33302022-03-18 15:07:38 -07001239func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(ctx context.Context, gemPortID uint32, flowID uint64) (bool, error) {
1240 flowIDList, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1241 if err != nil {
1242 return false, err
1243 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001244 for _, id := range flowIDList {
1245 if flowID != id {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001246 return true, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001247 }
1248 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001249 return false, nil
yasin sapli9e4c5092022-02-01 13:52:33 +00001250}
1251
1252// RegisterFlowIDForGem updates both cache and KV store for flowIDsForGem map
yasin saplibddc2d72022-02-08 13:10:17 +00001253func (rsrcMgr *OpenOltResourceMgr) RegisterFlowIDForGem(ctx context.Context, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
Girish Gowdrab4c33302022-03-18 15:07:38 -07001254 flowIDs, err := rsrcMgr.GetFlowIDsForGem(ctx, gemPortID)
1255 if err != nil {
1256 return err
yasin sapli9e4c5092022-02-01 13:52:33 +00001257 }
Girish Gowdrab4c33302022-03-18 15:07:38 -07001258
1259 flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
yasin sapli9e4c5092022-02-01 13:52:33 +00001260 // update the flowids for a gem to the KVstore
yasin saplibddc2d72022-02-08 13:10:17 +00001261 return rsrcMgr.UpdateFlowIDsForGem(ctx, gemPortID, flowIDs)
yasin sapli9e4c5092022-02-01 13:52:33 +00001262}
1263
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301264//UpdateFlowIDsForGem updates flow id per gemport
yasin saplibddc2d72022-02-08 13:10:17 +00001265func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301266 var val []byte
yasin saplibddc2d72022-02-08 13:10:17 +00001267 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301268
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001269 if flowIDs == nil {
Girish Gowdra950326e2021-11-05 12:43:24 -07001270 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1271 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1272 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001273 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301274 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001275 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301276 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001277 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301278 return err
1279 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001280
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001281 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1282 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301283 return err
1284 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001285 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001286
1287 // update cache
1288 rsrcMgr.flowIDsForGemLock.Lock()
1289 rsrcMgr.flowIDsForGem[gem] = flowIDs
1290 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301291 return nil
1292}
1293
1294//DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
yasin saplibddc2d72022-02-08 13:10:17 +00001295func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, gem uint32) error {
1296 path := fmt.Sprintf(FlowIDsForGem, rsrcMgr.PonIntfID, gem)
Gamze Abaka745ccb72021-11-18 11:29:58 +00001297 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1298 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1299 return err
1300 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001301 // update cache
1302 rsrcMgr.flowIDsForGemLock.Lock()
1303 delete(rsrcMgr.flowIDsForGem, gem)
1304 rsrcMgr.flowIDsForGemLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +00001305 return nil
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301306}
Esin Karamanccb714b2019-11-29 15:02:06 +00001307
Girish Gowdra950326e2021-11-05 12:43:24 -07001308//DeleteAllFlowIDsForGemForIntf deletes all the flow ids associated for all the gems on the given pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001309func (rsrcMgr *OpenOltResourceMgr) DeleteAllFlowIDsForGemForIntf(ctx context.Context) error {
1310 path := fmt.Sprintf(FlowIDsForGemPathPrefix, rsrcMgr.PonIntfID)
Girish Gowdra950326e2021-11-05 12:43:24 -07001311
yasin saplibddc2d72022-02-08 13:10:17 +00001312 logger.Debugw(ctx, "delete-flow-ids-for-gem-for-pon-intf", log.Fields{"intfID": rsrcMgr.PonIntfID})
Girish Gowdra950326e2021-11-05 12:43:24 -07001313 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1314 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1315 return err
1316 }
1317
1318 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1319 rsrcMgr.flowIDsForGemLock.Lock()
1320 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
1321 rsrcMgr.flowIDsForGemLock.Unlock()
1322 return nil
1323}
1324
Esin Karamanccb714b2019-11-29 15:02:06 +00001325//GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001326func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001327 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001328 var val []byte
1329
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001330 rsrcMgr.mcastQueueForIntfLock.RLock()
1331 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1332 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1333 return rsrcMgr.mcastQueueForIntf, nil
1334 }
1335 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1336
1337 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001338 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001339 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001340 return nil, err
1341 }
1342 if kvPair != nil && kvPair.Value != nil {
1343 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001344 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001345 return nil, err
1346 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001347 rsrcMgr.mcastQueueForIntfLock.Lock()
1348 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1349 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1350 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001351 return nil, err
1352 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001353 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001354 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001355 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001356}
1357
1358//AddMcastQueueForIntf adds multicast queue for pon interface
yasin saplibddc2d72022-02-08 13:10:17 +00001359func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001360 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001361 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001362
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001363 // Load local cache from kv store the first time
1364 rsrcMgr.mcastQueueForIntfLock.RLock()
1365 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1366 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1367 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1368 if err != nil {
yasin saplibddc2d72022-02-08 13:10:17 +00001369 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 -07001370 return err
1371 }
1372 } else {
1373 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1374 }
1375
1376 // Update KV store
1377 rsrcMgr.mcastQueueForIntfLock.Lock()
yasin saplibddc2d72022-02-08 13:10:17 +00001378 rsrcMgr.mcastQueueForIntf[rsrcMgr.PonIntfID] = []uint32{gem, servicePriority}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001379 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001380 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001381 rsrcMgr.mcastQueueForIntfLock.Unlock()
1382 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001383 return err
1384 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001385 rsrcMgr.mcastQueueForIntfLock.Unlock()
1386
1387 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1388 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001389 return err
1390 }
yasin saplibddc2d72022-02-08 13:10:17 +00001391 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 +00001392 return nil
1393}
1394
Girish Gowdraf3728b12022-02-02 21:46:51 -08001395//DeleteMcastQueueForIntf deletes multicast queue info for the current pon interface from kvstore
1396func (rsrcMgr *OpenOltResourceMgr) DeleteMcastQueueForIntf(ctx context.Context) {
1397 path := McastQueuesForIntf
1398
1399 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1400 logger.Errorw(ctx, "Failed to delete multicast queue info from kvstore", log.Fields{"err": err, "interfaceId": rsrcMgr.PonIntfID})
1401 return
1402 }
1403 logger.Debugw(ctx, "deleted multicast queue info from KV store successfully", log.Fields{"interfaceId": rsrcMgr.PonIntfID})
1404}
1405
Esin Karamanccb714b2019-11-29 15:02:06 +00001406//AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001407func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001408 var Value []byte
1409 var err error
1410 var path string
1411 if cached {
1412 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1413 } else {
1414 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1415 }
1416 //build group info object
1417 var outPorts []uint32
1418 for _, ofBucket := range groupEntry.Desc.Buckets {
1419 for _, ofAction := range ofBucket.Actions {
1420 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1421 outPorts = append(outPorts, ofAction.GetOutput().Port)
1422 }
1423 }
1424 }
1425 groupInfo := GroupInfo{
1426 GroupID: groupEntry.Desc.GroupId,
1427 OutPorts: outPorts,
1428 }
1429
1430 Value, err = json.Marshal(groupInfo)
1431
1432 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001433 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001434 return err
1435 }
1436
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001437 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001438 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001439 return err
1440 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001441
1442 // update cache
1443 rsrcMgr.groupInfoLock.Lock()
1444 rsrcMgr.groupInfo[path] = &groupInfo
1445 rsrcMgr.groupInfoLock.Unlock()
Esin Karamanccb714b2019-11-29 15:02:06 +00001446 return nil
1447}
1448
1449//RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001450func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001451 var path string
1452 if cached {
1453 path = fmt.Sprintf(FlowGroupCached, groupID)
1454 } else {
1455 path = fmt.Sprintf(FlowGroup, groupID)
1456 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001457
1458 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001459 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001460 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001461 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001462
1463 // update cache
1464 rsrcMgr.groupInfoLock.Lock()
1465 delete(rsrcMgr.groupInfo, path)
1466 rsrcMgr.groupInfoLock.Unlock()
Esin Karamand519bbf2020-07-01 11:16:03 +00001467 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001468}
1469
1470//GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1471//fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
1472// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001473func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001474 var groupInfo GroupInfo
1475 var path string
1476 if cached {
1477 path = fmt.Sprintf(FlowGroupCached, groupID)
1478 } else {
1479 path = fmt.Sprintf(FlowGroup, groupID)
1480 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001481
1482 // read from cache
1483 rsrcMgr.groupInfoLock.RLock()
1484 gi, ok := rsrcMgr.groupInfo[path]
1485 rsrcMgr.groupInfoLock.RUnlock()
1486 if ok {
1487 return true, *gi, nil
1488 }
1489
1490 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001491 if err != nil {
1492 return false, groupInfo, err
1493 }
1494 if kvPair != nil && kvPair.Value != nil {
1495 Val, err := kvstore.ToByte(kvPair.Value)
1496 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001497 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001498 return false, groupInfo, err
1499 }
1500 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001501 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001502 return false, groupInfo, err
1503 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001504 // update cache
1505 rsrcMgr.groupInfoLock.Lock()
1506 rsrcMgr.groupInfo[path] = &groupInfo
1507 rsrcMgr.groupInfoLock.Unlock()
1508
Esin Karamanccb714b2019-11-29 15:02:06 +00001509 return true, groupInfo, nil
1510 }
1511 return false, groupInfo, nil
1512}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001513
yasin sapli9e4c5092022-02-01 13:52:33 +00001514// GetOnuGemInfoList returns all gems in the onuGemInfo map
1515func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfoList(ctx context.Context) []OnuGemInfo {
1516 var onuGemInfoLst []OnuGemInfo
1517 rsrcMgr.onuGemInfoLock.RLock()
1518 defer rsrcMgr.onuGemInfoLock.RUnlock()
1519 for _, v := range rsrcMgr.onuGemInfo {
1520 onuGemInfoLst = append(onuGemInfoLst, *v)
1521 }
1522 return onuGemInfoLst
1523}
1524
yasin sapli9e4c5092022-02-01 13:52:33 +00001525func appendUnique64bit(slice []uint64, item uint64) []uint64 {
1526 for _, sliceElement := range slice {
1527 if sliceElement == item {
1528 return slice
1529 }
1530 }
1531 return append(slice, item)
1532}