blob: 7ed1d2c439a30bb4bc1e8f2bc3934f114810cc9f [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
manikkaraj kbf256be2019-03-25 00:13:48 +053017package resourcemanager
Abhilash S.L7f17e402019-03-15 17:40:41 +053018
19import (
20 "encoding/json"
21 "errors"
22 "fmt"
23 "strconv"
24 "strings"
25
manikkaraj kbf256be2019-03-25 00:13:48 +053026 ponrmgr "github.com/opencord/voltha-go/common/ponresourcemanager"
Abhilash S.L7f17e402019-03-15 17:40:41 +053027 "github.com/opencord/voltha-go/common/log"
28 "github.com/opencord/voltha-go/db/kvstore"
29 "github.com/opencord/voltha-go/db/model"
manikkaraj kbf256be2019-03-25 00:13:48 +053030 "github.com/opencord/voltha-protos/go/openolt"
Abhilash S.L7f17e402019-03-15 17:40:41 +053031)
32
manikkaraj kbf256be2019-03-25 00:13:48 +053033const KVSTORE_TIMEOUT = 5
Abhilash S.L7f17e402019-03-15 17:40:41 +053034const BASE_PATH_KV_STORE = "service/voltha/openolt/{%s}" // service/voltha/openolt/<device_id>
35
36type OpenOltResourceMgr struct {
37 DeviceID string //OLT device id
38 HostAndPort string // Host and port of the kv store to connect to
39 Args string // args
40 KVStore *model.Backend // backend kv store connection handle
41 DeviceType string
42 Host string // Host ip of the kv store
43 Port int // port of the kv store
44 DevInfo *openolt.DeviceInfo // device information
45 // array of pon resource managers per interface technology
46 ResourceMgrs map[uint32]*ponrmgr.PONResourceManager
47}
48
49func newKVClient(storeType string, address string, timeout uint32) (kvstore.Client, error) {
50 log.Infow("kv-store-type", log.Fields{"store": storeType})
51 switch storeType {
52 case "consul":
53 return kvstore.NewConsulClient(address, int(timeout))
54 case "etcd":
55 return kvstore.NewEtcdClient(address, int(timeout))
56 }
57 return nil, errors.New("unsupported-kv-store")
58}
59
60func SetKVClient(Backend string, Host string, Port int, DeviceID string) *model.Backend {
61 addr := Host + ":" + strconv.Itoa(Port)
62 // TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
63 // issue between kv store and backend , core is not calling NewBackend directly
64 kvClient, err := newKVClient(Backend, addr, KVSTORE_TIMEOUT)
65 if err != nil {
66 log.Fatalw("Failed to init KV client\n", log.Fields{"err": err})
67 return nil
68 }
69 kvbackend := &model.Backend{
70 Client: kvClient,
71 StoreType: Backend,
72 Host: Host,
73 Port: Port,
74 Timeout: KVSTORE_TIMEOUT,
75 PathPrefix: fmt.Sprintf(BASE_PATH_KV_STORE, DeviceID)}
76
77 return kvbackend
78}
79
80func NewResourceMgr(DeviceID string, HostPort string, DeviceType string, DevInfo *openolt.DeviceInfo) *OpenOltResourceMgr {
81
82 /* init a New resource maanger instance which in turn instantiates pon resource manager
83 instances according to technology. Initializes the default resource ranges for all
84 the reources.
85 */
86 var ResourceMgr OpenOltResourceMgr
87 log.Debugf("Init new resource manager , host_port: %s, deviceid: %s", HostPort, DeviceID)
88 ResourceMgr.HostAndPort = HostPort
89 ResourceMgr.DeviceType = DeviceType
90 ResourceMgr.DevInfo = DevInfo
91 IpPort := strings.Split(HostPort, ":")
92 ResourceMgr.Host = IpPort[0]
93 ResourceMgr.Port, _ = strconv.Atoi(IpPort[1])
94
95 Backend := "etcd" /* TODO remove this once we get backend store from registry*/
96 ResourceMgr.KVStore = SetKVClient(Backend, ResourceMgr.Host,
97 ResourceMgr.Port, DeviceID)
98 if ResourceMgr.KVStore == nil {
99 log.Error("Failed to setup KV store")
100 }
101 Ranges := make(map[string]*openolt.DeviceInfo_DeviceResourceRanges)
102 RsrcMgrsByTech := make(map[string]*ponrmgr.PONResourceManager)
103 ResourceMgr.ResourceMgrs = make(map[uint32]*ponrmgr.PONResourceManager)
104
105 // TODO self.args = registry('main').get_args()
106
107 /*
108 If a legacy driver returns protobuf without any ranges,s synthesize one from
109 the legacy global per-device informaiton. This, in theory, is temporary until
110 the legacy drivers are upgrade to support pool ranges.
111 */
112 if DevInfo.Ranges == nil {
113 var ranges openolt.DeviceInfo_DeviceResourceRanges
114 ranges.Technology = DevInfo.GetTechnology()
115
116 NumPONPorts := DevInfo.GetPonPorts()
117 var index uint32
118 for index = 0; index < NumPONPorts; index++ {
119 ranges.IntfIds = append(ranges.IntfIds, index)
120 }
121
122 var Pool *openolt.DeviceInfo_DeviceResourceRanges_Pool
123 Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID
124 Pool.Start = DevInfo.OnuIdStart
125 Pool.End = DevInfo.OnuIdEnd
126 Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
127 ranges.Pools = append(ranges.Pools, Pool)
128
129 Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID
130 Pool.Start = DevInfo.AllocIdStart
131 Pool.End = DevInfo.AllocIdEnd
132 Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
133 ranges.Pools = append(ranges.Pools, Pool)
134
135 Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID
136 Pool.Start = DevInfo.GemportIdStart
137 Pool.End = DevInfo.GemportIdEnd
138 Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
139 ranges.Pools = append(ranges.Pools, Pool)
140
141 Pool.Type = openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID
142 Pool.Start = DevInfo.FlowIdStart
143 Pool.End = DevInfo.FlowIdEnd
144 Pool.Sharing = openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH
145 ranges.Pools = append(ranges.Pools, Pool)
146 }
147
148 //Create a separate Resource Manager instance for each range. This assumes that
149 // each technology is represented by only a single range
150 var GlobalPONRsrcMgr *ponrmgr.PONResourceManager
151 var err error
152 for _, TechRange := range DevInfo.Ranges {
153 technology := TechRange.Technology
154 log.Debugf("Device info technology %s", technology)
155 Ranges[technology] = TechRange
156 RsrcMgrsByTech[technology], err = ponrmgr.NewPONResourceManager(technology, DeviceType, DeviceID,
157 Backend, ResourceMgr.Host, ResourceMgr.Port)
158 if err != nil {
159 log.Errorf("Failed to create pon resource manager instacnce for technology %s", technology)
160 return nil
161 }
162 //resource_mgrs_by_tech[technology] = resource_mgr
163 if GlobalPONRsrcMgr == nil {
164 GlobalPONRsrcMgr = RsrcMgrsByTech[technology]
165 }
166 for IntfId := range TechRange.IntfIds {
167 ResourceMgr.ResourceMgrs[uint32(IntfId)] = RsrcMgrsByTech[technology]
168 }
169 //self.initialize_device_resource_range_and_pool(resource_mgr, global_resource_mgr, arange)
170 InitializeDeviceResourceRangeAndPool(RsrcMgrsByTech[technology], GlobalPONRsrcMgr,
171 TechRange, DevInfo)
172 }
173 // After we have initialized resource ranges, initialize the
174 // resource pools accordingly.
175 for _, PONRMgr := range RsrcMgrsByTech {
176 PONRMgr.InitDeviceResourcePool()
177 }
178 return &ResourceMgr
179}
180
181func InitializeDeviceResourceRangeAndPool(PONRMgr *ponrmgr.PONResourceManager, GlobalPONRMgr *ponrmgr.PONResourceManager,
182 TechRange *openolt.DeviceInfo_DeviceResourceRanges, DevInfo *openolt.DeviceInfo) {
183
184 // init the resource range pool according to the sharing type
185
186 log.Debugf("Resource range pool init for technology %s", PONRMgr.Technology)
187 //first load from KV profiles
188 status := PONRMgr.InitResourceRangesFromKVStore()
189 if status == false {
190 log.Debugf("Failed to load resource ranges from KV store for tech %s", PONRMgr.Technology)
191 }
192
193 /*
194 Then apply device specific information. If KV doesn't exist
195 or is broader than the device, the device's informationw ill
196 dictate the range limits
197 */
198 log.Debugf("Using device info to init pon resource ranges for tech", PONRMgr.Technology)
199
200 ONUIDStart := DevInfo.OnuIdStart
201 ONUIDEnd := DevInfo.OnuIdEnd
202 ONUIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_DEDICATED_PER_INTF
203 ONUIDSharedPoolID := uint32(0)
204 AllocIDStart := DevInfo.AllocIdStart
205 AllocIDEnd := DevInfo.AllocIdEnd
206 AllocIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
207 AllocIDSharedPoolID := uint32(0)
208 GEMPortIDStart := DevInfo.GemportIdStart
209 GEMPortIDEnd := DevInfo.GemportIdEnd
210 GEMPortIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
211 GEMPortIDSharedPoolID := uint32(0)
212 FlowIDStart := DevInfo.FlowIdStart
213 FlowIDEnd := DevInfo.FlowIdEnd
214 FlowIDShared := openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH // TODO EdgeCore/BAL limitation
215 FlowIDSharedPoolID := uint32(0)
216
217 var GlobalPoolID uint32
218 var FirstIntfPoolID uint32
219 var SharedPoolID uint32
220
221 for _, FirstIntfPoolID = range TechRange.IntfIds {
222 break
223 }
224
225 for _, RangePool := range TechRange.Pools {
226 if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
227 SharedPoolID = GlobalPoolID
228 } else if RangePool.Sharing == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_SAME_TECH {
229 SharedPoolID = FirstIntfPoolID
230 } else {
231 SharedPoolID = 0
232 }
233 if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ONU_ID {
234 ONUIDStart = RangePool.Start
235 ONUIDEnd = RangePool.End
236 ONUIDShared = RangePool.Sharing
237 ONUIDSharedPoolID = SharedPoolID
238 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_ALLOC_ID {
239 AllocIDStart = RangePool.Start
240 AllocIDEnd = RangePool.End
241 AllocIDShared = RangePool.Sharing
242 AllocIDSharedPoolID = SharedPoolID
243 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_GEMPORT_ID {
244 GEMPortIDStart = RangePool.Start
245 GEMPortIDEnd = RangePool.End
246 GEMPortIDShared = RangePool.Sharing
247 GEMPortIDSharedPoolID = SharedPoolID
248 } else if RangePool.Type == openolt.DeviceInfo_DeviceResourceRanges_Pool_FLOW_ID {
249 FlowIDStart = RangePool.Start
250 FlowIDEnd = RangePool.End
251 FlowIDShared = RangePool.Sharing
252 FlowIDSharedPoolID = SharedPoolID
253 }
254 }
255
256 log.Debugw("Device info init", log.Fields{"technology": TechRange.Technology,
257 "onu_id_start": ONUIDStart, "onu_id_end": ONUIDEnd, "onu_id_shared_pool_id": ONUIDSharedPoolID,
258 "alloc_id_start": AllocIDStart, "alloc_id_end": AllocIDEnd,
259 "alloc_id_shared_pool_id": AllocIDSharedPoolID,
260 "gemport_id_start": GEMPortIDStart, "gemport_id_end": GEMPortIDEnd,
261 "gemport_id_shared_pool_id": GEMPortIDSharedPoolID,
262 "flow_id_start": FlowIDStart,
263 "flow_id_end_idx": FlowIDEnd,
264 "flow_id_shared_pool_id": FlowIDSharedPoolID,
265 "intf_ids": TechRange.IntfIds,
266 "uni_id_start": 0,
267 "uni_id_end_idx":/*MaxUNIIDperONU()*/ 1})
268
269 PONRMgr.InitDefaultPONResourceRanges(ONUIDStart, ONUIDEnd, ONUIDSharedPoolID,
270 AllocIDStart, AllocIDEnd, AllocIDSharedPoolID,
271 GEMPortIDStart, GEMPortIDEnd, GEMPortIDSharedPoolID,
272 FlowIDStart, FlowIDEnd, FlowIDSharedPoolID, 0, 1,
273 DevInfo.PonPorts, TechRange.IntfIds)
274
275 // For global sharing, make sure to refresh both local and global resource manager instances' range
276
277 if ONUIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
278 GlobalPONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
279 "", 0, nil)
280 PONRMgr.UpdateRanges(ponrmgr.ONU_ID_START_IDX, ONUIDStart, ponrmgr.ONU_ID_END_IDX, ONUIDEnd,
281 "", 0, GlobalPONRMgr)
282 }
283 if AllocIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
284 GlobalPONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
285 "", 0, nil)
286
287 PONRMgr.UpdateRanges(ponrmgr.ALLOC_ID_START_IDX, AllocIDStart, ponrmgr.ALLOC_ID_END_IDX, AllocIDEnd,
288 "", 0, GlobalPONRMgr)
289 }
290 if GEMPortIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
291 GlobalPONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
292 "", 0, nil)
293 PONRMgr.UpdateRanges(ponrmgr.GEMPORT_ID_START_IDX, GEMPortIDStart, ponrmgr.GEMPORT_ID_END_IDX, GEMPortIDEnd,
294 "", 0, GlobalPONRMgr)
295 }
296 if FlowIDShared == openolt.DeviceInfo_DeviceResourceRanges_Pool_SHARED_BY_ALL_INTF_ALL_TECH {
297 GlobalPONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
298 "", 0, nil)
299 PONRMgr.UpdateRanges(ponrmgr.FLOW_ID_START_IDX, FlowIDStart, ponrmgr.FLOW_ID_END_IDX, FlowIDEnd,
300 "", 0, GlobalPONRMgr)
301 }
302
303 // Make sure loaded range fits the platform bit encoding ranges
304 PONRMgr.UpdateRanges(ponrmgr.UNI_ID_START_IDX, 0, ponrmgr.UNI_ID_END_IDX /* TODO =OpenOltPlatform.MAX_UNIS_PER_ONU-1*/, 1, "", 0, nil)
305}
306
307/* TODO
308def __del__(self):
309 self.log.info("clearing-device-resource-pool")
310 for key, resource_mgr in self.resource_mgrs.iteritems():
311 resource_mgr.clear_device_resource_pool()
312
313 def assert_pon_id_limit(self, pon_intf_id):
314 assert pon_intf_id in self.resource_mgrs
315
316 def assert_onu_id_limit(self, pon_intf_id, onu_id):
317 self.assert_pon_id_limit(pon_intf_id)
318 self.resource_mgrs[pon_intf_id].assert_resource_limits(onu_id, PONResourceManager.ONU_ID)
319
320 @property
321 def max_uni_id_per_onu(self):
322 return 0 #OpenOltPlatform.MAX_UNIS_PER_ONU-1, zero-based indexing Uncomment or override to make default multi-uni
323
324 def assert_uni_id_limit(self, pon_intf_id, onu_id, uni_id):
325 self.assert_onu_id_limit(pon_intf_id, onu_id)
326 self.resource_mgrs[pon_intf_id].assert_resource_limits(uni_id, PONResourceManager.UNI_ID)
327*/
328
329func (RsrcMgr *OpenOltResourceMgr) GetONUID(PONIntfID uint32) (uint32, error) {
330
331 // Get ONU id for a provided pon interface ID.
332
333 ONUID, err := RsrcMgr.ResourceMgrs[PONIntfID].GetResourceID(PONIntfID,
334 ponrmgr.ONU_ID, 1)
335 if err != nil {
336 log.Errorf("Failed to get resource for interface %d for type %s",
337 PONIntfID, ponrmgr.ONU_ID)
338 return ONUID[0], err
339 }
340 if ONUID != nil {
341 RsrcMgr.ResourceMgrs[PONIntfID].InitResourceMap(fmt.Sprintf("%d,%d", PONIntfID, ONUID))
342 }
343
344 return ONUID[0], err
345}
346
347func (RsrcMgr *OpenOltResourceMgr) GetFlowID(PONIntfID uint32, ONUID uint32, UNIID uint32,
348 FlowStoreCookie interface{},
349 FlowCategory interface{}) (uint32, error) {
350
351 // Get flow ID for a given pon interface id, onu id and uni id.
352
353 var err error
354 FlowPath := fmt.Sprintf("%d,%d,%d", PONIntfID, ONUID, UNIID)
355 FlowIDs := RsrcMgr.ResourceMgrs[PONIntfID].GetCurrentFlowIDsForOnu(FlowPath)
356 if FlowIDs != nil {
357 /* TODO once the flow id info structure is known
358 for Flow := range FlowIDs {
359 FlowInfo := RsrcMgr.ResourceMgrs[PONIntfID].GetFlowIDInfo(FlowPath, Flow)
360 for Info := range FlowInfo {
361 if FlowCategory != nil &&
362 Info[FlowCategory] == FlowCategory {
363 return 0, Flow
364 }
365 if FlowStoreCookie != nil &&
366 Info[FlowStoreCookie] == FlowStoreCookie {
367 return 0, Flow
368 }
369 }
370 }
371 */
372 }
373 FlowIDs, err = RsrcMgr.ResourceMgrs[PONIntfID].GetResourceID(PONIntfID,
374 ponrmgr.FLOW_ID, 1)
375 if err != nil {
376 log.Errorf("Failed to get resource for interface %d for type %s",
377 PONIntfID, ponrmgr.FLOW_ID)
378 return FlowIDs[0], err
379 }
380 if FlowIDs != nil {
381 RsrcMgr.ResourceMgrs[PONIntfID].UpdateFlowIDForOnu(FlowPath, FlowIDs[0], true)
382 }
383
384 return FlowIDs[0], err
385}
386
387func (RsrcMgr *OpenOltResourceMgr) GetAllocID(IntfID uint32, ONUID uint32) uint32 {
388
389 // Get alloc id for a given pon interface id and onu id.
390 var err error
391 IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)
392 AllocID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)
393 if AllocID != nil {
394 // Since we support only one alloc_id for the ONU at the moment,
395 // return the first alloc_id in the list, if available, for that
396 // ONU.
397 return AllocID[0]
398 }
399 AllocID, err = RsrcMgr.ResourceMgrs[IntfID].GetResourceID(IntfID,
400 ponrmgr.ALLOC_ID, 1)
401
402 if AllocID == nil || err != nil {
403 log.Error("Failed to allocate alloc id")
404 return 0
405 }
406 // update the resource map on KV store with the list of alloc_id
407 // allocated for the pon_intf_onu_id tuple
408 err = RsrcMgr.ResourceMgrs[IntfID].UpdateAllocIdsForOnu(IntfONUID, AllocID)
409 if err != nil {
410 log.Error("Failed to update Alloc ID")
411 return 0
412 }
413 return AllocID[0]
414}
415
416func (RsrcMgr *OpenOltResourceMgr) UpdateAllocIdsForOnu(PONPort uint32, ONUID uint32,
417 UNIID uint32, AllocID []uint32) error {
418
419 /* update alloc ids in kv store for a given pon interface id,
420 onu id and uni id.
421 */
422 IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)
423 return RsrcMgr.ResourceMgrs[PONPort].UpdateAllocIdsForOnu(IntfONUID,
424 AllocID)
425}
426func (RsrcMgr *OpenOltResourceMgr) GetCurrentGEMPortIDsForOnu(IntfID uint32, ONUID uint32,
427 UNIID uint32) []uint32 {
428
429 /* Get gem ports for given pon interface , onu id and uni id. */
430
431 IntfONUID := fmt.Sprintf("%d,%d,%d", IntfID, ONUID, UNIID)
432 GEMPortID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentGEMPortIDsForOnu(IntfONUID)
433 if GEMPortID != nil {
434 // Since we support only one alloc_id for the ONU at the moment,
435 // return the first alloc_id in the list, if available, for that
436 // ONU.
437 return GEMPortID
438 }
439 return nil
440}
441
442func (RsrcMgr *OpenOltResourceMgr) GetCurrentAllocIDForOnu(IntfID uint32, ONUID uint32) uint32 {
443
444 /* Get alloc ids for given pon interface and onu id. */
445
446 IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)
447 AllocID := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)
448 if AllocID != nil {
449 // Since we support only one alloc_id for the ONU at the moment,
450 // return the first alloc_id in the list, if available, for that
451 // ONU.
452 return AllocID[0]
453 }
454 return 0
455}
456
457func (RsrcMgr *OpenOltResourceMgr) UpdateGEMportsPonportToOnuMapOnKVStore(GEMPorts []uint32, PonPort uint32,
458 ONUID uint32, UNIID uint32) error {
459
460 /* Update onu and uni id associated with the gem port to the kv store. */
461 var IntfGEMPortPath string
462 Data := fmt.Sprintf("%d %d", ONUID, UNIID)
463 for _, GEM := range GEMPorts {
464 IntfGEMPortPath = fmt.Sprintf("%d,%d", PonPort, GEM)
465 Val, err := json.Marshal(Data)
466 if err != nil {
467 log.Error("failed to Marshal")
468 return err
469 }
470 // This information is used when packet_indication is received and
471 // we need to derive the ONU Id for which the packet arrived based
472 // on the pon_intf and gemport available in the packet_indication
473 if err = RsrcMgr.KVStore.Put(IntfGEMPortPath, Val); err != nil {
474 log.Errorf("Failed to update resource %s", IntfGEMPortPath)
475 return err
476 }
477 }
478 return nil
479}
480
481func (RsrcMgr *OpenOltResourceMgr) GetONUUNIfromPONPortGEMPort(PONPort uint32, GEMPort uint32) []uint32 {
482
483 /* get the onu and uni id for a given gem port. */
484 IntfGEMPortPath := fmt.Sprintf("%d,%d", PONPort, GEMPort)
485 var GEMPortIDs []uint32
486 var Data string
487 Value, err := RsrcMgr.KVStore.Get(IntfGEMPortPath)
488 if err == nil {
489 if Value != nil {
490 Val, _ := kvstore.ToByte(Value.Value)
491 if err = json.Unmarshal(Val, &Data); err != nil {
492 log.Error("Failed to unmarshal")
493 return nil
494 }
495 IDs := strings.Split(Data, " ")
496 for _, port := range IDs {
497 Intport, _ := strconv.Atoi(port)
498 GEMPortIDs = append(GEMPortIDs, uint32(Intport))
499 }
500 }
501 }
502 return GEMPortIDs
503}
504
505func (RsrcMgr *OpenOltResourceMgr) GetGEMPortID(PONPort uint32, ONUID uint32,
506 UNIID uint32, NumOfPorts uint32) ([]uint32, error) {
507
508 /* Get gem port id for a particular pon port, onu id
509 and uni id.
510 */
511
512 var err error
513 IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)
514
515 GEMPortList := RsrcMgr.ResourceMgrs[PONPort].GetCurrentGEMPortIDsForOnu(IntfONUID)
516 if GEMPortList != nil {
517 return GEMPortList, nil
518 }
519
520 GEMPortList, err = RsrcMgr.ResourceMgrs[PONPort].GetResourceID(PONPort,
521 ponrmgr.GEMPORT_ID, NumOfPorts)
522 if err != nil && GEMPortList == nil {
523 log.Errorf("Failed to get gem port id for %s", IntfONUID)
524 return nil, err
525 }
526
527 // update the resource map on KV store with the list of gemport_id
528 // allocated for the pon_intf_onu_id tuple
529 err = RsrcMgr.ResourceMgrs[PONPort].UpdateGEMPortIDsForOnu(IntfONUID,
530 GEMPortList)
531 if err != nil {
532 log.Errorf("Failed to update GEM ports to kv store for %s", IntfONUID)
533 return nil, err
534 }
535 RsrcMgr.UpdateGEMportsPonportToOnuMapOnKVStore(GEMPortList, PONPort,
536 ONUID, UNIID)
537 return GEMPortList, err
538}
539
540func (RsrcMgr *OpenOltResourceMgr) UpdateGEMPortIDsForOnu(PONPort uint32, ONUID uint32,
541 UNIID uint32, GEMPortList []uint32) error {
542
543 /* Update gemport ids on to kv store for a given pon port,
544 onu id and uni id.
545 */
546 IntfONUID := fmt.Sprintf("%d,%d,%d", PONPort, ONUID, UNIID)
547 return RsrcMgr.ResourceMgrs[PONPort].UpdateGEMPortIDsForOnu(IntfONUID,
548 GEMPortList)
549
550}
551func (RsrcMgr *OpenOltResourceMgr) FreeONUID(IntfID uint32, ONUID []uint32) {
552
553 /* Free onu id for a particular interface.*/
554 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.ONU_ID, ONUID)
555
556 var IntfONUID string
557 for _, onu := range ONUID {
558 IntfONUID = fmt.Sprintf("%d,%d", IntfID, onu)
559 RsrcMgr.ResourceMgrs[IntfID].RemoveResourceMap(IntfONUID)
560 }
561 return
562}
563
564func (RsrcMgr *OpenOltResourceMgr) FreeFlowID(IntfID uint32, ONUID uint32,
565 UNIID uint32, FlowID []uint32) {
566
567 /* Free flow id for a given interface, onu id and uni id.*/
568
569 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID, ponrmgr.FLOW_ID, FlowID)
570
571 var IntfONUID string
572 var err error
573 for _, flow := range FlowID {
574 IntfONUID = fmt.Sprintf("%d,%d,%d", IntfID, ONUID, UNIID)
575 err = RsrcMgr.ResourceMgrs[IntfID].UpdateFlowIDForOnu(IntfONUID, flow, false)
576 if err != nil {
577 log.Error("Failed to Update flow id infor for %s", IntfONUID)
578 }
579 RsrcMgr.ResourceMgrs[IntfID].RemoveFlowIDInfo(IntfONUID, flow)
580 }
581 return
582}
583
584func (RsrcMgr *OpenOltResourceMgr) FreePONResourcesForONU(IntfID uint32, ONUID uint32) {
585
586 /* Free pon resources for a given pon interface and onu id. */
587
588 var ONUIDs []uint32
589 ONUIDs = append(ONUIDs, ONUID)
590 IntfONUID := fmt.Sprintf("%d,%d", IntfID, ONUID)
591
592 AllocIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentAllocIDForOnu(IntfONUID)
593
594 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
595 ponrmgr.ALLOC_ID,
596 AllocIDs)
597
598 GEMPortIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentGEMPortIDsForOnu(IntfONUID)
599 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
600 ponrmgr.GEMPORT_ID,
601 GEMPortIDs)
602
603 FlowIDs := RsrcMgr.ResourceMgrs[IntfID].GetCurrentFlowIDsForOnu(IntfONUID)
604 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
605 ponrmgr.FLOW_ID,
606 FlowIDs)
607 RsrcMgr.ResourceMgrs[IntfID].FreeResourceID(IntfID,
608 ponrmgr.ONU_ID,
609 ONUIDs)
610
611 // Clear resource map associated with (pon_intf_id, gemport_id) tuple.
612 RsrcMgr.ResourceMgrs[IntfID].RemoveResourceMap(IntfONUID)
613
614 // Clear the ONU Id associated with the (pon_intf_id, gemport_id) tuple.
615 for _, GEM := range GEMPortIDs {
616 RsrcMgr.KVStore.Delete(fmt.Sprintf("%d,%d", IntfID, GEM))
617 }
618}
619
620/* TODO once the flow id info structure is known
621def is_flow_cookie_on_kv_store(self, intf_id, onu_id, uni_id, flow_store_cookie):
622 '''
623 Note: For flows which trap from the NNI and not really associated with any particular
624 ONU (like LLDP), the onu_id and uni_id is set as -1. The intf_id is the NNI intf_id.
625 '''
626 intf_onu_id = (intf_id, onu_id, uni_id)
627 try:
628 flow_ids = self.resource_mgrs[intf_id]. \
629 get_current_flow_ids_for_onu(intf_onu_id)
630 if flow_ids is not None:
631 for flow_id in flow_ids:
632 flows = self.get_flow_id_info(intf_id, onu_id, uni_id, flow_id)
633 assert (isinstance(flows, list))
634 for flow in flows:
635 if flow['flow_store_cookie'] == flow_store_cookie:
636 return True
637 except Exception as e:
638 self.log.error("error-retrieving-flow-info", e=e)
639
640 return False
641*/
642