blob: 15ef9013dadc1728e5ddd479ed0fe26078903fc9 [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
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070029 "github.com/opencord/voltha-lib-go/v5/pkg/db"
30 "github.com/opencord/voltha-lib-go/v5/pkg/db/kvstore"
31 "github.com/opencord/voltha-lib-go/v5/pkg/log"
32 ponrmgr "github.com/opencord/voltha-lib-go/v5/pkg/ponresourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070033 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
34 "github.com/opencord/voltha-protos/v4/go/openolt"
Abhilash S.L7f17e402019-03-15 17:40:41 +053035)
36
salmansiddiqui7ac62132019-08-22 03:58:50 +000037const (
38 // KvstoreTimeout specifies the time out for KV Store Connection
Neha Sharmacc656962020-04-14 14:26:11 +000039 KvstoreTimeout = 5 * time.Second
Matteo Scandolodfa7a972020-11-06 13:03:40 -080040 // BasePathKvStore - <pathPrefix>/openolt/<device_id>
41 BasePathKvStore = "%s/openolt/{%s}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070042 // tpIDPathSuffix - <(pon_id, onu_id, uni_id)>/tp_id
43 tpIDPathSuffix = "{%d,%d,%d}/tp_id"
Gamze Abakafee36392019-10-03 11:17:24 +000044 //MeterIDPathSuffix - <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
45 MeterIDPathSuffix = "{%d,%d,%d}/{%d}/meter_id/{%s}"
Girish Gowdra1cd96d82021-11-05 09:56:26 -070046
47 // OnuPacketInPathPrefix - path prefix where ONU packet-in vlanID/PCP is stored
Girish Gowdraa09aeab2020-09-14 16:30:52 -070048 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}
Girish Gowdra1cd96d82021-11-05 09:56:26 -070049 OnuPacketInPathPrefix = "onu_packetin/{%d,%d,%d}"
50 // OnuPacketInPath path on the kvstore to store packetin gemport,which will be used for packetin, packetout
Girish Gowdraa09aeab2020-09-14 16:30:52 -070051 //format: onu_packetin/{<intfid>,<onuid>,<logicalport>}/{<vlanId>,<priority>}
Girish Gowdra1cd96d82021-11-05 09:56:26 -070052 OnuPacketInPath = OnuPacketInPathPrefix + "/{%d,%d}"
53
54 //FlowIDsForGemPathPrefix format: flowids_for_gem/<intfid>
55 FlowIDsForGemPathPrefix = "flowids_per_gem/{%d}"
56 //FlowIDsForGem flowids_for_gem/<intfid>/<gemport-id>
57 FlowIDsForGem = FlowIDsForGemPathPrefix + "/{%d}"
58
Esin Karamanccb714b2019-11-29 15:02:06 +000059 //McastQueuesForIntf multicast queues for pon interfaces
60 McastQueuesForIntf = "mcast_qs_for_int"
61 //FlowGroup flow_groups/<flow_group_id>
62 // A group is stored under this path on the KV store after it has been installed to the device.
63 // It should also be deleted after it has been removed from the device accordingly.
64 FlowGroup = "flow_groups/{%d}"
65 //FlowGroupCached flow_groups_cached/<flow_group_id>
66 // When a group add request received, we create the group without setting any members to it since we cannot
67 // set any members to a group until it is associated with a multicast flow. It is a BAL limitation.
68 // When the related multicast flow has been created we perform set members operation for the group.
69 // That is why we need to keep the members of a group until the multicast flow creation request comes.
70 // We preserve the groups under "FlowGroupsCached" directory in the KV store temporarily. Having set members,
71 // we remove the group from the cached group store.
72 FlowGroupCached = "flow_groups_cached/{%d}"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070073
74 //FlowIDPath - Path on the KV store for storing list of Flow IDs for a given subscriber
75 //Format: BasePathKvStore/<(pon_intf_id, onu_id, uni_id)>/flow_ids
76 FlowIDPath = "{%s}/flow_ids"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070077
Girish Gowdra1cd96d82021-11-05 09:56:26 -070078 //OnuGemInfoPathPathPrefix format: onu_gem_info/<intfid>
79 OnuGemInfoPathPathPrefix = "onu_gem_info/{%d}"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070080 //OnuGemInfoPath is path on the kvstore to store onugem info map
Girish Gowdra1cd96d82021-11-05 09:56:26 -070081 //format: onu_gem_info/<intfid>/<onu_id>
82 OnuGemInfoPath = OnuGemInfoPathPathPrefix + "/{%d}"
salmansiddiqui7ac62132019-08-22 03:58:50 +000083)
Abhilash S.L7f17e402019-03-15 17:40:41 +053084
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070085// FlowInfo holds the flow information
Abhilash S.L8ee90712019-04-29 16:24:22 +053086type FlowInfo struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -070087 Flow *openolt.Flow
88 IsSymmtricFlow bool
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +053089}
90
91// OnuGemInfo holds onu information along with gem port list and uni port list
92type OnuGemInfo struct {
93 OnuID uint32
94 SerialNumber string
95 IntfID uint32
96 GemPorts []uint32
97 UniPorts []uint32
98}
99
100// PacketInInfoKey is the key for packet in gemport
101type PacketInInfoKey struct {
102 IntfID uint32
103 OnuID uint32
104 LogicalPort uint32
Esin Karaman7fb80c22020-07-16 14:23:33 +0000105 VlanID uint16
106 Priority uint8
Abhilash S.L8ee90712019-04-29 16:24:22 +0530107}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108
Esin Karamanccb714b2019-11-29 15:02:06 +0000109// GroupInfo holds group information
110type GroupInfo struct {
111 GroupID uint32
112 OutPorts []uint32
113}
114
Girish Gowdraa482f272021-03-24 23:04:19 -0700115// MeterInfo store meter information at path <(pon_id, onu_id, uni_id)>/<tp_id>/meter_id/<direction>
116type MeterInfo struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700117 RefCnt uint8 // number of flow references for this meter. When RefCnt is 0, the MeterInfo should be deleted.
118 MeterID uint32
Girish Gowdraa482f272021-03-24 23:04:19 -0700119}
120
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700121// OpenOltResourceMgr holds resource related information as provided below for each field
Abhilash S.L7f17e402019-03-15 17:40:41 +0530122type OpenOltResourceMgr struct {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700123 PonIntfID uint32
Neha Sharma3f221ae2020-04-29 19:02:12 +0000124 DeviceID string // OLT device id
125 Address string // Host and port of the kv store to connect to
126 Args string // args
127 KVStore *db.Backend // backend kv store connection handle
128 DeviceType string
129 DevInfo *openolt.DeviceInfo // device information
Girish Gowdru0c588b22019-04-23 23:24:56 -0400130 // array of pon resource managers per interface technology
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700131 PonRsrMgr *ponrmgr.PONResourceManager
Girish Gowdra38d533d2020-03-30 20:38:51 -0700132
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700133 // Local maps used for write-through-cache - start
134 flowIDsForOnu map[string][]uint64
135 flowIDsForOnuLock sync.RWMutex
136
137 allocIDsForOnu map[string][]uint32
138 allocIDsForOnuLock sync.RWMutex
139
140 gemPortIDsForOnu map[string][]uint32
141 gemPortIDsForOnuLock sync.RWMutex
142
143 techProfileIDsForOnu map[string][]uint32
144 techProfileIDsForOnuLock sync.RWMutex
145
146 meterInfoForOnu map[string]*MeterInfo
147 meterInfoForOnuLock sync.RWMutex
148
149 onuGemInfo map[string]*OnuGemInfo
150 onuGemInfoLock sync.RWMutex
151
152 gemPortForPacketInInfo map[string]uint32
153 gemPortForPacketInInfoLock sync.RWMutex
154
155 flowIDsForGem map[uint32][]uint64
156 flowIDsForGemLock sync.RWMutex
157
158 mcastQueueForIntf map[uint32][]uint32
159 mcastQueueForIntfLock sync.RWMutex
160 mcastQueueForIntfLoadedFromKvStore bool
161
162 groupInfo map[string]*GroupInfo
163 groupInfoLock sync.RWMutex
164 // Local maps used for write-through-cache - end
Abhilash S.L7f17e402019-03-15 17:40:41 +0530165}
166
Neha Sharma96b7bf22020-06-15 10:37:32 +0000167func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
168 logger.Infow(ctx, "kv-store-type", log.Fields{"store": storeType})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400169 switch storeType {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400170 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000171 return kvstore.NewEtcdClient(ctx, address, timeout, log.FatalLevel)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400172 }
173 return nil, errors.New("unsupported-kv-store")
Abhilash S.L7f17e402019-03-15 17:40:41 +0530174}
175
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700176// SetKVClient sets the KV client and return a kv backend
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800177func SetKVClient(ctx context.Context, backend string, addr string, DeviceID string, basePathKvStore string) *db.Backend {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400178 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
179 // issue between kv store and backend , core is not calling NewBackend directly
Neha Sharma96b7bf22020-06-15 10:37:32 +0000180 kvClient, err := newKVClient(ctx, backend, addr, KvstoreTimeout)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400181 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000182 logger.Fatalw(ctx, "Failed to init KV client\n", log.Fields{"err": err})
Girish Gowdru0c588b22019-04-23 23:24:56 -0400183 return nil
184 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700185 // return db.NewBackend(ctx, backend, addr, KvstoreTimeout, fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID))
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700186
sbarbaria8910ba2019-11-05 10:12:23 -0500187 kvbackend := &db.Backend{
Girish Gowdru0c588b22019-04-23 23:24:56 -0400188 Client: kvClient,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700189 StoreType: backend,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000190 Address: addr,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700191 Timeout: KvstoreTimeout,
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800192 PathPrefix: fmt.Sprintf(BasePathKvStore, basePathKvStore, DeviceID)}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530193
Girish Gowdru0c588b22019-04-23 23:24:56 -0400194 return kvbackend
Abhilash S.L7f17e402019-03-15 17:40:41 +0530195}
196
Gamze Abakafee36392019-10-03 11:17:24 +0000197// NewResourceMgr init a New resource manager instance which in turn instantiates pon resource manager
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700198// instances according to technology. Initializes the default resource ranges for all
199// the resources.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700200func 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 -0400201 var ResourceMgr OpenOltResourceMgr
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700202 logger.Debugf(ctx, "Init new resource manager , ponIf: %v, address: %s, device-id: %s", PonIntfID, KVStoreAddress, deviceID)
203 ResourceMgr.PonIntfID = PonIntfID
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700204 ResourceMgr.DeviceID = deviceID
Neha Sharma3f221ae2020-04-29 19:02:12 +0000205 ResourceMgr.Address = KVStoreAddress
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700206 ResourceMgr.DeviceType = deviceType
207 ResourceMgr.DevInfo = devInfo
Abhilash S.L7f17e402019-03-15 17:40:41 +0530208
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700209 Backend := kvStoreType
Matteo Scandolodfa7a972020-11-06 13:03:40 -0800210 ResourceMgr.KVStore = SetKVClient(ctx, Backend, ResourceMgr.Address, deviceID, basePathKvStore)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400211 if ResourceMgr.KVStore == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000212 logger.Error(ctx, "Failed to setup KV store")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400213 }
Girish Gowdra38d533d2020-03-30 20:38:51 -0700214
Girish Gowdru0c588b22019-04-23 23:24:56 -0400215 // TODO self.args = registry('main').get_args()
Abhilash S.L7f17e402019-03-15 17:40:41 +0530216
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700217 // Create a separate Resource Manager instance for each range. This assumes that
Girish Gowdru0c588b22019-04-23 23:24:56 -0400218 // each technology is represented by only a single range
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700219 for _, TechRange := range devInfo.Ranges {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700220 for _, intfID := range TechRange.IntfIds {
221 if intfID == PonIntfID {
222 technology := TechRange.Technology
223 logger.Debugf(ctx, "Device info technology %s, intf-id %v", technology, PonIntfID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000224
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700225 rsrMgr, err := ponrmgr.NewPONResourceManager(ctx, technology, deviceType, deviceID,
226 Backend, ResourceMgr.Address, basePathKvStore)
227 if err != nil {
228 logger.Errorf(ctx, "Failed to create pon resource manager instance for technology %s", technology)
229 return nil
230 }
231 ResourceMgr.PonRsrMgr = rsrMgr
232 // self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
233 InitializeDeviceResourceRangeAndPool(ctx, rsrMgr, TechRange, devInfo)
234 if err := ResourceMgr.PonRsrMgr.InitDeviceResourcePoolForIntf(ctx, intfID); err != nil {
235 logger.Fatal(ctx, "failed-to-initialize-device-resource-pool-intf-id-%v-device-id", ResourceMgr.PonIntfID, ResourceMgr.DeviceID)
236 return nil
237 }
238 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400239 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400240 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700241
242 ResourceMgr.InitLocalCache()
243
Neha Sharma96b7bf22020-06-15 10:37:32 +0000244 logger.Info(ctx, "Initialization of resource manager success!")
Girish Gowdru0c588b22019-04-23 23:24:56 -0400245 return &ResourceMgr
Abhilash S.L7f17e402019-03-15 17:40:41 +0530246}
247
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700248//InitLocalCache initializes local maps used for write-through-cache
249func (rsrcMgr *OpenOltResourceMgr) InitLocalCache() {
250 rsrcMgr.flowIDsForOnu = make(map[string][]uint64)
251 rsrcMgr.allocIDsForOnu = make(map[string][]uint32)
252 rsrcMgr.gemPortIDsForOnu = make(map[string][]uint32)
253 rsrcMgr.techProfileIDsForOnu = make(map[string][]uint32)
254 rsrcMgr.meterInfoForOnu = make(map[string]*MeterInfo)
255 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
256 rsrcMgr.gemPortForPacketInInfo = make(map[string]uint32)
257 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
258 rsrcMgr.mcastQueueForIntf = make(map[uint32][]uint32)
259 rsrcMgr.groupInfo = make(map[string]*GroupInfo)
260}
261
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700262// InitializeDeviceResourceRangeAndPool initializes the resource range pool according to the sharing type, then apply
263// device specific information. If KV doesn't exist
264// or is broader than the device, the device's information will
265// dictate the range limits
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700266func InitializeDeviceResourceRangeAndPool(ctx context.Context, ponRMgr *ponrmgr.PONResourceManager,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700267 techRange *openolt.DeviceInfo_DeviceResourceRanges, devInfo *openolt.DeviceInfo) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700268 // var ONUIDShared, AllocIDShared, GEMPortIDShared openolt.DeviceInfo_DeviceResourceRanges_Pool_SharingType
269 var ONUIDStart, ONUIDEnd, AllocIDStart, AllocIDEnd, GEMPortIDStart, GEMPortIDEnd uint32
270 var ONUIDShared, AllocIDShared, GEMPortIDShared, FlowIDShared uint32
271
272 // The below variables are just dummy and needed to pass as arguments to InitDefaultPONResourceRanges function.
273 // The openolt adapter does not need flowIDs to be managed as it is managed on the OLT device
274 // The UNI IDs are dynamically generated by openonu adapter for every discovered UNI.
275 var flowIDDummyStart, flowIDDummyEnd uint32 = 1, 2
276 var uniIDDummyStart, uniIDDummyEnd uint32 = 0, 1
Abhilash S.L7f17e402019-03-15 17:40:41 +0530277
Girish Gowdru0c588b22019-04-23 23:24:56 -0400278 // init the resource range pool according to the sharing type
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700279 logger.Debugw(ctx, "Device info init", log.Fields{"technology": techRange.Technology,
280 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd,
281 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
282 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
283 "intf_ids": techRange.IntfIds,
284 })
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700285 for _, RangePool := range techRange.Pools {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700286 // FIXME: Remove hardcoding
Girish Gowdru0c588b22019-04-23 23:24:56 -0400287 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
288 ONUIDStart = RangePool.Start
289 ONUIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700290 ONUIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400291 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
292 AllocIDStart = RangePool.Start
293 AllocIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700294 AllocIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400295 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
296 GEMPortIDStart = RangePool.Start
297 GEMPortIDEnd = RangePool.End
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700298 GEMPortIDShared = uint32(RangePool.Sharing)
Girish Gowdru0c588b22019-04-23 23:24:56 -0400299 }
300 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530301
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700302 ponRMgr.InitDefaultPONResourceRanges(ctx, ONUIDStart, ONUIDEnd, ONUIDShared,
303 AllocIDStart, AllocIDEnd, AllocIDShared,
304 GEMPortIDStart, GEMPortIDEnd, GEMPortIDShared,
305 flowIDDummyStart, flowIDDummyEnd, FlowIDShared, uniIDDummyStart, uniIDDummyEnd,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700306 devInfo.PonPorts, techRange.IntfIds)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530307
Abhilash S.L7f17e402019-03-15 17:40:41 +0530308}
309
Devmalya Paul495b94a2019-08-27 19:42:00 -0400310// Delete clears used resources for the particular olt device being deleted
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700311func (rsrcMgr *OpenOltResourceMgr) Delete(ctx context.Context, intfID uint32) error {
312 if err := rsrcMgr.PonRsrMgr.ClearDeviceResourcePoolForIntf(ctx, intfID); err != nil {
313 logger.Debug(ctx, "Failed to clear device resource pool")
314 return err
Devmalya Paul495b94a2019-08-27 19:42:00 -0400315 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000316 logger.Debug(ctx, "Cleared device resource pool")
Devmalya Paul495b94a2019-08-27 19:42:00 -0400317 return nil
318}
Abhilash S.L7f17e402019-03-15 17:40:41 +0530319
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700320// GetONUID returns the available onuID for the given pon-port
321func (rsrcMgr *OpenOltResourceMgr) GetONUID(ctx context.Context, PonIntfID uint32) (uint32, error) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400322 // Get ONU id for a provided pon interface ID.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700323 onuID, err := rsrcMgr.PonRsrMgr.TechProfileMgr.GetResourceID(ctx, PonIntfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400324 ponrmgr.ONU_ID, 1)
325 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000326 logger.Errorf(ctx, "Failed to get resource for interface %d for type %s",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700327 PonIntfID, ponrmgr.ONU_ID)
cbabuabf02352019-10-15 13:14:56 +0200328 return 0, err
Girish Gowdru0c588b22019-04-23 23:24:56 -0400329 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530330
Girish Gowdra1cd96d82021-11-05 09:56:26 -0700331 if len(onuID) > 0 {
332 return onuID[0], nil
333 }
334 return 0, fmt.Errorf("no-onu-id-allocated")
Abhilash S.L8ee90712019-04-29 16:24:22 +0530335}
336
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700337// GetCurrentFlowIDsForOnu fetches flow ID from the resource manager
338// Note: For flows which trap from the NNI and not really associated with any particular
339// 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 -0700340func (rsrcMgr *OpenOltResourceMgr) GetCurrentFlowIDsForOnu(ctx context.Context, PonIntfID uint32, onuID int32, uniID int32) ([]uint64, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700341
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700342 subs := fmt.Sprintf("%d,%d,%d", PonIntfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700343 path := fmt.Sprintf(FlowIDPath, subs)
344
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700345 // fetch from cache
346 rsrcMgr.flowIDsForOnuLock.RLock()
347 flowIDsForOnu, ok := rsrcMgr.flowIDsForOnu[path]
348 rsrcMgr.flowIDsForOnuLock.RUnlock()
349
350 if ok {
351 return flowIDsForOnu, nil
352 }
353
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700354 var data []uint64
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700355 value, err := rsrcMgr.KVStore.Get(ctx, path)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700356 if err == nil {
357 if value != nil {
358 Val, _ := toByte(value.Value)
359 if err = json.Unmarshal(Val, &data); err != nil {
360 logger.Error(ctx, "Failed to unmarshal")
361 return nil, err
362 }
363 }
Serkant Uluderya89ff40c2019-10-17 16:02:25 -0700364 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700365 // update cache
366 rsrcMgr.flowIDsForOnuLock.Lock()
367 rsrcMgr.flowIDsForOnu[path] = data
368 rsrcMgr.flowIDsForOnuLock.Unlock()
369
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700370 return data, nil
Abhilash S.L8ee90712019-04-29 16:24:22 +0530371}
372
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700373// 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 -0700374func (rsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(ctx context.Context, ponPort uint32, onuID uint32, uniID uint32, allocIDs []uint32) error {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530375
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700376 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
377 // update cache
378 rsrcMgr.allocIDsForOnuLock.Lock()
379 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
380 rsrcMgr.allocIDsForOnuLock.Unlock()
381
382 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
383 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
384 return rsrcMgr.PonRsrMgr.UpdateAllocIdsForOnu(ctx, intfOnuIDuniID,
385 allocIDs)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530386}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700387
388// GetCurrentGEMPortIDsForOnu returns gem ports for given pon interface , onu id and uni id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700389func (rsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(ctx context.Context, intfID uint32, onuID uint32,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700390 uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530391
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700392 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530393
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700394 // fetch from cache
395 rsrcMgr.gemPortIDsForOnuLock.RLock()
396 gemIDs, ok := rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID]
397 rsrcMgr.gemPortIDsForOnuLock.RUnlock()
398 if ok {
399 return gemIDs
400 }
401 /* Get gem ports for given pon interface , onu id and uni id. */
402 gemIDs = rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
403
404 // update cache
405 rsrcMgr.gemPortIDsForOnuLock.Lock()
406 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
407 rsrcMgr.gemPortIDsForOnuLock.Unlock()
408
409 return gemIDs
Abhilash S.L7f17e402019-03-15 17:40:41 +0530410}
411
Gamze Abakafee36392019-10-03 11:17:24 +0000412// GetCurrentAllocIDsForOnu returns alloc ids for given pon interface and onu id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700413func (rsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530414
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700415 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
416 // fetch from cache
417 rsrcMgr.allocIDsForOnuLock.RLock()
418 allocIDs, ok := rsrcMgr.allocIDsForOnu[intfOnuIDuniID]
419 rsrcMgr.allocIDsForOnuLock.RUnlock()
420 if ok {
421 return allocIDs
Girish Gowdru0c588b22019-04-23 23:24:56 -0400422 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700423 allocIDs = rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
424
425 // update cache
426 rsrcMgr.allocIDsForOnuLock.Lock()
427 rsrcMgr.allocIDsForOnu[intfOnuIDuniID] = allocIDs
428 rsrcMgr.allocIDsForOnuLock.Unlock()
429
430 return allocIDs
Gamze Abakafee36392019-10-03 11:17:24 +0000431}
432
433// RemoveAllocIDForOnu removes the alloc id for given pon interface, onu id, uni id and alloc id
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700434func (rsrcMgr *OpenOltResourceMgr) RemoveAllocIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32) {
435 allocIDs := rsrcMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000436 for i := 0; i < len(allocIDs); i++ {
437 if allocIDs[i] == allocID {
438 allocIDs = append(allocIDs[:i], allocIDs[i+1:]...)
439 break
440 }
441 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700442 err := rsrcMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000443 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700444 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 +0000445 intfID, onuID, uniID, allocID)
446 }
447}
448
449// 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 -0700450func (rsrcMgr *OpenOltResourceMgr) RemoveGemPortIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32) {
451 gemPortIDs := rsrcMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000452 for i := 0; i < len(gemPortIDs); i++ {
453 if gemPortIDs[i] == gemPortID {
454 gemPortIDs = append(gemPortIDs[:i], gemPortIDs[i+1:]...)
455 break
456 }
457 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700458 err := rsrcMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs)
Gamze Abakafee36392019-10-03 11:17:24 +0000459 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700460 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 +0000461 intfID, onuID, uniID, gemPortID)
462 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530463}
464
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700465// 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 -0700466func (rsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(ctx context.Context, ponPort uint32, onuID uint32,
467 uniID uint32, gemIDs []uint32) error {
468 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", ponPort, onuID, uniID)
469 // update cache
470 rsrcMgr.gemPortIDsForOnuLock.Lock()
471 rsrcMgr.gemPortIDsForOnu[intfOnuIDuniID] = gemIDs
472 rsrcMgr.gemPortIDsForOnuLock.Unlock()
473
474 // Note: in case the write to DB fails there could be inconsistent data between cache and db.
475 // Although this is highly unlikely with DB retries in place, this is something we have to deal with in the next release
476 return rsrcMgr.PonRsrMgr.UpdateGEMPortIDsForOnu(ctx, intfOnuIDuniID,
477 gemIDs)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530478
479}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700480
481// FreeonuID releases(make free) onu id for a particular pon-port
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700482func (rsrcMgr *OpenOltResourceMgr) FreeonuID(ctx context.Context, intfID uint32, onuID []uint32) {
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700483 if len(onuID) == 0 {
484 logger.Info(ctx, "onu id slice is nil, nothing to free")
485 return
486 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700487 if err := rsrcMgr.PonRsrMgr.TechProfileMgr.FreeResourceID(ctx, intfID, ponrmgr.ONU_ID, onuID); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700488 logger.Errorw(ctx, "error-while-freeing-onu-id", log.Fields{
489 "intf-id": intfID,
490 "onu-id": onuID,
491 "err": err.Error(),
492 })
Girish Gowdrab8f1b5a2021-06-27 20:42:40 -0700493 } else {
494 logger.Infow(ctx, "freed onu id", log.Fields{"intfID": intfID, "onuID": onuID})
Matteo Scandolo84585372021-03-18 14:21:22 -0700495 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530496}
497
Gamze Abakafee36392019-10-03 11:17:24 +0000498// FreeAllocID frees AllocID on the PON resource pool and also frees the allocID association
499// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700500// The caller should ensure that this is a blocking call and this operation is serialized for
501// the ONU so as not cause resource corruption since there are no mutexes used here.
502func (rsrcMgr *OpenOltResourceMgr) FreeAllocID(ctx context.Context, intfID uint32, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000503 uniID uint32, allocID uint32) {
Girish Gowdrab77ded92020-04-08 11:45:05 -0700504
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700505 rsrcMgr.RemoveAllocIDForOnu(ctx, intfID, onuID, uniID, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000506 allocIDs := make([]uint32, 0)
507 allocIDs = append(allocIDs, allocID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700508 if err := rsrcMgr.PonRsrMgr.TechProfileMgr.FreeResourceID(ctx, intfID, ponrmgr.ALLOC_ID, allocIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700509 logger.Errorw(ctx, "error-while-freeing-alloc-id", log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700510 "intf-id": intfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700511 "onu-id": onuID,
512 "err": err.Error(),
513 })
514 }
Gamze Abakafee36392019-10-03 11:17:24 +0000515}
516
517// FreeGemPortID frees GemPortID on the PON resource pool and also frees the gemPortID association
518// for the given OLT device.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700519// The caller should ensure that this is a blocking call and this operation is serialized for
520// the ONU so as not cause resource corruption since there are no mutexes used here.
521func (rsrcMgr *OpenOltResourceMgr) FreeGemPortID(ctx context.Context, intfID uint32, onuID uint32,
Gamze Abakafee36392019-10-03 11:17:24 +0000522 uniID uint32, gemPortID uint32) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700523 rsrcMgr.RemoveGemPortIDForOnu(ctx, intfID, onuID, uniID, gemPortID)
Girish Gowdrab77ded92020-04-08 11:45:05 -0700524
Gamze Abakafee36392019-10-03 11:17:24 +0000525 gemPortIDs := make([]uint32, 0)
526 gemPortIDs = append(gemPortIDs, gemPortID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700527 if err := rsrcMgr.PonRsrMgr.TechProfileMgr.FreeResourceID(ctx, intfID, ponrmgr.GEMPORT_ID, gemPortIDs); err != nil {
Matteo Scandolo84585372021-03-18 14:21:22 -0700528 logger.Errorw(ctx, "error-while-freeing-gem-port-id", log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700529 "intf-id": intfID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700530 "onu-id": onuID,
531 "err": err.Error(),
532 })
533 }
Gamze Abakafee36392019-10-03 11:17:24 +0000534}
535
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700536// FreePONResourcesForONU make the pon resources free for a given pon interface and onu id
537func (rsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530538
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700539 intfOnuIDuniID := fmt.Sprintf("%d,%d,%d", intfID, onuID, uniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530540
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700541 AllocIDs := rsrcMgr.PonRsrMgr.GetCurrentAllocIDForOnu(ctx, intfOnuIDuniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700542
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700543 rsrcMgr.allocIDsForOnuLock.Lock()
544 delete(rsrcMgr.allocIDsForOnu, intfOnuIDuniID)
545 rsrcMgr.allocIDsForOnuLock.Unlock()
546
547 if err := rsrcMgr.PonRsrMgr.TechProfileMgr.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400548 ponrmgr.ALLOC_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700549 AllocIDs); err != nil {
550 logger.Errorw(ctx, "error-while-freeing-all-alloc-ids-for-onu", log.Fields{
551 "intf-id": intfID,
552 "onu-id": onuID,
553 "err": err.Error(),
554 })
555 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530556
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700557 GEMPortIDs := rsrcMgr.PonRsrMgr.GetCurrentGEMPortIDsForOnu(ctx, intfOnuIDuniID)
558
559 rsrcMgr.gemPortIDsForOnuLock.Lock()
560 delete(rsrcMgr.gemPortIDsForOnu, intfOnuIDuniID)
561 rsrcMgr.gemPortIDsForOnuLock.Unlock()
562
563 if err := rsrcMgr.PonRsrMgr.TechProfileMgr.FreeResourceID(ctx, intfID,
Girish Gowdru0c588b22019-04-23 23:24:56 -0400564 ponrmgr.GEMPORT_ID,
Matteo Scandolo84585372021-03-18 14:21:22 -0700565 GEMPortIDs); err != nil {
566 logger.Errorw(ctx, "error-while-freeing-all-gem-port-ids-for-onu", log.Fields{
567 "intf-id": intfID,
568 "onu-id": onuID,
569 "err": err.Error(),
570 })
571 }
Abhilash S.L7f17e402019-03-15 17:40:41 +0530572
Girish Gowdru0c588b22019-04-23 23:24:56 -0400573 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700574 rsrcMgr.PonRsrMgr.RemoveResourceMap(ctx, intfOnuIDuniID)
Abhilash S.L7f17e402019-03-15 17:40:41 +0530575}
576
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700577// IsFlowOnKvStore checks if the given flowID is present on the kv store
578// Returns true if the flowID is found, otherwise it returns false
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700579func (rsrcMgr *OpenOltResourceMgr) IsFlowOnKvStore(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700580 flowID uint64) bool {
Abhilash S.L7f17e402019-03-15 17:40:41 +0530581
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700582 FlowIDs, err := rsrcMgr.GetCurrentFlowIDsForOnu(ctx, intfID, onuID, uniID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700583 if err != nil {
584 // error logged in the called function
585 return false
586 }
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400587 if FlowIDs != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700588 logger.Debugw(ctx, "Found flowId(s) for this ONU", log.Fields{"pon": intfID, "onuID": onuID, "uniID": uniID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700589 for _, id := range FlowIDs {
590 if flowID == id {
591 return true
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400592 }
593 }
594 }
595 return false
596}
Manikkaraj kb1d51442019-07-23 10:41:02 -0400597
salmansiddiqui7ac62132019-08-22 03:58:50 +0000598// GetTechProfileIDForOnu fetches Tech-Profile-ID from the KV-Store for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700599// This path is formed as the following: {intfID, onuID, uniID}/tp_id
600func (rsrcMgr *OpenOltResourceMgr) GetTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) []uint32 {
601 Path := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
602 // fetch from cache
603 rsrcMgr.techProfileIDsForOnuLock.RLock()
604 tpIDs, ok := rsrcMgr.techProfileIDsForOnu[Path]
605 rsrcMgr.techProfileIDsForOnuLock.RUnlock()
606 if ok {
607 return tpIDs
608 }
609 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400610 if err == nil {
611 if Value != nil {
612 Val, err := kvstore.ToByte(Value.Value)
613 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700614 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": err})
615 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400616 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700617 if err = json.Unmarshal(Val, &tpIDs); err != nil {
618 logger.Error(ctx, "Failed to unmarshal", log.Fields{"err": err})
619 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400620 }
621 }
622 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000623 logger.Errorf(ctx, "Failed to get TP id from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400624 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700625 logger.Debugf(ctx, "Getting TP id %d from path %s", tpIDs, Path)
626
627 // update cache
628 rsrcMgr.techProfileIDsForOnuLock.Lock()
629 rsrcMgr.techProfileIDsForOnu[Path] = tpIDs
630 rsrcMgr.techProfileIDsForOnuLock.Unlock()
631
632 return tpIDs
Manikkaraj kb1d51442019-07-23 10:41:02 -0400633
634}
635
Gamze Abakafee36392019-10-03 11:17:24 +0000636// 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 -0700637// This path is formed as the following: {intfID, onuID, uniID}/tp_id
638func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDsForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
639 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
640 // update cache
641 rsrcMgr.techProfileIDsForOnuLock.Lock()
642 delete(rsrcMgr.techProfileIDsForOnu, intfOnuUniID)
643 rsrcMgr.techProfileIDsForOnuLock.Unlock()
644
645 if err := rsrcMgr.KVStore.Delete(ctx, intfOnuUniID); err != nil {
646 logger.Errorw(ctx, "Failed to delete techprofile id resource in KV store", log.Fields{"path": intfOnuUniID})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400647 return err
648 }
649 return nil
650}
651
Gamze Abakafee36392019-10-03 11:17:24 +0000652// 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 -0700653// This path is formed as the following: {intfID, onuID, uniID}/tp_id
654func (rsrcMgr *OpenOltResourceMgr) RemoveTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, tpID uint32) error {
655 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000656 for i, tpIDInList := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700657 if tpIDInList == tpID {
Gamze Abakafee36392019-10-03 11:17:24 +0000658 tpIDList = append(tpIDList[:i], tpIDList[i+1:]...)
659 }
660 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700661 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
662 // update cache
663 rsrcMgr.techProfileIDsForOnuLock.Lock()
664 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
665 rsrcMgr.techProfileIDsForOnuLock.Unlock()
666
Gamze Abakafee36392019-10-03 11:17:24 +0000667 Value, err := json.Marshal(tpIDList)
668 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000669 logger.Error(ctx, "failed to Marshal")
Gamze Abakafee36392019-10-03 11:17:24 +0000670 return err
671 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700672 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
673 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000674 return err
675 }
676 return err
677}
678
679// UpdateTechProfileIDForOnu updates (put) already present tech-profile-id for the given onu based on the path
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700680// This path is formed as the following: {intfID, onuID, uniID}/tp_id
681func (rsrcMgr *OpenOltResourceMgr) UpdateTechProfileIDForOnu(ctx context.Context, intfID uint32, onuID uint32,
682 uniID uint32, tpID uint32) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400683 var Value []byte
684 var err error
685
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700686 intfOnuUniID := fmt.Sprintf(tpIDPathSuffix, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000687
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700688 tpIDList := rsrcMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000689 for _, value := range tpIDList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700690 if value == tpID {
691 logger.Debugf(ctx, "tpID %d is already in tpIdList for the path %s", tpID, intfOnuUniID)
Gamze Abakafee36392019-10-03 11:17:24 +0000692 return err
693 }
694 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700695 logger.Debugf(ctx, "updating tp id %d on path %s", tpID, intfOnuUniID)
696 tpIDList = append(tpIDList, tpID)
697
698 // update cache
699 rsrcMgr.techProfileIDsForOnuLock.Lock()
700 rsrcMgr.techProfileIDsForOnu[intfOnuUniID] = tpIDList
701 rsrcMgr.techProfileIDsForOnuLock.Unlock()
702
Gamze Abakafee36392019-10-03 11:17:24 +0000703 Value, err = json.Marshal(tpIDList)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400704 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000705 logger.Error(ctx, "failed to Marshal")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400706 return err
707 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700708 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
709 logger.Errorf(ctx, "Failed to update resource %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400710 return err
711 }
712 return err
713}
714
Girish Gowdraa482f272021-03-24 23:04:19 -0700715// StoreMeterInfoForOnu updates the meter id in the KV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000716// 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 -0700717func (rsrcMgr *OpenOltResourceMgr) StoreMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
718 uniID uint32, tpID uint32, meterInfo *MeterInfo) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400719 var Value []byte
720 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700721 intfOnuUniID := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
722
723 // update cache
724 rsrcMgr.meterInfoForOnuLock.Lock()
725 rsrcMgr.meterInfoForOnu[intfOnuUniID] = meterInfo
726 rsrcMgr.meterInfoForOnuLock.Unlock()
727
Girish Gowdraa482f272021-03-24 23:04:19 -0700728 Value, err = json.Marshal(*meterInfo)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400729 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000730 logger.Error(ctx, "failed to Marshal meter config")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400731 return err
732 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700733 if err = rsrcMgr.KVStore.Put(ctx, intfOnuUniID, Value); err != nil {
734 logger.Errorf(ctx, "Failed to store meter into KV store %s", intfOnuUniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400735 return err
736 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700737 logger.Debugw(ctx, "meter info updated successfully", log.Fields{"path": intfOnuUniID, "meter-info": meterInfo})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400738 return err
739}
740
Girish Gowdraa482f272021-03-24 23:04:19 -0700741// GetMeterInfoForOnu fetches the meter id from the kv store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000742// 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 -0700743func (rsrcMgr *OpenOltResourceMgr) GetMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
744 uniID uint32, tpID uint32) (*MeterInfo, error) {
745 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
746
747 // get from cache
748 rsrcMgr.meterInfoForOnuLock.RLock()
749 val, ok := rsrcMgr.meterInfoForOnu[Path]
750 rsrcMgr.meterInfoForOnuLock.RUnlock()
751 if ok {
752 return val, nil
753 }
754
Girish Gowdraa482f272021-03-24 23:04:19 -0700755 var meterInfo MeterInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700756 Value, err := rsrcMgr.KVStore.Get(ctx, Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400757 if err == nil {
758 if Value != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700759 logger.Debug(ctx, "Found meter info in KV store", log.Fields{"Direction": Direction})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000760 Val, er := kvstore.ToByte(Value.Value)
761 if er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700762 logger.Errorw(ctx, "Failed to convert into byte array", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000763 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400764 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700765 if er = json.Unmarshal(Val, &meterInfo); er != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700766 logger.Error(ctx, "Failed to unmarshal meter info", log.Fields{"err": er})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000767 return nil, er
Manikkaraj kb1d51442019-07-23 10:41:02 -0400768 }
769 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000770 logger.Debug(ctx, "meter-does-not-exists-in-KVStore")
Manikkaraj kb1d51442019-07-23 10:41:02 -0400771 return nil, err
772 }
773 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000774 logger.Errorf(ctx, "Failed to get Meter config from kvstore for path %s", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400775
776 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700777 // update cache
778 rsrcMgr.meterInfoForOnuLock.Lock()
779 rsrcMgr.meterInfoForOnu[Path] = &meterInfo
780 rsrcMgr.meterInfoForOnuLock.Unlock()
781
Girish Gowdraa482f272021-03-24 23:04:19 -0700782 return &meterInfo, err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400783}
784
Girish Gowdraa482f272021-03-24 23:04:19 -0700785// HandleMeterInfoRefCntUpdate increments or decrements the reference counter for a given meter.
786// When reference count becomes 0, it clears the meter information from the kv store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700787func (rsrcMgr *OpenOltResourceMgr) HandleMeterInfoRefCntUpdate(ctx context.Context, Direction string,
788 intfID uint32, onuID uint32, uniID uint32, tpID uint32, increment bool) error {
789 meterInfo, err := rsrcMgr.GetMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID)
Girish Gowdra82c80982021-03-26 16:22:02 -0700790 if err != nil {
791 return err
792 } else if meterInfo == nil {
793 // If we are increasing the reference count, we expect the meter information to be present on KV store.
794 // But if decrementing the reference count, the meter is possibly already cleared from KV store. Just log warn but do not return error.
795 if increment {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700796 logger.Errorf(ctx, "error-fetching-meter-info-for-intf-%d-onu-%d-uni-%d-tp-id-%d-direction-%s", intfID, onuID, uniID, tpID, Direction)
797 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 -0700798 }
799 logger.Warnw(ctx, "meter is already cleared",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700800 log.Fields{"intfID": intfID, "onuID": onuID, "uniID": uniID, "direction": Direction, "increment": increment})
Girish Gowdra82c80982021-03-26 16:22:02 -0700801 return nil
Girish Gowdraa482f272021-03-24 23:04:19 -0700802 }
Girish Gowdra82c80982021-03-26 16:22:02 -0700803
Girish Gowdraa482f272021-03-24 23:04:19 -0700804 if increment {
805 meterInfo.RefCnt++
806 } else {
807 meterInfo.RefCnt--
Girish Gowdra82c80982021-03-26 16:22:02 -0700808 // If RefCnt become 0 clear the meter information from the DB.
Girish Gowdraa482f272021-03-24 23:04:19 -0700809 if meterInfo.RefCnt == 0 {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700810 if err := rsrcMgr.RemoveMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700811 return err
812 }
813 return nil
814 }
815 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700816 if err := rsrcMgr.StoreMeterInfoForOnu(ctx, Direction, intfID, onuID, uniID, tpID, meterInfo); err != nil {
Girish Gowdraa482f272021-03-24 23:04:19 -0700817 return err
818 }
819 return nil
820}
821
822// RemoveMeterInfoForOnu deletes the meter id from the kV-Store for the given onu based on the path
Gamze Abakafee36392019-10-03 11:17:24 +0000823// 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 -0700824func (rsrcMgr *OpenOltResourceMgr) RemoveMeterInfoForOnu(ctx context.Context, Direction string, intfID uint32, onuID uint32,
825 uniID uint32, tpID uint32) error {
826 Path := fmt.Sprintf(MeterIDPathSuffix, intfID, onuID, uniID, tpID, Direction)
827
828 // update cache
829 rsrcMgr.meterInfoForOnuLock.Lock()
830 delete(rsrcMgr.meterInfoForOnu, Path)
831 rsrcMgr.meterInfoForOnuLock.Unlock()
832
833 if err := rsrcMgr.KVStore.Delete(ctx, Path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834 logger.Errorf(ctx, "Failed to delete meter id %s from kvstore ", Path)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400835 return err
836 }
837 return nil
838}
salmansiddiqui7ac62132019-08-22 03:58:50 +0000839
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700840//AddGemToOnuGemInfo adds gemport to onugem info kvstore and also local cache
841func (rsrcMgr *OpenOltResourceMgr) AddGemToOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
842 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
843 if err != nil || onugem == nil || onugem.SerialNumber == "" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000844 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530845 return err
846 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700847 if onugem.OnuID == onuID {
848 for _, gem := range onugem.GemPorts {
849 if gem == gemPort {
850 logger.Debugw(ctx, "Gem already present in onugem info, skpping addition", log.Fields{"gem": gem})
851 return nil
852 }
853 }
854 logger.Debugw(ctx, "Added gem to onugem info", log.Fields{"gem": gemPort})
855 onugem.GemPorts = append(onugem.GemPorts, gemPort)
856 } else {
857 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
858 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530859 }
860
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700861 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530862 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000863 logger.Error(ctx, "Failed to add onugem to kv store")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530864 return err
865 }
866 return err
867}
868
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700869//RemoveGemFromOnuGemInfo removes gemport from onugem info on kvstore and also local cache
870func (rsrcMgr *OpenOltResourceMgr) RemoveGemFromOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, gemPort uint32) error {
871 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
872 if err != nil || onugem == nil || onugem.SerialNumber == "" {
873 logger.Errorf(ctx, "failed to get onuifo for intfid %d", intfID)
874 return err
875 }
876 updated := false
877 if onugem.OnuID == onuID {
878 for i, gem := range onugem.GemPorts {
879 if gem == gemPort {
880 logger.Debugw(ctx, "Gem found, removing from onu gem info", log.Fields{"gem": gem})
881 onugem.GemPorts = append(onugem.GemPorts[:i], onugem.GemPorts[i+1:]...)
882 updated = true
883 break
884 }
885 }
886 } else {
887 logger.Errorw(ctx, "onu id in OnuGemInfo does not match", log.Fields{"onuID": onuID, "ponIf": intfID, "onuGemInfoOnuID": onugem.OnuID})
888 return fmt.Errorf("onu-id-in-OnuGemInfo-does-not-match-%v", onuID)
889 }
890 if updated {
891 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
892 if err != nil {
893 logger.Error(ctx, "Failed to add onugem to kv store")
894 return err
895 }
896 } else {
897 logger.Debugw(ctx, "Gem port not found in onu gem info", log.Fields{"gem": gemPort})
898 }
899 return nil
900}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530901
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700902//GetOnuGemInfo gets onu gem info from the kvstore per interface
903func (rsrcMgr *OpenOltResourceMgr) GetOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) (*OnuGemInfo, error) {
904 var err error
905 var Val []byte
906 var onugem OnuGemInfo
907
908 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
909
910 rsrcMgr.onuGemInfoLock.RLock()
911 val, ok := rsrcMgr.onuGemInfo[path]
912 rsrcMgr.onuGemInfoLock.RUnlock()
913 if ok {
914 return val, nil
915 }
916 value, err := rsrcMgr.KVStore.Get(ctx, path)
917 if err != nil {
918 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
919 return nil, err
920 } else if value == nil {
921 logger.Debug(ctx, "No onuinfo for path", log.Fields{"path": path})
922 return nil, nil // returning nil as this could happen if there are no onus for the interface yet
923 }
924 if Val, err = kvstore.ToByte(value.Value); err != nil {
925 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530926 return nil, err
927 }
928
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700929 if err = json.Unmarshal(Val, &onugem); err != nil {
930 logger.Error(ctx, "Failed to unmarshall")
931 return nil, err
932 }
933 logger.Debugw(ctx, "found onugem info from path", log.Fields{"path": path, "onuGemInfo": onugem})
934 rsrcMgr.onuGemInfoLock.Lock()
935 rsrcMgr.onuGemInfo[path] = &onugem
936 rsrcMgr.onuGemInfoLock.Unlock()
937
938 return &onugem, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530939}
940
Chaitrashree G S1a55b882020-02-04 17:35:35 -0500941// AddOnuGemInfo adds onu info on to the kvstore per interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700942func (rsrcMgr *OpenOltResourceMgr) AddOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32, onuGem OnuGemInfo) error {
943
944 var Value []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530945 var err error
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700946 Path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530947
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700948 rsrcMgr.onuGemInfoLock.Lock()
949 rsrcMgr.onuGemInfo[Path] = &onuGem
950 rsrcMgr.onuGemInfoLock.Unlock()
951
952 Value, err = json.Marshal(onuGem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530953 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700954 logger.Error(ctx, "failed to Marshal")
955 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530956 }
957
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700958 if err = rsrcMgr.KVStore.Put(ctx, Path, Value); err != nil {
959 logger.Errorf(ctx, "Failed to update resource %s", Path)
960 return err
961 }
Girish Gowdrabcf98af2021-07-01 08:24:42 -0700962 logger.Debugw(ctx, "added onu gem info to store", log.Fields{"onuGemInfo": onuGem})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700963 return err
964}
965
966// DelOnuGemInfo deletes the onugem info from kvstore per ONU
967func (rsrcMgr *OpenOltResourceMgr) DelOnuGemInfo(ctx context.Context, intfID uint32, onuID uint32) error {
968 path := fmt.Sprintf(OnuGemInfoPath, intfID, onuID)
969 rsrcMgr.onuGemInfoLock.Lock()
970 logger.Debugw(ctx, "removing onu gem info", log.Fields{"onuGemInfo": rsrcMgr.onuGemInfo[path]})
971 delete(rsrcMgr.onuGemInfo, path)
972 rsrcMgr.onuGemInfoLock.Unlock()
973
974 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
975 logger.Errorf(ctx, "failed to remove resource %s", path)
976 return err
977 }
Andrea Campanellab83b39d2020-03-30 11:41:16 +0200978 return nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530979}
980
Girish Gowdra1cd96d82021-11-05 09:56:26 -0700981//DeleteAllOnuGemInfoForIntf deletes all the all onu gem info on the given pon interface
982func (rsrcMgr *OpenOltResourceMgr) DeleteAllOnuGemInfoForIntf(ctx context.Context, intfID uint32) error {
983
984 path := fmt.Sprintf(OnuGemInfoPathPathPrefix, intfID)
985
986 logger.Debugw(ctx, "delete-all-onu-gem-info-for-pon-intf", log.Fields{"intfID": intfID})
987 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
988 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
989 return err
990 }
991
992 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
993 rsrcMgr.onuGemInfoLock.Lock()
994 rsrcMgr.onuGemInfo = make(map[string]*OnuGemInfo)
995 rsrcMgr.onuGemInfoLock.Unlock()
996 return nil
997}
998
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530999// 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 -07001000func (rsrcMgr *OpenOltResourceMgr) AddUniPortToOnuInfo(ctx context.Context, intfID uint32, onuID uint32, portNo uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301001
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001002 onugem, err := rsrcMgr.GetOnuGemInfo(ctx, intfID, onuID)
1003 if err != nil || onugem == nil || onugem.SerialNumber == "" {
1004 logger.Warnf(ctx, "failed to get onuifo for intfid %d", intfID)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301005 return
1006 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001007
1008 if onugem.OnuID == onuID {
1009 for _, uni := range onugem.UniPorts {
1010 if uni == portNo {
1011 logger.Debugw(ctx, "uni already present in onugem info", log.Fields{"uni": portNo})
1012 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301013 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301014 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001015 onugem.UniPorts = append(onugem.UniPorts, portNo)
1016 } else {
1017 logger.Warnw(ctx, "onu id mismatch in onu gem info", log.Fields{"intfID": intfID, "onuID": onuID})
1018 return
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301019 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001020 err = rsrcMgr.AddOnuGemInfo(ctx, intfID, onuID, *onugem)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301021 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001022 logger.Errorw(ctx, "Failed to add uni port in onugem to kv store", log.Fields{"uni": portNo})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301023 return
1024 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301025}
1026
Esin Karaman7fb80c22020-07-16 14:23:33 +00001027//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 -07001028func (rsrcMgr *OpenOltResourceMgr) UpdateGemPortForPktIn(ctx context.Context, pktIn PacketInInfoKey, gemPort uint32) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301029
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001030 path := fmt.Sprintf(OnuPacketInPath, pktIn.IntfID, pktIn.OnuID, pktIn.LogicalPort, pktIn.VlanID, pktIn.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001031 // update cache
1032 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1033 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1034 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
1035
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301036 Value, err := json.Marshal(gemPort)
1037 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001038 logger.Error(ctx, "Failed to marshal data")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301039 return
1040 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001041 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"path": path, "value": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301043 return
1044 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001045 logger.Debugw(ctx, "added gem packet in successfully", log.Fields{"path": path, "gem": gemPort})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301046}
1047
Esin Karaman7fb80c22020-07-16 14:23:33 +00001048// 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 -07001049func (rsrcMgr *OpenOltResourceMgr) GetGemPortFromOnuPktIn(ctx context.Context, packetInInfoKey PacketInInfoKey) (uint32, error) {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301050
1051 var Val []byte
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301052
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001053 path := fmt.Sprintf(OnuPacketInPath, packetInInfoKey.IntfID, packetInInfoKey.OnuID, packetInInfoKey.LogicalPort,
Esin Karaman7fb80c22020-07-16 14:23:33 +00001054 packetInInfoKey.VlanID, packetInInfoKey.Priority)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001055 // get from cache
1056 rsrcMgr.gemPortForPacketInInfoLock.RLock()
1057 gemPort, ok := rsrcMgr.gemPortForPacketInInfo[path]
1058 rsrcMgr.gemPortForPacketInInfoLock.RUnlock()
1059 if ok {
1060 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
1061 return gemPort, nil
1062 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301063
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001064 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301065 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001066 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301067 return uint32(0), err
1068 } else if value == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001069 logger.Debugw(ctx, "No pkt in gem found", log.Fields{"path": path})
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301070 return uint32(0), nil
1071 }
1072
1073 if Val, err = kvstore.ToByte(value.Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301075 return uint32(0), err
1076 }
1077 if err = json.Unmarshal(Val, &gemPort); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001078 logger.Error(ctx, "Failed to unmarshall")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301079 return uint32(0), err
1080 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Debugw(ctx, "found packein gemport from path", log.Fields{"path": path, "gem": gemPort})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001082 // update cache
1083 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1084 rsrcMgr.gemPortForPacketInInfo[path] = gemPort
1085 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301086
1087 return gemPort, nil
1088}
1089
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001090//DeletePacketInGemPortForOnu deletes the packet-in gemport for ONU
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001091func (rsrcMgr *OpenOltResourceMgr) DeletePacketInGemPortForOnu(ctx context.Context, intfID uint32, onuID uint32, logicalPort uint32) error {
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001092 path := fmt.Sprintf(OnuPacketInPathPrefix, intfID, onuID, logicalPort)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001093 value, err := rsrcMgr.KVStore.List(ctx, path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001094 if err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001095 logger.Errorf(ctx, "failed-to-read-value-from-path-%s", path)
1096 return errors.New("failed-to-read-value-from-path-" + path)
Esin Karaman7fb80c22020-07-16 14:23:33 +00001097 }
Esin Karaman7fb80c22020-07-16 14:23:33 +00001098
1099 //remove them one by one
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001100 for key := range value {
serkant.uluderyab428a6c2020-12-17 20:57:59 +03001101 // Remove the PathPrefix from the path on KV key.
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001102 // gemPortForPacketInInfo cache uses OnuPacketInPath as the key
serkant.uluderyab428a6c2020-12-17 20:57:59 +03001103 stringToBeReplaced := rsrcMgr.KVStore.PathPrefix + "/"
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001104 replacedWith := ""
1105 key = strings.Replace(key, stringToBeReplaced, replacedWith, 1)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001106 // update cache
1107 rsrcMgr.gemPortForPacketInInfoLock.Lock()
1108 delete(rsrcMgr.gemPortForPacketInInfo, key)
1109 rsrcMgr.gemPortForPacketInInfoLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001110
serkant.uluderyab428a6c2020-12-17 20:57:59 +03001111 logger.Debugw(ctx, "removed-key-from-packetin-gem-port-cache", log.Fields{"key": key, "cache-len": len(rsrcMgr.gemPortForPacketInInfo)})
1112 }
1113
1114 logger.Debugw(ctx, "delete-packetin-gem-port", log.Fields{"realPath": path})
1115 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1116 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1117 return err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301118 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001119
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301120 return nil
1121}
1122
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001123//GetFlowIDsForGem gets the list of FlowIDs for the given gemport
1124func (rsrcMgr *OpenOltResourceMgr) GetFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) ([]uint64, error) {
1125 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
1126
1127 // get from cache
1128 rsrcMgr.flowIDsForGemLock.RLock()
1129 flowIDs, ok := rsrcMgr.flowIDsForGem[gem]
1130 rsrcMgr.flowIDsForGemLock.RUnlock()
1131 if ok {
1132 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301133 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301134
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001135 value, err := rsrcMgr.KVStore.Get(ctx, path)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301136 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001137 logger.Errorw(ctx, "Failed to get from kv store", log.Fields{"path": path})
1138 return nil, err
1139 } else if value == nil {
1140 logger.Debug(ctx, "no flow-ids found", log.Fields{"path": path})
1141 return nil, nil
1142 }
1143 Val, err := kvstore.ToByte(value.Value)
1144 if err != nil {
1145 logger.Error(ctx, "Failed to convert to byte array")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301146 return nil, err
1147 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301148
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001149 if err = json.Unmarshal(Val, &flowIDs); err != nil {
1150 logger.Error(ctx, "Failed to unmarshall")
1151 return nil, err
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301152 }
1153
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001154 // update cache
1155 rsrcMgr.flowIDsForGemLock.Lock()
1156 rsrcMgr.flowIDsForGem[gem] = flowIDs
1157 rsrcMgr.flowIDsForGemLock.Unlock()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301158
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001159 return flowIDs, nil
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301160}
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301161
1162//UpdateFlowIDsForGem updates flow id per gemport
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001163func (rsrcMgr *OpenOltResourceMgr) UpdateFlowIDsForGem(ctx context.Context, intf uint32, gem uint32, flowIDs []uint64) error {
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301164 var val []byte
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001165 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301166
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001167 // update cache
1168 rsrcMgr.flowIDsForGemLock.Lock()
1169 rsrcMgr.flowIDsForGem[gem] = flowIDs
1170 rsrcMgr.flowIDsForGemLock.Unlock()
1171
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001172 // If the flowIDs slice is empty delete the key entry from the DB.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001173 if flowIDs == nil {
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001174 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1175 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
1176 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001177 return nil
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301178 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001179 val, err := json.Marshal(flowIDs)
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301180 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001181 logger.Error(ctx, "Failed to marshal data", log.Fields{"err": err})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301182 return err
1183 }
Girish Gowdrab77ded92020-04-08 11:45:05 -07001184
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001185 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1186 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301187 return err
1188 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001189 logger.Debugw(ctx, "added flowid list for gem to kv successfully", log.Fields{"path": path, "flowidlist": flowIDs})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301190 return nil
1191}
1192
1193//DeleteFlowIDsForGem deletes the flowID list entry per gem from kvstore.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001194func (rsrcMgr *OpenOltResourceMgr) DeleteFlowIDsForGem(ctx context.Context, intf uint32, gem uint32) {
1195 path := fmt.Sprintf(FlowIDsForGem, intf, gem)
1196 // update cache
1197 rsrcMgr.flowIDsForGemLock.Lock()
1198 delete(rsrcMgr.flowIDsForGem, gem)
1199 rsrcMgr.flowIDsForGemLock.Unlock()
1200 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
1201 logger.Errorw(ctx, "Failed to delete from kvstore", log.Fields{"err": err, "path": path})
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +05301202 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301203}
Esin Karamanccb714b2019-11-29 15:02:06 +00001204
Girish Gowdra1cd96d82021-11-05 09:56:26 -07001205//DeleteAllFlowIDsForGemForIntf deletes all the flow ids associated for all the gems on the given pon interface
1206func (rsrcMgr *OpenOltResourceMgr) DeleteAllFlowIDsForGemForIntf(ctx context.Context, intfID uint32) error {
1207
1208 path := fmt.Sprintf(FlowIDsForGemPathPrefix, intfID)
1209
1210 logger.Debugw(ctx, "delete-flow-ids-for-gem-for-pon-intf", log.Fields{"intfID": intfID})
1211 if err := rsrcMgr.KVStore.DeleteWithPrefix(ctx, path); err != nil {
1212 logger.Errorf(ctx, "failed-to-remove-resource-%s", path)
1213 return err
1214 }
1215
1216 // Reset cache. Normally not necessary as the entire device is getting deleted when this API is invoked.
1217 rsrcMgr.flowIDsForGemLock.Lock()
1218 rsrcMgr.flowIDsForGem = make(map[uint32][]uint64)
1219 rsrcMgr.flowIDsForGemLock.Unlock()
1220 return nil
1221}
1222
Esin Karamanccb714b2019-11-29 15:02:06 +00001223//GetMcastQueuePerInterfaceMap gets multicast queue info per pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001224func (rsrcMgr *OpenOltResourceMgr) GetMcastQueuePerInterfaceMap(ctx context.Context) (map[uint32][]uint32, error) {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001225 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001226 var val []byte
1227
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001228 rsrcMgr.mcastQueueForIntfLock.RLock()
1229 if rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1230 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1231 return rsrcMgr.mcastQueueForIntf, nil
1232 }
1233 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1234
1235 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001236 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237 logger.Error(ctx, "failed to get data from kv store")
Esin Karamanccb714b2019-11-29 15:02:06 +00001238 return nil, err
1239 }
1240 if kvPair != nil && kvPair.Value != nil {
1241 if val, err = kvstore.ToByte(kvPair.Value); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001242 logger.Error(ctx, "Failed to convert to byte array ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001243 return nil, err
1244 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001245 rsrcMgr.mcastQueueForIntfLock.Lock()
1246 defer rsrcMgr.mcastQueueForIntfLock.Unlock()
1247 if err = json.Unmarshal(val, &rsrcMgr.mcastQueueForIntf); err != nil {
1248 logger.Error(ctx, "Failed to unmarshall ", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001249 return nil, err
1250 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001251 rsrcMgr.mcastQueueForIntfLoadedFromKvStore = true
Esin Karamanccb714b2019-11-29 15:02:06 +00001252 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001253 return rsrcMgr.mcastQueueForIntf, nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001254}
1255
1256//AddMcastQueueForIntf adds multicast queue for pon interface
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001257func (rsrcMgr *OpenOltResourceMgr) AddMcastQueueForIntf(ctx context.Context, intf uint32, gem uint32, servicePriority uint32) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001258 var val []byte
Kent Hagermane6ff1012020-07-14 15:07:53 -04001259 path := McastQueuesForIntf
Esin Karamanccb714b2019-11-29 15:02:06 +00001260
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001261 // Load local cache from kv store the first time
1262 rsrcMgr.mcastQueueForIntfLock.RLock()
1263 if !rsrcMgr.mcastQueueForIntfLoadedFromKvStore {
1264 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1265 _, err := rsrcMgr.GetMcastQueuePerInterfaceMap(ctx)
1266 if err != nil {
1267 logger.Errorw(ctx, "Failed to get multicast queue info for interface", log.Fields{"err": err, "intf": intf})
1268 return err
1269 }
1270 } else {
1271 rsrcMgr.mcastQueueForIntfLock.RUnlock()
1272 }
1273
1274 // Update KV store
1275 rsrcMgr.mcastQueueForIntfLock.Lock()
1276 rsrcMgr.mcastQueueForIntf[intf] = []uint32{gem, servicePriority}
1277 val, err := json.Marshal(rsrcMgr.mcastQueueForIntf)
Esin Karamanccb714b2019-11-29 15:02:06 +00001278 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001279 rsrcMgr.mcastQueueForIntfLock.Unlock()
1280 logger.Errorw(ctx, "Failed to marshal data", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001281 return err
1282 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001283 rsrcMgr.mcastQueueForIntfLock.Unlock()
1284
1285 if err = rsrcMgr.KVStore.Put(ctx, path, val); err != nil {
1286 logger.Errorw(ctx, "Failed to put to kvstore", log.Fields{"err": err, "path": path, "value": val})
Esin Karamanccb714b2019-11-29 15:02:06 +00001287 return err
1288 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001289 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 +00001290 return nil
1291}
1292
1293//AddFlowGroupToKVStore adds flow group into KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001294func (rsrcMgr *OpenOltResourceMgr) AddFlowGroupToKVStore(ctx context.Context, groupEntry *ofp.OfpGroupEntry, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001295 var Value []byte
1296 var err error
1297 var path string
1298 if cached {
1299 path = fmt.Sprintf(FlowGroupCached, groupEntry.Desc.GroupId)
1300 } else {
1301 path = fmt.Sprintf(FlowGroup, groupEntry.Desc.GroupId)
1302 }
1303 //build group info object
1304 var outPorts []uint32
1305 for _, ofBucket := range groupEntry.Desc.Buckets {
1306 for _, ofAction := range ofBucket.Actions {
1307 if ofAction.Type == ofp.OfpActionType_OFPAT_OUTPUT {
1308 outPorts = append(outPorts, ofAction.GetOutput().Port)
1309 }
1310 }
1311 }
1312 groupInfo := GroupInfo{
1313 GroupID: groupEntry.Desc.GroupId,
1314 OutPorts: outPorts,
1315 }
1316
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001317 rsrcMgr.groupInfoLock.Lock()
1318 rsrcMgr.groupInfo[path] = &groupInfo
1319 rsrcMgr.groupInfoLock.Unlock()
1320
Esin Karamanccb714b2019-11-29 15:02:06 +00001321 Value, err = json.Marshal(groupInfo)
1322
1323 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001324 logger.Error(ctx, "failed to Marshal flow group object")
Esin Karamanccb714b2019-11-29 15:02:06 +00001325 return err
1326 }
1327
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001328 if err = rsrcMgr.KVStore.Put(ctx, path, Value); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001329 logger.Errorf(ctx, "Failed to update resource %s", path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001330 return err
1331 }
1332 return nil
1333}
1334
1335//RemoveFlowGroupFromKVStore removes flow group from KV store
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001336func (rsrcMgr *OpenOltResourceMgr) RemoveFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) error {
Esin Karamanccb714b2019-11-29 15:02:06 +00001337 var path string
1338 if cached {
1339 path = fmt.Sprintf(FlowGroupCached, groupID)
1340 } else {
1341 path = fmt.Sprintf(FlowGroup, groupID)
1342 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001343 rsrcMgr.groupInfoLock.Lock()
1344 delete(rsrcMgr.groupInfo, path)
1345 rsrcMgr.groupInfoLock.Unlock()
1346
1347 if err := rsrcMgr.KVStore.Delete(ctx, path); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001348 logger.Errorf(ctx, "Failed to remove resource %s due to %s", path, err)
Esin Karamand519bbf2020-07-01 11:16:03 +00001349 return err
Esin Karamanccb714b2019-11-29 15:02:06 +00001350 }
Esin Karamand519bbf2020-07-01 11:16:03 +00001351 return nil
Esin Karamanccb714b2019-11-29 15:02:06 +00001352}
1353
1354//GetFlowGroupFromKVStore fetches flow group from the KV store. Returns (false, {} error) if any problem occurs during
1355//fetching the data. Returns (true, groupInfo, nil) if the group is fetched successfully.
1356// Returns (false, {}, nil) if the group does not exists in the KV store.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001357func (rsrcMgr *OpenOltResourceMgr) GetFlowGroupFromKVStore(ctx context.Context, groupID uint32, cached bool) (bool, GroupInfo, error) {
Esin Karamanccb714b2019-11-29 15:02:06 +00001358 var groupInfo GroupInfo
1359 var path string
1360 if cached {
1361 path = fmt.Sprintf(FlowGroupCached, groupID)
1362 } else {
1363 path = fmt.Sprintf(FlowGroup, groupID)
1364 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001365
1366 // read from cache
1367 rsrcMgr.groupInfoLock.RLock()
1368 gi, ok := rsrcMgr.groupInfo[path]
1369 rsrcMgr.groupInfoLock.RUnlock()
1370 if ok {
1371 return true, *gi, nil
1372 }
1373
1374 kvPair, err := rsrcMgr.KVStore.Get(ctx, path)
Esin Karamanccb714b2019-11-29 15:02:06 +00001375 if err != nil {
1376 return false, groupInfo, err
1377 }
1378 if kvPair != nil && kvPair.Value != nil {
1379 Val, err := kvstore.ToByte(kvPair.Value)
1380 if err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001381 logger.Errorw(ctx, "Failed to convert flow group into byte array", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001382 return false, groupInfo, err
1383 }
1384 if err = json.Unmarshal(Val, &groupInfo); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001385 logger.Errorw(ctx, "Failed to unmarshal", log.Fields{"err": err})
Esin Karamanccb714b2019-11-29 15:02:06 +00001386 return false, groupInfo, err
1387 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001388 // update cache
1389 rsrcMgr.groupInfoLock.Lock()
1390 rsrcMgr.groupInfo[path] = &groupInfo
1391 rsrcMgr.groupInfoLock.Unlock()
1392
Esin Karamanccb714b2019-11-29 15:02:06 +00001393 return true, groupInfo, nil
1394 }
1395 return false, groupInfo, nil
1396}
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001397
1398// toByte converts an interface value to a []byte. The interface should either be of
1399// a string type or []byte. Otherwise, an error is returned.
1400func toByte(value interface{}) ([]byte, error) {
1401 switch t := value.(type) {
1402 case []byte:
1403 return value.([]byte), nil
1404 case string:
1405 return []byte(value.(string)), nil
1406 default:
1407 return nil, fmt.Errorf("unexpected-type-%T", t)
1408 }
1409}