blob: cfc755e1a037c023cf9353de0cfeafd91884546b [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}"
salmansiddiqui7ac62132019-08-22 03:58:50 +000085)
Abhilash S.L7f17e402019-03-15 17:40:41 +053086
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070087// FlowInfo holds the flow information
Abhilash S.L8ee90712019-04-29 16:24:22 +053088type FlowInfo struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -070089 Flow *openolt.Flow
90 IsSymmtricFlow bool
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053091}
92
93// OnuGemInfo holds onu information along with gem port list and uni port list
94type OnuGemInfo struct {
95 OnuID uint32
96 SerialNumber string
97 IntfID uint32
98 GemPorts []uint32
99 UniPorts []uint32
100}
101
102// PacketInInfoKey is the key for packet in gemport
103type PacketInInfoKey struct {
104 IntfID uint32
105 OnuID uint32
106 LogicalPort uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000107 VlanID uint16
108 Priority uint8
Abhilash S.L8ee90712019-04-29 16:24:22 +0530109}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110
Esin Karamanccb714b2019-11-29 15:02:06 +0000111// GroupInfo holds group information
112type GroupInfo struct {
113 GroupID uint32
114 OutPorts []uint32
115}
116
Girish Gowdraa482f272021-03-24 23:04:19 -0700117// MeterInfo store meter information at path <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
118type MeterInfo struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700119 RefCnt uint8 // number of flow references for this meter. When RefCnt is 0, the MeterInfo should be deleted.
120 MeterID uint32
Girish Gowdraa482f272021-03-24 23:04:19 -0700121}
122
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700123// OpenOltResourceMgr holds resource related information as provided below for each field
Abhilash S.L7f17e402019-03-15 17:40:41 +0530124type OpenOltResourceMgr struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700125 PonIntfID uint32
Neha Sharma3f221ae2020-04-29 19:02:12 +0000126 DeviceID string // OLT device id
127 Address string // Host and port of the kv store to connect to
128 Args string // args
129 KVStore *db.Backend // backend kv store connection handle
130 DeviceType string
131 DevInfo *openolt.DeviceInfo // device information
Girish Gowdru0c588b22019-04-23 23:24:56 -0400132 // array of pon resource managers per interface technology
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700133 PonRsrMgr *ponrmgr.PONResourceManager
Girish Gowdra38d533d2020-03-30 20:38:51 -0700134
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700135 // Local maps used for write-through-cache - start
136 flowIDsForOnu map[string][]uint64
137 flowIDsForOnuLock sync.RWMutex
138
139 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 sapli9e4c5092022-02-01 13:52:33 +0000247 if err := ResourceMgr.LoadLocalCacheFromKVStore(ctx, PonIntfID); err != nil {
248 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() {
256 rsrcMgr.flowIDsForOnu = make(map[string][]uint64)
257 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
258 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
259 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
260 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
261 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
262 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
263 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
264 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
265 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
266}
267
yasin sapli9e4c5092022-02-01 13:52:33 +0000268//LoadLocalCacheFromKVStore loads local maps
269func (rsrcMgr *OpenOltResourceMgr) LoadLocalCacheFromKVStore(ctx context.Context, PonIntfID uint32) error {
270
271 //List all the keys for OnuGemInfo
272 prefixPath := fmt.Sprintf(OnuGemInfoPathPathPrefix, PonIntfID)
273 keys, err := rsrcMgr.KVStore.List(ctx, prefixPath)
274 logger.Debug(ctx, "load-local-cache-from-KV-store-started")
275 if err != nil {
276 logger.Errorf(ctx, "failed-to-list-keys-from-path-%s", prefixPath)
277 return err
278 }
279 for path := range keys {
280 var Val []byte
281 var onugem OnuGemInfo
282 // Get rid of the path prefix
283 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
284 replacedWith := ""
285 path = strings.Replace(path, stringToBeReplaced, replacedWith, 1)
286
287 value, err := rsrcMgr.KVStore.Get(ctx, path)
288 if err != nil {
289 logger.Errorw(ctx, "failed-to-get-from-kv-store", log.Fields{"path": path})
290 return err
291 } else if value == nil {
292 logger.Debug(ctx, "no-onugeminfo-for-path", log.Fields{"path": path})
293 continue
294 }
295 if Val, err = kvstore.ToByte(value.Value); err != nil {
296 logger.Error(ctx, "failed-to-covert-to-byte-array")
297 return err
298 }
299 if err = json.Unmarshal(Val, &onugem); err != nil {
300 logger.Error(ctx, "failed-to-unmarshall")
301 return err
302 }
303 logger.Debugw(ctx, "found-onugeminfo-from-path", log.Fields{"path": path, "onuGemInfo": onugem})
304
305 rsrcMgr.onuGemInfoLock.Lock()
306 rsrcMgr.onuGemInfo[path] = &onugem
307 rsrcMgr.onuGemInfoLock.Unlock()
308
309 }
310 logger.Debug(ctx, "load-local-cache-from-KV-store-finished")
311 return nil
312}
313
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700314// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
315// device specific information. If KV doesn't exist
316// or is broader than the device, the device's information will
317// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700318func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700319 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700320 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
321 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
322 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
323
324 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
325 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
326 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
327 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
328 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530329
Girish Gowdru0c588b22019-04-23 23:24:56 -0400330 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700331 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
332 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
333 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
334 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
335 "intf_ids": techRange.IntfIds,
336 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700337 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700338 // FIXME: Remove hardcoding
Girish Gowdru0c588b22019-04-23 23:24:56 -0400339 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
340 ONUIDStart = RangePool.Start
341 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700342 ONUIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400343 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
344 AllocIDStart = RangePool.Start
345 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700346 AllocIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400347 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
348 GEMPortIDStart = RangePool.Start
349 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700350 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400351 }
352 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530353
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700354 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
355 AllocIDStart, AllocIDEnd, AllocIDShared,
356 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
357 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700358 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530359
Abhilash S.L7f17e402019-03-15 17:40:41 +0530360}
361
Devmalya Paul495b94a2019-08-27 19:42:00 -0400362// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700363func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
364 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
365 logger.Debug(ctx, "Failed to clear device resource pool")
366 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400367 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000368 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400369 return nil
370}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530371
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700372// GetONUID returns the available onuID for the given pon-port
373func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context, PonIntfID uint32) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400374 // Get ONU id for a provided pon interface ID.
Girish Gowdra76a1b092021-07-28 10:07:04 -0700375 onuID, err := rsrcMgr.TechprofileRef.GetResourceID(ctx, PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400376 ponrmgr.ONU_ID, 1)
377 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000378 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700379 PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200380 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400381 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700382 if len(onuID) > 0 {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700383 return onuID[0], err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400384 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530385
Girish Gowdra950326e2021-11-05 12:43:24 -0700386 return 0, fmt.Errorf("no-onu-id-allocated")
Abhilash S.L8ee90712019-04-29 16:24:22 +0530387}
388
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700389// GetCurrentFlowIDsForOnu fetches flow ID from the resource manager
390// Note: For flows which trap from the NNI and not really associated with any particular
391// ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700392func (rsrcMgr *OpenOltResourceMgr) GetCurrentFlowIDsForOnu(ctx context.Context, PonIntfID uint32, onuID int32, uniID int32) ([]uint64, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700393
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700394 subs := fmt.Sprintf("%d,%d,%d", PonIntfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700395 path := fmt.Sprintf(FlowIDPath, subs)
396
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700397 // fetch from cache
398 rsrcMgr.flowIDsForOnuLock.RLock()
399 flowIDsForOnu, ok := rsrcMgr.flowIDsForOnu[path]
400 rsrcMgr.flowIDsForOnuLock.RUnlock()
401
402 if ok {
403 return flowIDsForOnu, nil
404 }
405
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700406 var data []uint64
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700407 value, err := rsrcMgr.KVStore.Get(ctx, path)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700408 if err == nil {
409 if value != nil {
410 Val, _ := toByte(value.Value)
411 if err = json.Unmarshal(Val, &data); err != nil {
412 logger.Error(ctx, "Failed to unmarshal")
413 return nil, err
414 }
415 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -0700416 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700417 // update cache
418 rsrcMgr.flowIDsForOnuLock.Lock()
419 rsrcMgr.flowIDsForOnu[path] = data
420 rsrcMgr.flowIDsForOnuLock.Unlock()
421
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700422 return data, nil
Abhilash S.L8ee90712019-04-29 16:24:22 +0530423}
424
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700425// UpdateAllocIdsForOnu updates alloc ids in kv store for a given pon interface id, onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700426func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, ponPort uint32, onuID uint32, uniID uint32, allocIDs []uint32) error {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530427
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700428 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000429
430 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
431 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
432 if err := rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID, allocIDs); err != nil {
433 logger.Errorw(ctx, "Failed to update alloc ids for onu", log.Fields{"err": err})
434 return err
435 }
436
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700437 // update cache
438 rsrcMgr.allocIDsForOnuLock.Lock()
439 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
440 rsrcMgr.allocIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000441 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530442}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700443
444// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700445func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, intfID uint32, onuID uint32,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700446 uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530447
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700448 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530449
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700450 // fetch from cache
451 rsrcMgr.gemPortIDsForOnuLock.RLock()
452 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
453 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
454 if ok {
455 return gemIDs
456 }
457 /* Get gem ports for given pon interface , onu id and uni id. */
458 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
459
460 // update cache
461 rsrcMgr.gemPortIDsForOnuLock.Lock()
462 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
463 rsrcMgr.gemPortIDsForOnuLock.Unlock()
464
465 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530466}
467
Gamze Abakafee36392019-10-03 11:17:24 +0000468// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700469func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530470
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700471 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
472 // fetch from cache
473 rsrcMgr.allocIDsForOnuLock.RLock()
474 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
475 rsrcMgr.allocIDsForOnuLock.RUnlock()
476 if ok {
477 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400478 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700479 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
480
481 // update cache
482 rsrcMgr.allocIDsForOnuLock.Lock()
483 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
484 rsrcMgr.allocIDsForOnuLock.Unlock()
485
486 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000487}
488
489// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700490func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32) {
491 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000492 for i := 0; i < len(allocIDs); i++ {
493 if allocIDs[i] == allocID {
494 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
495 break
496 }
497 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700498 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000499 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700500 logger.Errorf(ctx, "Failed to Remove Alloc Id For Onu. intfID %d onuID %d uniID %d allocID %d",
Gamze Abakafee36392019-10-03 11:17:24 +0000501 intfID, onuID, uniID, allocID)
502 }
503}
504
505// RemoveGemPortIDForOnu removes the gem port id for given pon interface, onu id, uni id and gem port id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700506func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32) {
507 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000508 for i := 0; i < len(gemPortIDs); i++ {
509 if gemPortIDs[i] == gemPortID {
510 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
511 break
512 }
513 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700514 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000515 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700516 logger.Errorf(ctx, "Failed to Remove Gem Id For Onu. intfID %d onuID %d uniID %d gemPortId %d",
Gamze Abakafee36392019-10-03 11:17:24 +0000517 intfID, onuID, uniID, gemPortID)
518 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530519}
520
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700521// UpdateGEMPortIDsForOnu updates gemport ids on to the kv store for a given pon port, onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700522func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, ponPort uint32, onuID uint32,
523 uniID uint32, gemIDs []uint32) error {
524 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
Gamze Abaka745ccb72021-11-18 11:29:58 +0000525
526 if err := rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID, gemIDs); err != nil {
527 logger.Errorw(ctx, "Failed to update gem port ids for onu", log.Fields{"err": err})
528 return err
529 }
530
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700531 // update cache
532 rsrcMgr.gemPortIDsForOnuLock.Lock()
533 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
534 rsrcMgr.gemPortIDsForOnuLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +0000535 return nil
Abhilash S.L7f17e402019-03-15 17:40:41 +0530536}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700537
538// FreeonuID releases(make free) onu id for a particular pon-port
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700539func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, intfID uint32, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700540 if len(onuID) == 0 {
541 logger.Info(ctx, "onu id slice is nil, nothing to free")
542 return
543 }
Girish Gowdra76a1b092021-07-28 10:07:04 -0700544 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700545 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
546 "intf-id": intfID,
547 "onu-id": onuID,
548 "err": err.Error(),
549 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700550 } else {
551 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": intfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700552 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530553}
554
Gamze Abakafee36392019-10-03 11:17:24 +0000555// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
556// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700557// The caller should ensure that this is a blocking call and this operation is serialized for
558// the ONU so as not cause resource corruption since there are no mutexes used here.
Girish Gowdraf3728b12022-02-02 21:46:51 -0800559// Setting freeFromResourcePool to false will not clear it from the resource pool but only
560// clear it for the given pon/onu/uni
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700561func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, intfID uint32, onuID uint32,
Girish Gowdraf3728b12022-02-02 21:46:51 -0800562 uniID uint32, allocID uint32, freeFromResourcePool bool) {
Girish Gowdrab77ded92020-04-08 11:45:05 -0700563
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700564 rsrcMgr.RemoveAllocIDForOnu(ctx, intfID, onuID, uniID, allocID)
Girish Gowdraf3728b12022-02-02 21:46:51 -0800565 if freeFromResourcePool {
566 allocIDs := make([]uint32, 0)
567 allocIDs = append(allocIDs, allocID)
568 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
569 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
570 "intf-id": intfID,
571 "onu-id": onuID,
572 "err": err.Error(),
573 })
574 }
Matteo Scandolo84585372021-03-18 14:21:22 -0700575 }
Gamze Abakafee36392019-10-03 11:17:24 +0000576}
577
578// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
579// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700580// The caller should ensure that this is a blocking call and this operation is serialized for
581// the ONU so as not cause resource corruption since there are no mutexes used here.
582func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, intfID uint32, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000583 uniID uint32, gemPortID uint32) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700584 rsrcMgr.RemoveGemPortIDForOnu(ctx, intfID, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700585
Gamze Abakafee36392019-10-03 11:17:24 +0000586 gemPortIDs := make([]uint32, 0)
587 gemPortIDs = append(gemPortIDs, gemPortID)
Girish Gowdra76a1b092021-07-28 10:07:04 -0700588 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700589 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700590 "intf-id": intfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700591 "onu-id": onuID,
592 "err": err.Error(),
593 })
594 }
Gamze Abakafee36392019-10-03 11:17:24 +0000595}
596
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700597// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
598func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530599
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700600 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530601
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700602 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700603
Girish Gowdra76a1b092021-07-28 10:07:04 -0700604 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400605 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700606 AllocIDs); err != nil {
607 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
608 "intf-id": intfID,
609 "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.allocIDsForOnuLock.Lock()
616 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
617 rsrcMgr.allocIDsForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700618
Gamze Abaka745ccb72021-11-18 11:29:58 +0000619 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700620
Girish Gowdra76a1b092021-07-28 10:07:04 -0700621 if err := rsrcMgr.TechprofileRef.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400622 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700623 GEMPortIDs); err != nil {
624 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
625 "intf-id": intfID,
626 "onu-id": onuID,
627 "err": err.Error(),
628 })
629 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530630
Gamze Abaka745ccb72021-11-18 11:29:58 +0000631 // update cache
632 rsrcMgr.gemPortIDsForOnuLock.Lock()
633 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
634 rsrcMgr.gemPortIDsForOnuLock.Unlock()
635
Girish Gowdru0c588b22019-04-23 23:24:56 -0400636 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700637 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530638}
639
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700640// IsFlowOnKvStore checks if the given flowID is present on the kv store
641// Returns true if the flowID is found, otherwise it returns false
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700642func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700643 flowID uint64) bool {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530644
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700645 FlowIDs, err := rsrcMgr.GetCurrentFlowIDsForOnu(ctx, intfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700646 if err != nil {
647 // error logged in the called function
648 return false
649 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400650 if FlowIDs != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700651 logger.Debugw(ctx, "Found flowId(s) for this ONU", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700652 for _, id := range FlowIDs {
653 if flowID == id {
654 return true
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400655 }
656 }
657 }
658 return false
659}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400660
salmansiddiqui7ac62132019-08-22 03:58:50 +0000661// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700662// This path is formed as the following: {intfID, onuID, uniID}/tp_id
663func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
664 Path := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
665 // fetch from cache
666 rsrcMgr.techProfileIDsForOnuLock.RLock()
667 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
668 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
669 if ok {
670 return tpIDs
671 }
672 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400673 if err == nil {
674 if Value != nil {
675 Val, err := kvstore.ToByte(Value.Value)
676 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700677 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
678 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400679 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700680 if err = json.Unmarshal(Val, &tpIDs); err != nil {
681 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
682 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400683 }
684 }
685 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000686 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400687 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700688 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
689
690 // update cache
691 rsrcMgr.techProfileIDsForOnuLock.Lock()
692 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
693 rsrcMgr.techProfileIDsForOnuLock.Unlock()
694
695 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400696
697}
698
Gamze Abakafee36392019-10-03 11:17:24 +0000699// 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 -0700700// This path is formed as the following: {intfID, onuID, uniID}/tp_id
701func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
702 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700703
704 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
705 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400706 return err
707 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000708
709 // update cache
710 rsrcMgr.techProfileIDsForOnuLock.Lock()
711 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
712 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400713 return nil
714}
715
Gamze Abakafee36392019-10-03 11:17:24 +0000716// 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 -0700717// This path is formed as the following: {intfID, onuID, uniID}/tp_id
718func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, tpID uint32) error {
719 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000720 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700721 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000722 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
723 }
724 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700725 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700726
Gamze Abakafee36392019-10-03 11:17:24 +0000727 Value, err := json.Marshal(tpIDList)
728 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000729 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000730 return err
731 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700732 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
733 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000734 return err
735 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000736
737 // update cache
738 rsrcMgr.techProfileIDsForOnuLock.Lock()
739 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
740 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Gamze Abakafee36392019-10-03 11:17:24 +0000741 return err
742}
743
744// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700745// This path is formed as the following: {intfID, onuID, uniID}/tp_id
746func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32,
747 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400748 var Value []byte
749 var err error
750
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700751 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000752
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700753 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000754 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700755 if value == tpID {
756 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000757 return err
758 }
759 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700760 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
761 tpIDList = append(tpIDList, tpID)
762
Gamze Abakafee36392019-10-03 11:17:24 +0000763 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400764 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000765 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400766 return err
767 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700768 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
769 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400770 return err
771 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000772
773 // update cache
774 rsrcMgr.techProfileIDsForOnuLock.Lock()
775 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
776 rsrcMgr.techProfileIDsForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400777 return err
778}
779
Girish Gowdraa482f272021-03-24 23:04:19 -0700780// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000781// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700782func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
783 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400784 var Value []byte
785 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700786 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
787
Girish Gowdraa482f272021-03-24 23:04:19 -0700788 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400789 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000790 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400791 return err
792 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700793 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
794 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400795 return err
796 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000797
798 // update cache
799 rsrcMgr.meterInfoForOnuLock.Lock()
800 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
801 rsrcMgr.meterInfoForOnuLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700802 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400803 return err
804}
805
Girish Gowdraa482f272021-03-24 23:04:19 -0700806// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000807// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700808func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
809 uniID uint32, tpID uint32) (*MeterInfo, error) {
810 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
811
812 // get from cache
813 rsrcMgr.meterInfoForOnuLock.RLock()
814 val, ok := rsrcMgr.meterInfoForOnu[Path]
815 rsrcMgr.meterInfoForOnuLock.RUnlock()
816 if ok {
817 return val, nil
818 }
819
Girish Gowdraa482f272021-03-24 23:04:19 -0700820 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700821 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400822 if err == nil {
823 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700824 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000825 Val, er := kvstore.ToByte(Value.Value)
826 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700827 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000828 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400829 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700830 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700831 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000832 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400833 }
834 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000835 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400836 return nil, err
837 }
838 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400840
841 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700842 // update cache
843 rsrcMgr.meterInfoForOnuLock.Lock()
844 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
845 rsrcMgr.meterInfoForOnuLock.Unlock()
846
Girish Gowdraa482f272021-03-24 23:04:19 -0700847 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400848}
849
Girish Gowdraa482f272021-03-24 23:04:19 -0700850// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
851// When reference count becomes 0, it clears the meter information from the kv store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700852func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, Direction string,
853 intfID uint32, onuID uint32, uniID uint32, tpID uint32, increment bool) error {
854 meterInfo, err := rsrcMgr.GetMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID)
Girish Gowdra82c80982021-03-26 16:22:02 -0700855 if err != nil {
856 return err
857 } else if meterInfo == nil {
858 // If we are increasing the reference count, we expect the meter information to be present on KV store.
859 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
860 if increment {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700861 logger.Errorf(ctx, "error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", intfID, onuID, uniID, tpID, Direction)
862 return fmt.Errorf("error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", intfID, onuID, uniID, tpID, Direction)
Girish Gowdra82c80982021-03-26 16:22:02 -0700863 }
864 logger.Warnw(ctx, "meter is already cleared",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700865 log.Fields{"intfID": intfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700866 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700867 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700868
Girish Gowdraa482f272021-03-24 23:04:19 -0700869 if increment {
870 meterInfo.RefCnt++
871 } else {
872 meterInfo.RefCnt--
Girish Gowdraa482f272021-03-24 23:04:19 -0700873 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700874 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700875 return err
876 }
877 return nil
878}
879
880// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000881// This path is formed as the following: <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700882func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
883 uniID uint32, tpID uint32) error {
884 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
885
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700886 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000887 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400888 return err
889 }
Gamze Abaka745ccb72021-11-18 11:29:58 +0000890
891 // update cache
892 rsrcMgr.meterInfoForOnuLock.Lock()
893 delete(rsrcMgr.meterInfoForOnu, Path)
894 rsrcMgr.meterInfoForOnuLock.Unlock()
Manikkaraj kb1d51442019-07-23 10:41:02 -0400895 return nil
896}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000897
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700898//AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
899func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
900 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
901 if err != nil || onugem == nil || onugem.SerialNumber == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530903 return err
904 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700905 if onugem.OnuID == onuID {
906 for _, gem := range onugem.GemPorts {
907 if gem == gemPort {
908 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
909 return nil
910 }
911 }
912 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
913 onugem.GemPorts = append(onugem.GemPorts, gemPort)
914 } else {
915 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
916 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530917 }
918
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700919 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530920 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530922 return err
923 }
924 return err
925}
926
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700927//RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
928func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
929 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
930 if err != nil || onugem == nil || onugem.SerialNumber == "" {
931 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
932 return err
933 }
934 updated := false
935 if onugem.OnuID == onuID {
936 for i, gem := range onugem.GemPorts {
937 if gem == gemPort {
938 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
939 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
940 updated = true
941 break
942 }
943 }
944 } else {
945 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
946 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
947 }
948 if updated {
949 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
950 if err != nil {
951 logger.Error(ctx, "Failed to add onugem to kv store")
952 return err
953 }
954 } else {
955 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
956 }
957 return nil
958}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530959
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700960//GetOnuGemInfo gets onu gem info from the kvstore per interface
961func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) (*OnuGemInfo, error) {
962 var err error
963 var Val []byte
964 var onugem OnuGemInfo
965
966 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
967
968 rsrcMgr.onuGemInfoLock.RLock()
969 val, ok := rsrcMgr.onuGemInfo[path]
970 rsrcMgr.onuGemInfoLock.RUnlock()
971 if ok {
972 return val, nil
973 }
974 value, err := rsrcMgr.KVStore.Get(ctx, path)
975 if err != nil {
976 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
977 return nil, err
978 } else if value == nil {
979 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
980 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
981 }
982 if Val, err = kvstore.ToByte(value.Value); err != nil {
983 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530984 return nil, err
985 }
986
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700987 if err = json.Unmarshal(Val, &onugem); err != nil {
988 logger.Error(ctx, "Failed to unmarshall")
989 return nil, err
990 }
991 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
992 rsrcMgr.onuGemInfoLock.Lock()
993 rsrcMgr.onuGemInfo[path] = &onugem
994 rsrcMgr.onuGemInfoLock.Unlock()
995
996 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530997}
998
yasin sapli9e4c5092022-02-01 13:52:33 +0000999//AddNewOnuGemInfoToCacheAndKvStore function adds a new onu gem info to cache and kvstore
1000func (rsrcMgr *OpenOltResourceMgr) AddNewOnuGemInfoToCacheAndKvStore(ctx context.Context, intfID uint32, onuID uint32, serialNum string) error {
1001
1002 Path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
1003
1004 rsrcMgr.onuGemInfoLock.Lock()
1005 _, ok := rsrcMgr.onuGemInfo[Path]
1006 rsrcMgr.onuGemInfoLock.Unlock()
1007
1008 // If the ONU already exists in onuGemInfo list, nothing to do
1009 if ok {
1010 logger.Debugw(ctx, "onu-id-already-exists-in-cache", log.Fields{"onuID": onuID, "serialNum": serialNum})
1011 return nil
1012 }
1013
1014 onuGemInfo := OnuGemInfo{OnuID: onuID, SerialNumber: serialNum, IntfID: intfID}
1015
1016 if err := rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, onuGemInfo); err != nil {
1017 return err
1018 }
1019 logger.Infow(ctx, "added-onuinfo",
1020 log.Fields{
1021 "intf-id": intfID,
1022 "onu-id": onuID,
1023 "serial-num": serialNum,
1024 "onu": onuGemInfo,
1025 "device-id": rsrcMgr.DeviceID})
1026 return nil
1027}
1028
Chaitrashree G S1a55b882020-02-04 17:35:35 -05001029// AddOnuGemInfo adds onu info on to the kvstore per interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001030func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, onuGem OnuGemInfo) error {
1031
1032 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301033 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001034 Path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301035
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001036 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301037 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001038 logger.Error(ctx, "failed to Marshal")
1039 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301040 }
1041
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001042 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
1043 logger.Errorf(ctx, "Failed to update resource %s", Path)
1044 return err
1045 }
yasin sapli9e4c5092022-02-01 13:52:33 +00001046 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem, "Path": Path})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001047
1048 //update cache
1049 rsrcMgr.onuGemInfoLock.Lock()
1050 rsrcMgr.onuGemInfo[Path] = &onuGem
1051 rsrcMgr.onuGemInfoLock.Unlock()
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001052 return err
1053}
1054
1055// DelOnuGemInfo deletes the onugem info from kvstore per ONU
1056func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) error {
1057 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001058
1059 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1060 logger.Errorf(ctx, "failed to remove resource %s", path)
1061 return err
1062 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001063
1064 //update cache
1065 rsrcMgr.onuGemInfoLock.Lock()
1066 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
1067 delete(rsrcMgr.onuGemInfo, path)
1068 rsrcMgr.onuGemInfoLock.Unlock()
Andrea Campanellab83b39d2020-03-30 11:41:16 +02001069 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301070}
1071
Girish Gowdra950326e2021-11-05 12:43:24 -07001072//DeleteAllOnuGemInfoForIntf deletes all the all onu gem info on the given pon interface
1073func (rsrcMgr *OpenOltResourceMgr) DeleteAllOnuGemInfoForIntf(ctx context.Context, intfID uint32) error {
1074
1075 path := fmt.Sprintf(OnuGemInfoPathPathPrefix, intfID)
1076
1077 logger.Debugw(ctx, "delete-all-onu-gem-info-for-pon-intf", log.Fields{"intfID": intfID})
1078 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1079 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1080 return err
1081 }
1082
1083 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1084 rsrcMgr.onuGemInfoLock.Lock()
1085 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
1086 rsrcMgr.onuGemInfoLock.Unlock()
1087 return nil
1088}
1089
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301090// AddUniPortToOnuInfo adds uni port to the onuinfo kvstore. check if the uni is already present if not update the kv store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001091func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNo uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301092
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001093 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
1094 if err != nil || onugem == nil || onugem.SerialNumber == "" {
1095 logger.Warnf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301096 return
1097 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001098
1099 if onugem.OnuID == onuID {
1100 for _, uni := range onugem.UniPorts {
1101 if uni == portNo {
1102 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
1103 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301104 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301105 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001106 onugem.UniPorts = append(onugem.UniPorts, portNo)
1107 } else {
1108 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": intfID, "onuID": onuID})
1109 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301110 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001111 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301112 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001113 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301114 return
1115 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301116}
1117
Esin Karaman7fb80c22020-07-16 14:23:33 +00001118//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 -07001119func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301120
Girish Gowdra950326e2021-11-05 12:43:24 -07001121 path := fmt.Sprintf(OnuPacketInPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001122
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301123 Value, err := json.Marshal(gemPort)
1124 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001125 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301126 return
1127 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001128 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001129 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301130 return
1131 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001132
1133 // update cache
1134 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1135 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1136 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Neha Sharma96b7bf22020-06-15 10:37:32 +00001137 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301138}
1139
Esin Karaman7fb80c22020-07-16 14:23:33 +00001140// 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 -07001141func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301142
1143 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301144
Girish Gowdra950326e2021-11-05 12:43:24 -07001145 path := fmt.Sprintf(OnuPacketInPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
Esin Karaman7fb80c22020-07-16 14:23:33 +00001146 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001147 // get from cache
1148 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1149 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1150 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1151 if ok {
1152 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1153 return gemPort, nil
1154 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301155
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001156 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301157 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001158 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301159 return uint32(0), err
1160 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301162 return uint32(0), nil
1163 }
1164
1165 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001166 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301167 return uint32(0), err
1168 }
1169 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301171 return uint32(0), err
1172 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001173 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001174 // update cache
1175 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1176 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1177 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301178
1179 return gemPort, nil
1180}
1181
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001182//DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001183func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32) error {
Girish Gowdra950326e2021-11-05 12:43:24 -07001184 path := fmt.Sprintf(OnuPacketInPathPrefix, intfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001185 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001186 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001187 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1188 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001189 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001190
Gamze Abaka745ccb72021-11-18 11:29:58 +00001191 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1192 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1193 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1194 return err
1195 }
1196
Esin Karaman7fb80c22020-07-16 14:23:33 +00001197 //remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001198 for key := range value {
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001199 // Remove the PathPrefix from the path on KV key.
Girish Gowdra950326e2021-11-05 12:43:24 -07001200 // gemPortForPacketInInfo cache uses OnuPacketInPath as the key
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001201 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001202 replacedWith := ""
1203 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001204 // update cache
1205 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1206 delete(rsrcMgr.gemPortForPacketInInfo, key)
1207 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001208
serkant.uluderya4f5ed592020-12-17 20:57:59 +03001209 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1210 }
1211
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301212 return nil
1213}
1214
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001215//GetFlowIDsForGem gets the list of FlowIDs for the given gemport
1216func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) ([]uint64, error) {
1217 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
1218
1219 // get from cache
1220 rsrcMgr.flowIDsForGemLock.RLock()
1221 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1222 rsrcMgr.flowIDsForGemLock.RUnlock()
1223 if ok {
1224 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301225 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301226
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001227 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301228 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001229 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1230 return nil, err
1231 } else if value == nil {
1232 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1233 return nil, nil
1234 }
1235 Val, err := kvstore.ToByte(value.Value)
1236 if err != nil {
1237 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301238 return nil, err
1239 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301240
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001241 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1242 logger.Error(ctx, "Failed to unmarshall")
1243 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301244 }
1245
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001246 // update cache
1247 rsrcMgr.flowIDsForGemLock.Lock()
1248 rsrcMgr.flowIDsForGem[gem] = flowIDs
1249 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301250
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001251 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301252}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301253
yasin sapli9e4c5092022-02-01 13:52:33 +00001254// IsGemPortUsedByAnotherFlow returns true if given gem is used by another flow
1255func (rsrcMgr *OpenOltResourceMgr) IsGemPortUsedByAnotherFlow(gemPortID uint32, flowID uint64) bool {
1256 rsrcMgr.flowIDsForGemLock.RLock()
1257 flowIDList := rsrcMgr.flowIDsForGem[gemPortID]
1258 rsrcMgr.flowIDsForGemLock.RUnlock()
1259 for _, id := range flowIDList {
1260 if flowID != id {
1261 return true
1262 }
1263 }
1264 return false
1265}
1266
1267// RegisterFlowIDForGem updates both cache and KV store for flowIDsForGem map
1268func (rsrcMgr *OpenOltResourceMgr) RegisterFlowIDForGem(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
1269 // get from cache
1270 rsrcMgr.flowIDsForGemLock.RLock()
1271 flowIDs, ok := rsrcMgr.flowIDsForGem[gemPortID]
1272 rsrcMgr.flowIDsForGemLock.RUnlock()
1273 if !ok {
1274 flowIDs = []uint64{flowFromCore.Id}
1275 } else {
1276 flowIDs = appendUnique64bit(flowIDs, flowFromCore.Id)
1277 }
1278 // update the flowids for a gem to the KVstore
1279 return rsrcMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDs)
1280}
1281
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301282//UpdateFlowIDsForGem updates flow id per gemport
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001283func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, intf uint32, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301284 var val []byte
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001285 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301286
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001287 if flowIDs == nil {
Girish Gowdra950326e2021-11-05 12:43:24 -07001288 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1289 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1290 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001291 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301292 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001293 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301294 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001295 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301296 return err
1297 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001298
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001299 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1300 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301301 return err
1302 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001303 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Gamze Abaka745ccb72021-11-18 11:29:58 +00001304
1305 // update cache
1306 rsrcMgr.flowIDsForGemLock.Lock()
1307 rsrcMgr.flowIDsForGem[gem] = flowIDs
1308 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301309 return nil
1310}
1311
1312//DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
Gamze Abaka745ccb72021-11-18 11:29:58 +00001313func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001314 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
Gamze Abaka745ccb72021-11-18 11:29:58 +00001315 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1316 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1317 return err
1318 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001319 // update cache
1320 rsrcMgr.flowIDsForGemLock.Lock()
1321 delete(rsrcMgr.flowIDsForGem, gem)
1322 rsrcMgr.flowIDsForGemLock.Unlock()
Gamze Abaka745ccb72021-11-18 11:29:58 +00001323 return nil
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301324}
Esin Karamanccb714b2019-11-29 15:02:06 +00001325
Girish Gowdra950326e2021-11-05 12:43:24 -07001326//DeleteAllFlowIDsForGemForIntf deletes all the flow ids associated for all the gems on the given pon interface
1327func (rsrcMgr *OpenOltResourceMgr) DeleteAllFlowIDsForGemForIntf(ctx context.Context, intfID uint32) error {
1328
1329 path := fmt.Sprintf(FlowIDsForGemPathPrefix, intfID)
1330
1331 logger.Debugw(ctx, "delete-flow-ids-for-gem-for-pon-intf", log.Fields{"intfID": intfID})
1332 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1333 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1334 return err
1335 }
1336
1337 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1338 rsrcMgr.flowIDsForGemLock.Lock()
1339 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
1340 rsrcMgr.flowIDsForGemLock.Unlock()
1341 return nil
1342}
1343
Esin Karamanccb714b2019-11-29 15:02:06 +00001344//GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001345func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001346 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001347 var val []byte
1348
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001349 rsrcMgr.mcastQueueForIntfLock.RLock()
1350 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1351 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1352 return rsrcMgr.mcastQueueForIntf, nil
1353 }
1354 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1355
1356 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001357 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001359 return nil, err
1360 }
1361 if kvPair != nil && kvPair.Value != nil {
1362 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001363 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001364 return nil, err
1365 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001366 rsrcMgr.mcastQueueForIntfLock.Lock()
1367 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1368 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1369 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001370 return nil, err
1371 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001372 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001373 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001374 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001375}
1376
1377//AddMcastQueueForIntf adds multicast queue for pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001378func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, intf uint32, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001379 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001380 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001381
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001382 // Load local cache from kv store the first time
1383 rsrcMgr.mcastQueueForIntfLock.RLock()
1384 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1385 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1386 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1387 if err != nil {
1388 logger.Errorw(ctx, "Failed to get multicast queue info for interface", log.Fields{"err": err, "intf": intf})
1389 return err
1390 }
1391 } else {
1392 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1393 }
1394
1395 // Update KV store
1396 rsrcMgr.mcastQueueForIntfLock.Lock()
1397 rsrcMgr.mcastQueueForIntf[intf] = []uint32{gem, servicePriority}
1398 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001399 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001400 rsrcMgr.mcastQueueForIntfLock.Unlock()
1401 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001402 return err
1403 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001404 rsrcMgr.mcastQueueForIntfLock.Unlock()
1405
1406 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1407 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001408 return err
1409 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001410 logger.Debugw(ctx, "added multicast queue info to KV store successfully", log.Fields{"path": path, "interfaceId": intf, "gem": gem, "svcPrior": servicePriority})
Esin Karamanccb714b2019-11-29 15:02:06 +00001411 return nil
1412}
1413
Girish Gowdraf3728b12022-02-02 21:46:51 -08001414//DeleteMcastQueueForIntf deletes multicast queue info for the current pon interface from kvstore
1415func (rsrcMgr *OpenOltResourceMgr) DeleteMcastQueueForIntf(ctx context.Context) {
1416 path := McastQueuesForIntf
1417
1418 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1419 logger.Errorw(ctx, "Failed to delete multicast queue info from kvstore", log.Fields{"err": err, "interfaceId": rsrcMgr.PonIntfID})
1420 return
1421 }
1422 logger.Debugw(ctx, "deleted multicast queue info from KV store successfully", log.Fields{"interfaceId": rsrcMgr.PonIntfID})
1423}
1424
Esin Karamanccb714b2019-11-29 15:02:06 +00001425//AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001426func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001427 var Value []byte
1428 var err error
1429 var path string
1430 if cached {
1431 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1432 } else {
1433 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1434 }
1435 //build group info object
1436 var outPorts []uint32
1437 for _, ofBucket := range groupEntry.Desc.Buckets {
1438 for _, ofAction := range ofBucket.Actions {
1439 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1440 outPorts = append(outPorts, ofAction.GetOutput().Port)
1441 }
1442 }
1443 }
1444 groupInfo := GroupInfo{
1445 GroupID: groupEntry.Desc.GroupId,
1446 OutPorts: outPorts,
1447 }
1448
1449 Value, err = json.Marshal(groupInfo)
1450
1451 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001452 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001453 return err
1454 }
1455
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001456 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001457 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001458 return err
1459 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001460
1461 // update cache
1462 rsrcMgr.groupInfoLock.Lock()
1463 rsrcMgr.groupInfo[path] = &groupInfo
1464 rsrcMgr.groupInfoLock.Unlock()
Esin Karamanccb714b2019-11-29 15:02:06 +00001465 return nil
1466}
1467
1468//RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001469func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001470 var path string
1471 if cached {
1472 path = fmt.Sprintf(FlowGroupCached, groupID)
1473 } else {
1474 path = fmt.Sprintf(FlowGroup, groupID)
1475 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001476
1477 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001478 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001479 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001480 }
Gamze Abaka745ccb72021-11-18 11:29:58 +00001481
1482 // update cache
1483 rsrcMgr.groupInfoLock.Lock()
1484 delete(rsrcMgr.groupInfo, path)
1485 rsrcMgr.groupInfoLock.Unlock()
Esin Karamand519bbf2020-07-01 11:16:03 +00001486 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001487}
1488
1489//GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1490//fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
1491// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001492func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001493 var groupInfo GroupInfo
1494 var path string
1495 if cached {
1496 path = fmt.Sprintf(FlowGroupCached, groupID)
1497 } else {
1498 path = fmt.Sprintf(FlowGroup, groupID)
1499 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001500
1501 // read from cache
1502 rsrcMgr.groupInfoLock.RLock()
1503 gi, ok := rsrcMgr.groupInfo[path]
1504 rsrcMgr.groupInfoLock.RUnlock()
1505 if ok {
1506 return true, *gi, nil
1507 }
1508
1509 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001510 if err != nil {
1511 return false, groupInfo, err
1512 }
1513 if kvPair != nil && kvPair.Value != nil {
1514 Val, err := kvstore.ToByte(kvPair.Value)
1515 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001516 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001517 return false, groupInfo, err
1518 }
1519 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001520 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001521 return false, groupInfo, err
1522 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001523 // update cache
1524 rsrcMgr.groupInfoLock.Lock()
1525 rsrcMgr.groupInfo[path] = &groupInfo
1526 rsrcMgr.groupInfoLock.Unlock()
1527
Esin Karamanccb714b2019-11-29 15:02:06 +00001528 return true, groupInfo, nil
1529 }
1530 return false, groupInfo, nil
1531}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001532
yasin sapli9e4c5092022-02-01 13:52:33 +00001533// GetOnuGemInfoList returns all gems in the onuGemInfo map
1534func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfoList(ctx context.Context) []OnuGemInfo {
1535 var onuGemInfoLst []OnuGemInfo
1536 rsrcMgr.onuGemInfoLock.RLock()
1537 defer rsrcMgr.onuGemInfoLock.RUnlock()
1538 for _, v := range rsrcMgr.onuGemInfo {
1539 onuGemInfoLst = append(onuGemInfoLst, *v)
1540 }
1541 return onuGemInfoLst
1542}
1543
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001544// toByte converts an interface value to a []byte. The interface should either be of
1545// a string type or []byte. Otherwise, an error is returned.
1546func toByte(value interface{}) ([]byte, error) {
1547 switch t := value.(type) {
1548 case []byte:
1549 return value.([]byte), nil
1550 case string:
1551 return []byte(value.(string)), nil
1552 default:
1553 return nil, fmt.Errorf("unexpected-type-%T", t)
1554 }
1555}
yasin sapli9e4c5092022-02-01 13:52:33 +00001556
1557func appendUnique64bit(slice []uint64, item uint64) []uint64 {
1558 for _, sliceElement := range slice {
1559 if sliceElement == item {
1560 return slice
1561 }
1562 }
1563 return append(slice, item)
1564}