blob: 2d2332de0ad5225838a090f76568e7211a1412e7 [file] [log] [blame]
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001/*
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
17package techprofile
18
19import (
npujarec5762e2020-01-01 14:08:48 +053020 "context"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040021 "encoding/json"
22 "errors"
23 "fmt"
Girish Gowdra54934262019-11-13 14:19:55 +053024 "regexp"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040025 "strconv"
Girish Gowdra631ef3d2020-06-15 10:45:52 -070026 "sync"
Neha Sharmacc656962020-04-14 14:26:11 +000027 "time"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040028
Girish Gowdraa09aeab2020-09-14 16:30:52 -070029 "github.com/opencord/voltha-lib-go/v4/pkg/db"
Esin Karamanccb714b2019-11-29 15:02:06 +000030
Girish Gowdraa09aeab2020-09-14 16:30:52 -070031 "github.com/opencord/voltha-lib-go/v4/pkg/db/kvstore"
32 "github.com/opencord/voltha-lib-go/v4/pkg/log"
33 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
Matt Jeanneretcab955f2019-04-10 15:45:57 -040034)
35
36// Interface to pon resource manager APIs
37type iPonResourceMgr interface {
npujarec5762e2020-01-01 14:08:48 +053038 GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error)
Matteo Scandolo84585372021-03-18 14:21:22 -070039 FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error
Matt Jeanneretcab955f2019-04-10 15:45:57 -040040 GetResourceTypeAllocID() string
41 GetResourceTypeGemPortID() string
Matteo Scandolo84585372021-03-18 14:21:22 -070042 GetResourceTypeOnuID() string
Matt Jeanneretcab955f2019-04-10 15:45:57 -040043 GetTechnology() string
44}
45
46type Direction int32
47
48const (
49 Direction_UPSTREAM Direction = 0
50 Direction_DOWNSTREAM Direction = 1
51 Direction_BIDIRECTIONAL Direction = 2
52)
53
54var Direction_name = map[Direction]string{
55 0: "UPSTREAM",
56 1: "DOWNSTREAM",
57 2: "BIDIRECTIONAL",
58}
59
60type SchedulingPolicy int32
61
62const (
63 SchedulingPolicy_WRR SchedulingPolicy = 0
64 SchedulingPolicy_StrictPriority SchedulingPolicy = 1
65 SchedulingPolicy_Hybrid SchedulingPolicy = 2
66)
67
68var SchedulingPolicy_name = map[SchedulingPolicy]string{
69 0: "WRR",
70 1: "StrictPriority",
71 2: "Hybrid",
72}
73
74type AdditionalBW int32
75
76const (
77 AdditionalBW_AdditionalBW_None AdditionalBW = 0
78 AdditionalBW_AdditionalBW_NA AdditionalBW = 1
79 AdditionalBW_AdditionalBW_BestEffort AdditionalBW = 2
80 AdditionalBW_AdditionalBW_Auto AdditionalBW = 3
81)
82
83var AdditionalBW_name = map[AdditionalBW]string{
84 0: "AdditionalBW_None",
85 1: "AdditionalBW_NA",
86 2: "AdditionalBW_BestEffort",
87 3: "AdditionalBW_Auto",
88}
89
90type DiscardPolicy int32
91
92const (
93 DiscardPolicy_TailDrop DiscardPolicy = 0
94 DiscardPolicy_WTailDrop DiscardPolicy = 1
95 DiscardPolicy_Red DiscardPolicy = 2
96 DiscardPolicy_WRed DiscardPolicy = 3
97)
98
99var DiscardPolicy_name = map[DiscardPolicy]string{
100 0: "TailDrop",
101 1: "WTailDrop",
102 2: "Red",
103 3: "WRed",
104}
105
Girish Gowdra54934262019-11-13 14:19:55 +0530106// Required uniPortName format
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700107var uniPortNameFormat = regexp.MustCompile(`^olt-{[a-z0-9\-]+}/pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}$`)
Girish Gowdra54934262019-11-13 14:19:55 +0530108
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400109/*
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700110 type InferredAdditionBWIndication int32
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400111
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700112 const (
113 InferredAdditionBWIndication_InferredAdditionBWIndication_None InferredAdditionBWIndication = 0
114 InferredAdditionBWIndication_InferredAdditionBWIndication_Assured InferredAdditionBWIndication = 1
115 InferredAdditionBWIndication_InferredAdditionBWIndication_BestEffort InferredAdditionBWIndication = 2
116 )
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400117
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700118 var InferredAdditionBWIndication_name = map[int32]string{
119 0: "InferredAdditionBWIndication_None",
120 1: "InferredAdditionBWIndication_Assured",
121 2: "InferredAdditionBWIndication_BestEffort",
122 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400123*/
124// instance control defaults
125const (
126 defaultOnuInstance = "multi-instance"
127 defaultUniInstance = "single-instance"
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400128 defaultGemPayloadSize = "auto"
129)
130
131const MAX_GEM_PAYLOAD = "max_gem_payload_size"
132
133type InstanceControl struct {
Matt Jeanneret384d8c92019-05-06 14:27:31 -0400134 Onu string `json:"ONU"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400135 Uni string `json:"uni"`
136 MaxGemPayloadSize string `json:"max_gem_payload_size"`
137}
138
139// default discard config constants
140const (
141 defaultMinThreshold = 0
142 defaultMaxThreshold = 0
143 defaultMaxProbability = 0
144)
145
146type DiscardConfig struct {
147 MinThreshold int `json:"min_threshold"`
148 MaxThreshold int `json:"max_threshold"`
149 MaxProbability int `json:"max_probability"`
150}
151
152// default scheduler contants
153const (
kdarapub26b4502019-10-05 03:02:33 +0530154 defaultAdditionalBw = AdditionalBW_AdditionalBW_BestEffort
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400155 defaultPriority = 0
156 defaultWeight = 0
157 defaultQueueSchedPolicy = SchedulingPolicy_Hybrid
158)
159
160type Scheduler struct {
161 Direction string `json:"direction"`
162 AdditionalBw string `json:"additional_bw"`
163 Priority uint32 `json:"priority"`
164 Weight uint32 `json:"weight"`
165 QSchedPolicy string `json:"q_sched_policy"`
166}
167
168// default GEM attribute constants
169const (
Scott Bakeree7c0a02020-01-07 11:12:26 -0800170 defaultAESEncryption = "True"
171 defaultPriorityQueue = 0
172 defaultQueueWeight = 0
173 defaultMaxQueueSize = "auto"
174 defaultdropPolicy = DiscardPolicy_TailDrop
175 defaultSchedulePolicy = SchedulingPolicy_WRR
176 defaultIsMulticast = "False"
177 defaultAccessControlList = "224.0.0.0-239.255.255.255"
178 defaultMcastGemID = 4069
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400179)
180
181type GemPortAttribute struct {
182 MaxQueueSize string `json:"max_q_size"`
183 PbitMap string `json:"pbit_map"`
184 AesEncryption string `json:"aes_encryption"`
185 SchedulingPolicy string `json:"scheduling_policy"`
Manikkaraj kb1d51442019-07-23 10:41:02 -0400186 PriorityQueue uint32 `json:"priority_q"`
187 Weight uint32 `json:"weight"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400188 DiscardPolicy string `json:"discard_policy"`
189 DiscardConfig DiscardConfig `json:"discard_config"`
Scott Bakeree7c0a02020-01-07 11:12:26 -0800190 IsMulticast string `json:"is_multicast"`
191 DControlList string `json:"dynamic_access_control_list"`
192 SControlList string `json:"static_access_control_list"`
193 McastGemID uint32 `json:"multicast_gem_id"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400194}
195
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700196// Instance of Scheduler
197type IScheduler struct {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400198 AllocID uint32 `json:"alloc_id"`
199 Direction string `json:"direction"`
200 AdditionalBw string `json:"additional_bw"`
201 Priority uint32 `json:"priority"`
202 Weight uint32 `json:"weight"`
203 QSchedPolicy string `json:"q_sched_policy"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400204}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700205
206// Instance of GemPortAttribute
207type IGemPortAttribute struct {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400208 GemportID uint32 `json:"gemport_id"`
209 MaxQueueSize string `json:"max_q_size"`
210 PbitMap string `json:"pbit_map"`
211 AesEncryption string `json:"aes_encryption"`
212 SchedulingPolicy string `json:"scheduling_policy"`
Manikkaraj kb1d51442019-07-23 10:41:02 -0400213 PriorityQueue uint32 `json:"priority_q"`
214 Weight uint32 `json:"weight"`
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400215 DiscardPolicy string `json:"discard_policy"`
216 DiscardConfig DiscardConfig `json:"discard_config"`
Scott Bakeree7c0a02020-01-07 11:12:26 -0800217 IsMulticast string `json:"is_multicast"`
218 DControlList string `json:"dynamic_access_control_list"`
219 SControlList string `json:"static_access_control_list"`
220 McastGemID uint32 `json:"multicast_gem_id"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400221}
222
223type TechProfileMgr struct {
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700224 config *TechProfileFlags
225 resourceMgr iPonResourceMgr
Matteo Scandolo84585372021-03-18 14:21:22 -0700226 OnuIDMgmtLock sync.RWMutex
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700227 GemPortIDMgmtLock sync.RWMutex
228 AllocIDMgmtLock sync.RWMutex
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400229}
230type DefaultTechProfile struct {
231 Name string `json:"name"`
232 ProfileType string `json:"profile_type"`
233 Version int `json:"version"`
234 NumGemPorts uint32 `json:"num_gem_ports"`
235 InstanceCtrl InstanceControl `json:"instance_control"`
236 UsScheduler Scheduler `json:"us_scheduler"`
237 DsScheduler Scheduler `json:"ds_scheduler"`
238 UpstreamGemPortAttributeList []GemPortAttribute `json:"upstream_gem_port_attribute_list"`
239 DownstreamGemPortAttributeList []GemPortAttribute `json:"downstream_gem_port_attribute_list"`
240}
241type TechProfile struct {
242 Name string `json:"name"`
243 SubscriberIdentifier string `json:"subscriber_identifier"`
244 ProfileType string `json:"profile_type"`
245 Version int `json:"version"`
246 NumGemPorts uint32 `json:"num_gem_ports"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400247 InstanceCtrl InstanceControl `json:"instance_control"`
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700248 UsScheduler IScheduler `json:"us_scheduler"`
249 DsScheduler IScheduler `json:"ds_scheduler"`
250 UpstreamGemPortAttributeList []IGemPortAttribute `json:"upstream_gem_port_attribute_list"`
251 DownstreamGemPortAttributeList []IGemPortAttribute `json:"downstream_gem_port_attribute_list"`
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400252}
253
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700254// QThresholds struct for EPON
255type QThresholds struct {
256 QThreshold1 uint32 `json:"q_threshold1"`
257 QThreshold2 uint32 `json:"q_threshold2"`
258 QThreshold3 uint32 `json:"q_threshold3"`
259 QThreshold4 uint32 `json:"q_threshold4"`
260 QThreshold5 uint32 `json:"q_threshold5"`
261 QThreshold6 uint32 `json:"q_threshold6"`
262 QThreshold7 uint32 `json:"q_threshold7"`
263}
264
265// UpstreamQueueAttribute struct for EPON
266type UpstreamQueueAttribute struct {
267 MaxQueueSize string `json:"max_q_size"`
268 PbitMap string `json:"pbit_map"`
269 AesEncryption string `json:"aes_encryption"`
270 TrafficType string `json:"traffic_type"`
271 UnsolicitedGrantSize uint32 `json:"unsolicited_grant_size"`
272 NominalInterval uint32 `json:"nominal_interval"`
273 ToleratedPollJitter uint32 `json:"tolerated_poll_jitter"`
274 RequestTransmissionPolicy uint32 `json:"request_transmission_policy"`
275 NumQueueSet uint32 `json:"num_q_sets"`
276 QThresholds QThresholds `json:"q_thresholds"`
277 SchedulingPolicy string `json:"scheduling_policy"`
278 PriorityQueue uint32 `json:"priority_q"`
279 Weight uint32 `json:"weight"`
280 DiscardPolicy string `json:"discard_policy"`
281 DiscardConfig DiscardConfig `json:"discard_config"`
282}
283
284// Default EPON constants
285const (
286 defaultPakageType = "B"
287)
288const (
289 defaultTrafficType = "BE"
290 defaultUnsolicitedGrantSize = 0
291 defaultNominalInterval = 0
292 defaultToleratedPollJitter = 0
293 defaultRequestTransmissionPolicy = 0
294 defaultNumQueueSet = 2
295)
296const (
297 defaultQThreshold1 = 5500
298 defaultQThreshold2 = 0
299 defaultQThreshold3 = 0
300 defaultQThreshold4 = 0
301 defaultQThreshold5 = 0
302 defaultQThreshold6 = 0
303 defaultQThreshold7 = 0
304)
305
306// DownstreamQueueAttribute struct for EPON
307type DownstreamQueueAttribute struct {
308 MaxQueueSize string `json:"max_q_size"`
309 PbitMap string `json:"pbit_map"`
310 AesEncryption string `json:"aes_encryption"`
311 SchedulingPolicy string `json:"scheduling_policy"`
312 PriorityQueue uint32 `json:"priority_q"`
313 Weight uint32 `json:"weight"`
314 DiscardPolicy string `json:"discard_policy"`
315 DiscardConfig DiscardConfig `json:"discard_config"`
316}
317
318// iUpstreamQueueAttribute struct for EPON
319type iUpstreamQueueAttribute struct {
320 GemportID uint32 `json:"q_id"`
321 MaxQueueSize string `json:"max_q_size"`
322 PbitMap string `json:"pbit_map"`
323 AesEncryption string `json:"aes_encryption"`
324 TrafficType string `json:"traffic_type"`
325 UnsolicitedGrantSize uint32 `json:"unsolicited_grant_size"`
326 NominalInterval uint32 `json:"nominal_interval"`
327 ToleratedPollJitter uint32 `json:"tolerated_poll_jitter"`
328 RequestTransmissionPolicy uint32 `json:"request_transmission_policy"`
329 NumQueueSet uint32 `json:"num_q_sets"`
330 QThresholds QThresholds `json:"q_thresholds"`
331 SchedulingPolicy string `json:"scheduling_policy"`
332 PriorityQueue uint32 `json:"priority_q"`
333 Weight uint32 `json:"weight"`
334 DiscardPolicy string `json:"discard_policy"`
335 DiscardConfig DiscardConfig `json:"discard_config"`
336}
337
338// iDownstreamQueueAttribute struct for EPON
339type iDownstreamQueueAttribute struct {
340 GemportID uint32 `json:"q_id"`
341 MaxQueueSize string `json:"max_q_size"`
342 PbitMap string `json:"pbit_map"`
343 AesEncryption string `json:"aes_encryption"`
344 SchedulingPolicy string `json:"scheduling_policy"`
345 PriorityQueue uint32 `json:"priority_q"`
346 Weight uint32 `json:"weight"`
347 DiscardPolicy string `json:"discard_policy"`
348 DiscardConfig DiscardConfig `json:"discard_config"`
349}
350
351// EponAttribute struct for EPON
352type EponAttribute struct {
353 PackageType string `json:"pakage_type"`
354}
355
356// DefaultTechProfile struct for EPON
357type DefaultEponProfile struct {
358 Name string `json:"name"`
359 ProfileType string `json:"profile_type"`
360 Version int `json:"version"`
361 NumGemPorts uint32 `json:"num_gem_ports"`
362 InstanceCtrl InstanceControl `json:"instance_control"`
363 EponAttribute EponAttribute `json:"epon_attribute"`
364 UpstreamQueueAttributeList []UpstreamQueueAttribute `json:"upstream_queue_attribute_list"`
365 DownstreamQueueAttributeList []DownstreamQueueAttribute `json:"downstream_queue_attribute_list"`
366}
367
368// TechProfile struct for EPON
369type EponProfile struct {
370 Name string `json:"name"`
371 SubscriberIdentifier string `json:"subscriber_identifier"`
372 ProfileType string `json:"profile_type"`
373 Version int `json:"version"`
374 NumGemPorts uint32 `json:"num_gem_ports"`
375 InstanceCtrl InstanceControl `json:"instance_control"`
376 EponAttribute EponAttribute `json:"epon_attribute"`
377 AllocID uint32 `json:"llid"`
378 UpstreamQueueAttributeList []iUpstreamQueueAttribute `json:"upstream_queue_attribute_list"`
379 DownstreamQueueAttributeList []iDownstreamQueueAttribute `json:"downstream_queue_attribute_list"`
380}
381
382const (
Andrea Campanella974d7452020-06-26 19:32:30 +0200383 xgspon = "XGS-PON"
384 gpon = "GPON"
385 epon = "EPON"
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700386)
387
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800388func (t *TechProfileMgr) SetKVClient(ctx context.Context, pathPrefix string) *db.Backend {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000389 kvClient, err := newKVClient(ctx, t.config.KVStoreType, t.config.KVStoreAddress, t.config.KVStoreTimeout)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400390 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000391 logger.Errorw(ctx, "failed-to-create-kv-client",
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400392 log.Fields{
Neha Sharma3f221ae2020-04-29 19:02:12 +0000393 "type": t.config.KVStoreType, "address": t.config.KVStoreAddress,
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800394 "timeout": t.config.KVStoreTimeout, "prefix": pathPrefix,
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400395 "error": err.Error(),
396 })
397 return nil
398 }
sbarbaria8910ba2019-11-05 10:12:23 -0500399 return &db.Backend{
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400400 Client: kvClient,
401 StoreType: t.config.KVStoreType,
Neha Sharma3f221ae2020-04-29 19:02:12 +0000402 Address: t.config.KVStoreAddress,
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400403 Timeout: t.config.KVStoreTimeout,
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800404 PathPrefix: pathPrefix}
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400405
406 /* TODO : Make sure direct call to NewBackend is working fine with backend , currently there is some
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700407 issue between kv store and backend , core is not calling NewBackend directly
408 kv := model.NewBackend(t.config.KVStoreType, t.config.KVStoreHost, t.config.KVStorePort,
409 t.config.KVStoreTimeout, kvStoreTechProfilePathPrefix)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400410 */
411}
412
Neha Sharma96b7bf22020-06-15 10:37:32 +0000413func newKVClient(ctx context.Context, storeType string, address string, timeout time.Duration) (kvstore.Client, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400414
Neha Sharma96b7bf22020-06-15 10:37:32 +0000415 logger.Infow(ctx, "kv-store", log.Fields{"storeType": storeType, "address": address})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400416 switch storeType {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400417 case "etcd":
Neha Sharma96b7bf22020-06-15 10:37:32 +0000418 return kvstore.NewEtcdClient(ctx, address, timeout, log.WarnLevel)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400419 }
420 return nil, errors.New("unsupported-kv-store")
421}
422
Matteo Scandoloc858ab72020-11-16 12:44:51 -0800423func NewTechProfile(ctx context.Context, resourceMgr iPonResourceMgr, KVStoreType string, KVStoreAddress string, basePathKvStore string) (*TechProfileMgr, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400424 var techprofileObj TechProfileMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000425 logger.Debug(ctx, "Initializing techprofile Manager")
Matteo Scandoloc858ab72020-11-16 12:44:51 -0800426 techprofileObj.config = NewTechProfileFlags(KVStoreType, KVStoreAddress, basePathKvStore)
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800427 techprofileObj.config.KVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.TPKVPathPrefix)
428 techprofileObj.config.DefaultTpKVBackend = techprofileObj.SetKVClient(ctx, techprofileObj.config.defaultTpKvPathPrefix)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400429 if techprofileObj.config.KVBackend == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000430 logger.Error(ctx, "Failed to initialize KV backend\n")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400431 return nil, errors.New("KV backend init failed")
432 }
433 techprofileObj.resourceMgr = resourceMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Debug(ctx, "Initializing techprofile object instance success")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400435 return &techprofileObj, nil
436}
437
Neha Sharma96b7bf22020-06-15 10:37:32 +0000438func (t *TechProfileMgr) GetTechProfileInstanceKVPath(ctx context.Context, techProfiletblID uint32, uniPortName string) string {
439 logger.Debugw(ctx, "get-tp-instance-kv-path", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700440 "uniPortName": uniPortName,
441 "tpId": techProfiletblID,
442 })
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400443 return fmt.Sprintf(t.config.TPInstanceKVPath, t.resourceMgr.GetTechnology(), techProfiletblID, uniPortName)
444}
445
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700446func (t *TechProfileMgr) GetTPInstanceFromKVStore(ctx context.Context, techProfiletblID uint32, path string) (interface{}, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400447 var err error
Girish Gowdra54934262019-11-13 14:19:55 +0530448 var kvResult *kvstore.KVPair
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700449 var KvTpIns TechProfile
450 var KvEponIns EponProfile
451 var resPtr interface{}
452 // For example:
453 // tpInstPath like "XGS-PON/64/uni_port_name"
454 // is broken into ["XGS-PON" "64" ...]
455 pathSlice := regexp.MustCompile(`/`).Split(path, -1)
456 switch pathSlice[0] {
Andrea Campanella974d7452020-06-26 19:32:30 +0200457 case xgspon, gpon:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700458 resPtr = &KvTpIns
459 case epon:
460 resPtr = &KvEponIns
461 default:
Girish Kumar935f7af2020-08-18 11:59:42 +0000462 logger.Errorw(ctx, "unknown-tech", log.Fields{"tech": pathSlice[0]})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700463 return nil, fmt.Errorf("unknown-tech-%s", pathSlice[0])
464 }
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700465
npujarec5762e2020-01-01 14:08:48 +0530466 kvResult, _ = t.config.KVBackend.Get(ctx, path)
Girish Gowdra54934262019-11-13 14:19:55 +0530467 if kvResult == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000468 logger.Infow(ctx, "tp-instance-not-found-on-kv", log.Fields{"key": path})
Girish Gowdra54934262019-11-13 14:19:55 +0530469 return nil, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400470 } else {
Girish Gowdra54934262019-11-13 14:19:55 +0530471 if value, err := kvstore.ToByte(kvResult.Value); err == nil {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400472 if err = json.Unmarshal(value, resPtr); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000473 logger.Errorw(ctx, "error-unmarshal-kv-result", log.Fields{"key": path, "value": value})
Girish Gowdra54934262019-11-13 14:19:55 +0530474 return nil, errors.New("error-unmarshal-kv-result")
475 } else {
476 return resPtr, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400477 }
478 }
479 }
Girish Gowdra54934262019-11-13 14:19:55 +0530480 return nil, err
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400481}
482
npujarec5762e2020-01-01 14:08:48 +0530483func (t *TechProfileMgr) addTechProfInstanceToKVStore(ctx context.Context, techProfiletblID uint32, uniPortName string, tpInstance *TechProfile) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000484 path := t.GetTechProfileInstanceKVPath(ctx, techProfiletblID, uniPortName)
485 logger.Debugw(ctx, "Adding techprof instance to kvstore", log.Fields{"key": path, "tpinstance": tpInstance})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400486 tpInstanceJson, err := json.Marshal(*tpInstance)
487 if err == nil {
488 // Backend will convert JSON byte array into string format
Neha Sharma96b7bf22020-06-15 10:37:32 +0000489 logger.Debugw(ctx, "Storing tech profile instance to KV Store", log.Fields{"key": path, "val": tpInstanceJson})
npujarec5762e2020-01-01 14:08:48 +0530490 err = t.config.KVBackend.Put(ctx, path, tpInstanceJson)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400491 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000492 logger.Errorw(ctx, "Error in marshaling into Json format", log.Fields{"key": path, "tpinstance": tpInstance})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400493 }
494 return err
495}
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700496
497func (t *TechProfileMgr) addEponProfInstanceToKVStore(ctx context.Context, techProfiletblID uint32, uniPortName string, tpInstance *EponProfile) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000498 path := t.GetTechProfileInstanceKVPath(ctx, techProfiletblID, uniPortName)
499 logger.Debugw(ctx, "Adding techprof instance to kvstore", log.Fields{"key": path, "tpinstance": tpInstance})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700500 tpInstanceJson, err := json.Marshal(*tpInstance)
501 if err == nil {
502 // Backend will convert JSON byte array into string format
Neha Sharma96b7bf22020-06-15 10:37:32 +0000503 logger.Debugw(ctx, "Storing tech profile instance to KV Store", log.Fields{"key": path, "val": tpInstanceJson})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700504 err = t.config.KVBackend.Put(ctx, path, tpInstanceJson)
505 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000506 logger.Errorw(ctx, "Error in marshaling into Json format", log.Fields{"key": path, "tpinstance": tpInstance})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700507 }
508 return err
509}
510
npujarec5762e2020-01-01 14:08:48 +0530511func (t *TechProfileMgr) getTPFromKVStore(ctx context.Context, techProfiletblID uint32) *DefaultTechProfile {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400512 var kvtechprofile DefaultTechProfile
513 key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000514 logger.Debugw(ctx, "Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800515 kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400516 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000517 logger.Errorw(ctx, "Error while fetching value from KV store", log.Fields{"key": key})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400518 return nil
519 }
520 if kvresult != nil {
521 /* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
522 if value, err := kvstore.ToByte(kvresult.Value); err == nil {
Girish Kumar8f73fe02019-12-09 13:19:37 +0000523 if err = json.Unmarshal(value, &kvtechprofile); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000524 logger.Errorw(ctx, "Error unmarshaling techprofile fetched from KV store", log.Fields{"techProfiletblID": techProfiletblID, "error": err, "techprofile_json": value})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000525 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400526 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000527
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 logger.Debugw(ctx, "Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000529 return &kvtechprofile
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400530 }
531 }
532 return nil
533}
Girish Kumar8f73fe02019-12-09 13:19:37 +0000534
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700535func (t *TechProfileMgr) getEponTPFromKVStore(ctx context.Context, techProfiletblID uint32) *DefaultEponProfile {
536 var kvtechprofile DefaultEponProfile
537 key := fmt.Sprintf(t.config.TPFileKVPath, t.resourceMgr.GetTechnology(), techProfiletblID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 logger.Debugw(ctx, "Getting techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "Key": key})
Matteo Scandolod9d6f512020-11-24 13:57:53 -0800539 kvresult, err := t.config.DefaultTpKVBackend.Get(ctx, key)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700540 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000541 logger.Errorw(ctx, "Error while fetching value from KV store", log.Fields{"key": key})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700542 return nil
543 }
544 if kvresult != nil {
545 /* Backend will return Value in string format,needs to be converted to []byte before unmarshal*/
546 if value, err := kvstore.ToByte(kvresult.Value); err == nil {
547 if err = json.Unmarshal(value, &kvtechprofile); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000548 logger.Errorw(ctx, "Error unmarshaling techprofile fetched from KV store", log.Fields{"techProfiletblID": techProfiletblID, "error": err, "techprofile_json": value})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700549 return nil
550 }
551
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 logger.Debugw(ctx, "Success fetched techprofile from KV store", log.Fields{"techProfiletblID": techProfiletblID, "value": kvtechprofile})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700553 return &kvtechprofile
554 }
555 }
556 return nil
557}
558
559func (t *TechProfileMgr) CreateTechProfInstance(ctx context.Context, techProfiletblID uint32, uniPortName string, intfId uint32) (interface{}, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400560 var tpInstance *TechProfile
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700561 var tpEponInstance *EponProfile
562
Neha Sharma96b7bf22020-06-15 10:37:32 +0000563 logger.Infow(ctx, "creating-tp-instance", log.Fields{"tableid": techProfiletblID, "uni": uniPortName, "intId": intfId})
Girish Gowdra54934262019-11-13 14:19:55 +0530564
565 // Make sure the uniPortName is as per format pon-{[0-9]+}/onu-{[0-9]+}/uni-{[0-9]+}
566 if !uniPortNameFormat.Match([]byte(uniPortName)) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000567 logger.Errorw(ctx, "uni-port-name-not-confirming-to-format", log.Fields{"uniPortName": uniPortName})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000568 return nil, errors.New("uni-port-name-not-confirming-to-format")
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400569 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000570 tpInstancePath := t.GetTechProfileInstanceKVPath(ctx, techProfiletblID, uniPortName)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700571 // For example:
572 // tpInstPath like "XGS-PON/64/uni_port_name"
573 // is broken into ["XGS-PON" "64" ...]
574 pathSlice := regexp.MustCompile(`/`).Split(tpInstancePath, -1)
575 if pathSlice[0] == epon {
576 tp := t.getEponTPFromKVStore(ctx, techProfiletblID)
577 if tp != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000578 if err := t.validateInstanceControlAttr(ctx, tp.InstanceCtrl); err != nil {
579 logger.Error(ctx, "invalid-instance-ctrl-attr--using-default-tp")
Girish Kumar935f7af2020-08-18 11:59:42 +0000580 tp = t.getDefaultEponProfile(ctx)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700581 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000582 logger.Infow(ctx, "using-specified-tp-from-kv-store", log.Fields{"tpid": techProfiletblID})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700583 }
584 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Info(ctx, "tp-not-found-on-kv--creating-default-tp")
Girish Kumar935f7af2020-08-18 11:59:42 +0000586 tp = t.getDefaultEponProfile(ctx)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700587 }
588
589 if tpEponInstance = t.allocateEponTPInstance(ctx, uniPortName, tp, intfId, tpInstancePath); tpEponInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000590 logger.Error(ctx, "tp-intance-allocation-failed")
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700591 return nil, errors.New("tp-intance-allocation-failed")
592 }
593 if err := t.addEponProfInstanceToKVStore(ctx, techProfiletblID, uniPortName, tpEponInstance); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000594 logger.Errorw(ctx, "error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700595 return nil, errors.New("error-adding-tp-to-kv-store")
596 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000597 logger.Infow(ctx, "tp-added-to-kv-store-successfully",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700598 log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
599 return tpEponInstance, nil
600 } else {
601 tp := t.getTPFromKVStore(ctx, techProfiletblID)
602 if tp != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000603 if err := t.validateInstanceControlAttr(ctx, tp.InstanceCtrl); err != nil {
604 logger.Error(ctx, "invalid-instance-ctrl-attr--using-default-tp")
605 tp = t.getDefaultTechProfile(ctx)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700606 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000607 logger.Infow(ctx, "using-specified-tp-from-kv-store", log.Fields{"tpid": techProfiletblID})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700608 }
609 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 logger.Info(ctx, "tp-not-found-on-kv--creating-default-tp")
611 tp = t.getDefaultTechProfile(ctx)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700612 }
613
614 if tpInstance = t.allocateTPInstance(ctx, uniPortName, tp, intfId, tpInstancePath); tpInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000615 logger.Error(ctx, "tp-intance-allocation-failed")
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700616 return nil, errors.New("tp-intance-allocation-failed")
617 }
618 if err := t.addTechProfInstanceToKVStore(ctx, techProfiletblID, uniPortName, tpInstance); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000619 logger.Errorw(ctx, "error-adding-tp-to-kv-store", log.Fields{"tableid": techProfiletblID, "uni": uniPortName})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700620 return nil, errors.New("error-adding-tp-to-kv-store")
621 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000622 logger.Infow(ctx, "tp-added-to-kv-store-successfully",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700623 log.Fields{"tpid": techProfiletblID, "uni": uniPortName, "intfId": intfId})
624 return tpInstance, nil
Girish Gowdra54934262019-11-13 14:19:55 +0530625 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400626}
627
npujarec5762e2020-01-01 14:08:48 +0530628func (t *TechProfileMgr) DeleteTechProfileInstance(ctx context.Context, techProfiletblID uint32, uniPortName string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000629 path := t.GetTechProfileInstanceKVPath(ctx, techProfiletblID, uniPortName)
npujarec5762e2020-01-01 14:08:48 +0530630 return t.config.KVBackend.Delete(ctx, path)
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400631}
632
Neha Sharma96b7bf22020-06-15 10:37:32 +0000633func (t *TechProfileMgr) validateInstanceControlAttr(ctx context.Context, instCtl InstanceControl) error {
Girish Gowdra54934262019-11-13 14:19:55 +0530634 if instCtl.Onu != "single-instance" && instCtl.Onu != "multi-instance" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000635 logger.Errorw(ctx, "invalid-onu-instance-control-attribute", log.Fields{"onu-inst": instCtl.Onu})
Girish Gowdra54934262019-11-13 14:19:55 +0530636 return errors.New("invalid-onu-instance-ctl-attr")
637 }
638
639 if instCtl.Uni != "single-instance" && instCtl.Uni != "multi-instance" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000640 logger.Errorw(ctx, "invalid-uni-instance-control-attribute", log.Fields{"uni-inst": instCtl.Uni})
Girish Gowdra54934262019-11-13 14:19:55 +0530641 return errors.New("invalid-uni-instance-ctl-attr")
642 }
643
644 if instCtl.Uni == "multi-instance" {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000645 logger.Error(ctx, "uni-multi-instance-tp-not-supported")
Girish Gowdra54934262019-11-13 14:19:55 +0530646 return errors.New("uni-multi-instance-tp-not-supported")
647 }
648
649 return nil
650}
651
npujarec5762e2020-01-01 14:08:48 +0530652func (t *TechProfileMgr) allocateTPInstance(ctx context.Context, uniPortName string, tp *DefaultTechProfile, intfId uint32, tpInstPath string) *TechProfile {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400653
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700654 var usGemPortAttributeList []IGemPortAttribute
655 var dsGemPortAttributeList []IGemPortAttribute
656 var dsMulticastGemAttributeList []IGemPortAttribute
657 var dsUnicastGemAttributeList []IGemPortAttribute
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400658 var tcontIDs []uint32
659 var gemPorts []uint32
660 var err error
661
Neha Sharma96b7bf22020-06-15 10:37:32 +0000662 logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
Girish Gowdra54934262019-11-13 14:19:55 +0530663
664 if tp.InstanceCtrl.Onu == "multi-instance" {
Matteo Scandolo84585372021-03-18 14:21:22 -0700665 tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700666 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000667 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Girish Gowdra54934262019-11-13 14:19:55 +0530668 return nil
669 }
670 } else { // "single-instance"
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000671 if tpInst, err := t.getSingleInstanceTp(ctx, tpInstPath); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000672 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Rohan Agrawal02f784d2020-02-14 09:34:02 +0000673 return nil
674 } else if tpInst == nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530675 // No "single-instance" tp found on one any uni port for the given TP ID
676 // Allocate a new TcontID or AllocID
Matteo Scandolo84585372021-03-18 14:21:22 -0700677 tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1)
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700678 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000679 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Girish Gowdra54934262019-11-13 14:19:55 +0530680 return nil
681 }
682 } else {
683 // Use the alloc-id from the existing TpInstance
684 tcontIDs = append(tcontIDs, tpInst.UsScheduler.AllocID)
685 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400686 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000687 logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
Matteo Scandolo84585372021-03-18 14:21:22 -0700688 gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts)
Girish Gowdra631ef3d2020-06-15 10:45:52 -0700689 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000690 logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400691 return nil
692 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000693 logger.Infow(ctx, "Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400694 for index := 0; index < int(tp.NumGemPorts); index++ {
695 usGemPortAttributeList = append(usGemPortAttributeList,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700696 IGemPortAttribute{GemportID: gemPorts[index],
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400697 MaxQueueSize: tp.UpstreamGemPortAttributeList[index].MaxQueueSize,
698 PbitMap: tp.UpstreamGemPortAttributeList[index].PbitMap,
699 AesEncryption: tp.UpstreamGemPortAttributeList[index].AesEncryption,
700 SchedulingPolicy: tp.UpstreamGemPortAttributeList[index].SchedulingPolicy,
701 PriorityQueue: tp.UpstreamGemPortAttributeList[index].PriorityQueue,
702 Weight: tp.UpstreamGemPortAttributeList[index].Weight,
703 DiscardPolicy: tp.UpstreamGemPortAttributeList[index].DiscardPolicy,
704 DiscardConfig: tp.UpstreamGemPortAttributeList[index].DiscardConfig})
Scott Bakeree7c0a02020-01-07 11:12:26 -0800705 }
706
Neha Sharma96b7bf22020-06-15 10:37:32 +0000707 logger.Info(ctx, "length of DownstreamGemPortAttributeList", len(tp.DownstreamGemPortAttributeList))
Scott Bakeree7c0a02020-01-07 11:12:26 -0800708 //put multicast and unicast downstream GEM port attributes in different lists first
709 for index := 0; index < int(len(tp.DownstreamGemPortAttributeList)); index++ {
710 if isMulticastGem(tp.DownstreamGemPortAttributeList[index].IsMulticast) {
711 dsMulticastGemAttributeList = append(dsMulticastGemAttributeList,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700712 IGemPortAttribute{
Scott Bakeree7c0a02020-01-07 11:12:26 -0800713 McastGemID: tp.DownstreamGemPortAttributeList[index].McastGemID,
714 MaxQueueSize: tp.DownstreamGemPortAttributeList[index].MaxQueueSize,
715 PbitMap: tp.DownstreamGemPortAttributeList[index].PbitMap,
716 AesEncryption: tp.DownstreamGemPortAttributeList[index].AesEncryption,
717 SchedulingPolicy: tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
718 PriorityQueue: tp.DownstreamGemPortAttributeList[index].PriorityQueue,
719 Weight: tp.DownstreamGemPortAttributeList[index].Weight,
720 DiscardPolicy: tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
721 DiscardConfig: tp.DownstreamGemPortAttributeList[index].DiscardConfig,
722 IsMulticast: tp.DownstreamGemPortAttributeList[index].IsMulticast,
723 DControlList: tp.DownstreamGemPortAttributeList[index].DControlList,
724 SControlList: tp.DownstreamGemPortAttributeList[index].SControlList})
725 } else {
726 dsUnicastGemAttributeList = append(dsUnicastGemAttributeList,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700727 IGemPortAttribute{
Scott Bakeree7c0a02020-01-07 11:12:26 -0800728 MaxQueueSize: tp.DownstreamGemPortAttributeList[index].MaxQueueSize,
729 PbitMap: tp.DownstreamGemPortAttributeList[index].PbitMap,
730 AesEncryption: tp.DownstreamGemPortAttributeList[index].AesEncryption,
731 SchedulingPolicy: tp.DownstreamGemPortAttributeList[index].SchedulingPolicy,
732 PriorityQueue: tp.DownstreamGemPortAttributeList[index].PriorityQueue,
733 Weight: tp.DownstreamGemPortAttributeList[index].Weight,
734 DiscardPolicy: tp.DownstreamGemPortAttributeList[index].DiscardPolicy,
735 DiscardConfig: tp.DownstreamGemPortAttributeList[index].DiscardConfig})
736 }
737 }
738 //add unicast downstream GEM ports to dsGemPortAttributeList
739 for index := 0; index < int(tp.NumGemPorts); index++ {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400740 dsGemPortAttributeList = append(dsGemPortAttributeList,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700741 IGemPortAttribute{GemportID: gemPorts[index],
Scott Bakeree7c0a02020-01-07 11:12:26 -0800742 MaxQueueSize: dsUnicastGemAttributeList[index].MaxQueueSize,
743 PbitMap: dsUnicastGemAttributeList[index].PbitMap,
744 AesEncryption: dsUnicastGemAttributeList[index].AesEncryption,
745 SchedulingPolicy: dsUnicastGemAttributeList[index].SchedulingPolicy,
746 PriorityQueue: dsUnicastGemAttributeList[index].PriorityQueue,
747 Weight: dsUnicastGemAttributeList[index].Weight,
748 DiscardPolicy: dsUnicastGemAttributeList[index].DiscardPolicy,
749 DiscardConfig: dsUnicastGemAttributeList[index].DiscardConfig})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400750 }
Scott Bakeree7c0a02020-01-07 11:12:26 -0800751 //add multicast GEM ports to dsGemPortAttributeList afterwards
752 for k := range dsMulticastGemAttributeList {
753 dsGemPortAttributeList = append(dsGemPortAttributeList, dsMulticastGemAttributeList[k])
754 }
755
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400756 return &TechProfile{
757 SubscriberIdentifier: uniPortName,
758 Name: tp.Name,
759 ProfileType: tp.ProfileType,
760 Version: tp.Version,
761 NumGemPorts: tp.NumGemPorts,
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400762 InstanceCtrl: tp.InstanceCtrl,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700763 UsScheduler: IScheduler{
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400764 AllocID: tcontIDs[0],
765 Direction: tp.UsScheduler.Direction,
766 AdditionalBw: tp.UsScheduler.AdditionalBw,
767 Priority: tp.UsScheduler.Priority,
768 Weight: tp.UsScheduler.Weight,
769 QSchedPolicy: tp.UsScheduler.QSchedPolicy},
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700770 DsScheduler: IScheduler{
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400771 AllocID: tcontIDs[0],
772 Direction: tp.DsScheduler.Direction,
773 AdditionalBw: tp.DsScheduler.AdditionalBw,
774 Priority: tp.DsScheduler.Priority,
775 Weight: tp.DsScheduler.Weight,
776 QSchedPolicy: tp.DsScheduler.QSchedPolicy},
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400777 UpstreamGemPortAttributeList: usGemPortAttributeList,
778 DownstreamGemPortAttributeList: dsGemPortAttributeList}
779}
780
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700781// allocateTPInstance function for EPON
782func (t *TechProfileMgr) allocateEponTPInstance(ctx context.Context, uniPortName string, tp *DefaultEponProfile, intfId uint32, tpInstPath string) *EponProfile {
783
784 var usQueueAttributeList []iUpstreamQueueAttribute
785 var dsQueueAttributeList []iDownstreamQueueAttribute
786 var tcontIDs []uint32
787 var gemPorts []uint32
788 var err error
789
Girish Kumar935f7af2020-08-18 11:59:42 +0000790 logger.Infow(ctx, "Allocating TechProfileMgr instance from techprofile template", log.Fields{"uniPortName": uniPortName, "intfId": intfId, "numGem": tp.NumGemPorts})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700791
792 if tp.InstanceCtrl.Onu == "multi-instance" {
Matteo Scandolo84585372021-03-18 14:21:22 -0700793 if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
Girish Kumar935f7af2020-08-18 11:59:42 +0000794 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700795 return nil
796 }
797 } else { // "single-instance"
798 if tpInst, err := t.getSingleInstanceEponTp(ctx, tpInstPath); err != nil {
Girish Kumar935f7af2020-08-18 11:59:42 +0000799 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700800 return nil
801 } else if tpInst == nil {
802 // No "single-instance" tp found on one any uni port for the given TP ID
803 // Allocate a new TcontID or AllocID
Matteo Scandolo84585372021-03-18 14:21:22 -0700804 if tcontIDs, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeAllocID(), 1); err != nil {
Girish Kumar935f7af2020-08-18 11:59:42 +0000805 logger.Errorw(ctx, "Error getting alloc id from rsrcrMgr", log.Fields{"intfId": intfId})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700806 return nil
807 }
808 } else {
809 // Use the alloc-id from the existing TpInstance
810 tcontIDs = append(tcontIDs, tpInst.AllocID)
811 }
812 }
Girish Kumar935f7af2020-08-18 11:59:42 +0000813 logger.Debugw(ctx, "Num GEM ports in TP:", log.Fields{"NumGemPorts": tp.NumGemPorts})
Matteo Scandolo84585372021-03-18 14:21:22 -0700814 if gemPorts, err = t.GetResourceID(ctx, intfId, t.resourceMgr.GetResourceTypeGemPortID(), tp.NumGemPorts); err != nil {
Girish Kumar935f7af2020-08-18 11:59:42 +0000815 logger.Errorw(ctx, "Error getting gemport ids from rsrcrMgr", log.Fields{"intfId": intfId, "numGemports": tp.NumGemPorts})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700816 return nil
817 }
Girish Kumar935f7af2020-08-18 11:59:42 +0000818 logger.Infow(ctx, "Allocated tconts and GEM ports successfully", log.Fields{"tconts": tcontIDs, "gemports": gemPorts})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700819 for index := 0; index < int(tp.NumGemPorts); index++ {
820 usQueueAttributeList = append(usQueueAttributeList,
821 iUpstreamQueueAttribute{GemportID: gemPorts[index],
822 MaxQueueSize: tp.UpstreamQueueAttributeList[index].MaxQueueSize,
823 PbitMap: tp.UpstreamQueueAttributeList[index].PbitMap,
824 AesEncryption: tp.UpstreamQueueAttributeList[index].AesEncryption,
825 TrafficType: tp.UpstreamQueueAttributeList[index].TrafficType,
826 UnsolicitedGrantSize: tp.UpstreamQueueAttributeList[index].UnsolicitedGrantSize,
827 NominalInterval: tp.UpstreamQueueAttributeList[index].NominalInterval,
828 ToleratedPollJitter: tp.UpstreamQueueAttributeList[index].ToleratedPollJitter,
829 RequestTransmissionPolicy: tp.UpstreamQueueAttributeList[index].RequestTransmissionPolicy,
830 NumQueueSet: tp.UpstreamQueueAttributeList[index].NumQueueSet,
831 QThresholds: tp.UpstreamQueueAttributeList[index].QThresholds,
832 SchedulingPolicy: tp.UpstreamQueueAttributeList[index].SchedulingPolicy,
833 PriorityQueue: tp.UpstreamQueueAttributeList[index].PriorityQueue,
834 Weight: tp.UpstreamQueueAttributeList[index].Weight,
835 DiscardPolicy: tp.UpstreamQueueAttributeList[index].DiscardPolicy,
836 DiscardConfig: tp.UpstreamQueueAttributeList[index].DiscardConfig})
837 }
838
Girish Kumar935f7af2020-08-18 11:59:42 +0000839 logger.Info(ctx, "length of DownstreamGemPortAttributeList", len(tp.DownstreamQueueAttributeList))
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700840 for index := 0; index < int(tp.NumGemPorts); index++ {
841 dsQueueAttributeList = append(dsQueueAttributeList,
842 iDownstreamQueueAttribute{GemportID: gemPorts[index],
843 MaxQueueSize: tp.DownstreamQueueAttributeList[index].MaxQueueSize,
844 PbitMap: tp.DownstreamQueueAttributeList[index].PbitMap,
845 AesEncryption: tp.DownstreamQueueAttributeList[index].AesEncryption,
846 SchedulingPolicy: tp.DownstreamQueueAttributeList[index].SchedulingPolicy,
847 PriorityQueue: tp.DownstreamQueueAttributeList[index].PriorityQueue,
848 Weight: tp.DownstreamQueueAttributeList[index].Weight,
849 DiscardPolicy: tp.DownstreamQueueAttributeList[index].DiscardPolicy,
850 DiscardConfig: tp.DownstreamQueueAttributeList[index].DiscardConfig})
851 }
852
853 return &EponProfile{
854 SubscriberIdentifier: uniPortName,
855 Name: tp.Name,
856 ProfileType: tp.ProfileType,
857 Version: tp.Version,
858 NumGemPorts: tp.NumGemPorts,
859 InstanceCtrl: tp.InstanceCtrl,
860 EponAttribute: tp.EponAttribute,
861 AllocID: tcontIDs[0],
862 UpstreamQueueAttributeList: usQueueAttributeList,
863 DownstreamQueueAttributeList: dsQueueAttributeList}
864}
865
Girish Gowdra54934262019-11-13 14:19:55 +0530866// getSingleInstanceTp returns another TpInstance for an ONU on a different
867// uni port for the same TP ID, if it finds one, else nil.
npujarec5762e2020-01-01 14:08:48 +0530868func (t *TechProfileMgr) getSingleInstanceTp(ctx context.Context, tpPath string) (*TechProfile, error) {
Girish Gowdra54934262019-11-13 14:19:55 +0530869 var tpInst TechProfile
870
871 // For example:
872 // tpPath like "service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}/uni-{1}"
873 // is broken into ["service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}" ""]
874 uniPathSlice := regexp.MustCompile(`/uni-{[0-9]+}$`).Split(tpPath, 2)
npujarec5762e2020-01-01 14:08:48 +0530875 kvPairs, _ := t.config.KVBackend.List(ctx, uniPathSlice[0])
Girish Gowdra54934262019-11-13 14:19:55 +0530876
877 // Find a valid TP Instance among all the UNIs of that ONU for the given TP ID
878 for keyPath, kvPair := range kvPairs {
879 if value, err := kvstore.ToByte(kvPair.Value); err == nil {
880 if err = json.Unmarshal(value, &tpInst); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881 logger.Errorw(ctx, "error-unmarshal-kv-pair", log.Fields{"keyPath": keyPath, "value": value})
Girish Gowdra54934262019-11-13 14:19:55 +0530882 return nil, errors.New("error-unmarshal-kv-pair")
883 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000884 logger.Debugw(ctx, "found-valid-tp-instance-on-another-uni", log.Fields{"keyPath": keyPath})
Girish Gowdra54934262019-11-13 14:19:55 +0530885 return &tpInst, nil
886 }
887 }
888 }
889 return nil, nil
890}
891
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700892func (t *TechProfileMgr) getSingleInstanceEponTp(ctx context.Context, tpPath string) (*EponProfile, error) {
893 var tpInst EponProfile
894
895 // For example:
896 // tpPath like "service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}/uni-{1}"
897 // is broken into ["service/voltha/technology_profiles/xgspon/64/pon-{0}/onu-{1}" ""]
898 uniPathSlice := regexp.MustCompile(`/uni-{[0-9]+}$`).Split(tpPath, 2)
899 kvPairs, _ := t.config.KVBackend.List(ctx, uniPathSlice[0])
900
901 // Find a valid TP Instance among all the UNIs of that ONU for the given TP ID
902 for keyPath, kvPair := range kvPairs {
903 if value, err := kvstore.ToByte(kvPair.Value); err == nil {
904 if err = json.Unmarshal(value, &tpInst); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905 logger.Errorw(ctx, "error-unmarshal-kv-pair", log.Fields{"keyPath": keyPath, "value": value})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700906 return nil, errors.New("error-unmarshal-kv-pair")
907 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000908 logger.Debugw(ctx, "found-valid-tp-instance-on-another-uni", log.Fields{"keyPath": keyPath})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700909 return &tpInst, nil
910 }
911 }
912 }
913 return nil, nil
914}
915
Neha Sharma96b7bf22020-06-15 10:37:32 +0000916func (t *TechProfileMgr) getDefaultTechProfile(ctx context.Context) *DefaultTechProfile {
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400917 var usGemPortAttributeList []GemPortAttribute
918 var dsGemPortAttributeList []GemPortAttribute
919
920 for _, pbit := range t.config.DefaultPbits {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000921 logger.Debugw(ctx, "Creating GEM port", log.Fields{"pbit": pbit})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400922 usGemPortAttributeList = append(usGemPortAttributeList,
923 GemPortAttribute{
924 MaxQueueSize: defaultMaxQueueSize,
925 PbitMap: pbit,
926 AesEncryption: defaultAESEncryption,
927 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
928 PriorityQueue: defaultPriorityQueue,
929 Weight: defaultQueueWeight,
930 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
931 DiscardConfig: DiscardConfig{
932 MinThreshold: defaultMinThreshold,
933 MaxThreshold: defaultMaxThreshold,
934 MaxProbability: defaultMaxProbability}})
935 dsGemPortAttributeList = append(dsGemPortAttributeList,
936 GemPortAttribute{
937 MaxQueueSize: defaultMaxQueueSize,
938 PbitMap: pbit,
939 AesEncryption: defaultAESEncryption,
940 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
941 PriorityQueue: defaultPriorityQueue,
942 Weight: defaultQueueWeight,
943 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
944 DiscardConfig: DiscardConfig{
945 MinThreshold: defaultMinThreshold,
946 MaxThreshold: defaultMaxThreshold,
Scott Bakeree7c0a02020-01-07 11:12:26 -0800947 MaxProbability: defaultMaxProbability},
948 IsMulticast: defaultIsMulticast,
949 DControlList: defaultAccessControlList,
950 SControlList: defaultAccessControlList,
951 McastGemID: defaultMcastGemID})
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400952 }
953 return &DefaultTechProfile{
954 Name: t.config.DefaultTPName,
955 ProfileType: t.resourceMgr.GetTechnology(),
956 Version: t.config.TPVersion,
957 NumGemPorts: uint32(len(usGemPortAttributeList)),
958 InstanceCtrl: InstanceControl{
959 Onu: defaultOnuInstance,
960 Uni: defaultUniInstance,
961 MaxGemPayloadSize: defaultGemPayloadSize},
962 UsScheduler: Scheduler{
963 Direction: Direction_name[Direction_UPSTREAM],
kdarapub26b4502019-10-05 03:02:33 +0530964 AdditionalBw: AdditionalBW_name[defaultAdditionalBw],
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400965 Priority: defaultPriority,
966 Weight: defaultWeight,
967 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
968 DsScheduler: Scheduler{
969 Direction: Direction_name[Direction_DOWNSTREAM],
kdarapub26b4502019-10-05 03:02:33 +0530970 AdditionalBw: AdditionalBW_name[defaultAdditionalBw],
Matt Jeanneretcab955f2019-04-10 15:45:57 -0400971 Priority: defaultPriority,
972 Weight: defaultWeight,
973 QSchedPolicy: SchedulingPolicy_name[defaultQueueSchedPolicy]},
974 UpstreamGemPortAttributeList: usGemPortAttributeList,
975 DownstreamGemPortAttributeList: dsGemPortAttributeList}
976}
977
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700978// getDefaultTechProfile function for EPON
Girish Kumar935f7af2020-08-18 11:59:42 +0000979func (t *TechProfileMgr) getDefaultEponProfile(ctx context.Context) *DefaultEponProfile {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700980
981 var usQueueAttributeList []UpstreamQueueAttribute
982 var dsQueueAttributeList []DownstreamQueueAttribute
983
984 for _, pbit := range t.config.DefaultPbits {
Girish Kumar935f7af2020-08-18 11:59:42 +0000985 logger.Debugw(ctx, "Creating Queue", log.Fields{"pbit": pbit})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700986 usQueueAttributeList = append(usQueueAttributeList,
987 UpstreamQueueAttribute{
988 MaxQueueSize: defaultMaxQueueSize,
989 PbitMap: pbit,
990 AesEncryption: defaultAESEncryption,
991 TrafficType: defaultTrafficType,
992 UnsolicitedGrantSize: defaultUnsolicitedGrantSize,
993 NominalInterval: defaultNominalInterval,
994 ToleratedPollJitter: defaultToleratedPollJitter,
995 RequestTransmissionPolicy: defaultRequestTransmissionPolicy,
996 NumQueueSet: defaultNumQueueSet,
997 QThresholds: QThresholds{
998 QThreshold1: defaultQThreshold1,
999 QThreshold2: defaultQThreshold2,
1000 QThreshold3: defaultQThreshold3,
1001 QThreshold4: defaultQThreshold4,
1002 QThreshold5: defaultQThreshold5,
1003 QThreshold6: defaultQThreshold6,
1004 QThreshold7: defaultQThreshold7},
1005 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
1006 PriorityQueue: defaultPriorityQueue,
1007 Weight: defaultQueueWeight,
1008 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
1009 DiscardConfig: DiscardConfig{
1010 MinThreshold: defaultMinThreshold,
1011 MaxThreshold: defaultMaxThreshold,
1012 MaxProbability: defaultMaxProbability}})
1013 dsQueueAttributeList = append(dsQueueAttributeList,
1014 DownstreamQueueAttribute{
1015 MaxQueueSize: defaultMaxQueueSize,
1016 PbitMap: pbit,
1017 AesEncryption: defaultAESEncryption,
1018 SchedulingPolicy: SchedulingPolicy_name[defaultSchedulePolicy],
1019 PriorityQueue: defaultPriorityQueue,
1020 Weight: defaultQueueWeight,
1021 DiscardPolicy: DiscardPolicy_name[defaultdropPolicy],
1022 DiscardConfig: DiscardConfig{
1023 MinThreshold: defaultMinThreshold,
1024 MaxThreshold: defaultMaxThreshold,
1025 MaxProbability: defaultMaxProbability}})
1026 }
1027 return &DefaultEponProfile{
1028 Name: t.config.DefaultTPName,
1029 ProfileType: t.resourceMgr.GetTechnology(),
1030 Version: t.config.TPVersion,
1031 NumGemPorts: uint32(len(usQueueAttributeList)),
1032 InstanceCtrl: InstanceControl{
1033 Onu: defaultOnuInstance,
1034 Uni: defaultUniInstance,
1035 MaxGemPayloadSize: defaultGemPayloadSize},
1036 EponAttribute: EponAttribute{
1037 PackageType: defaultPakageType},
1038 UpstreamQueueAttributeList: usQueueAttributeList,
1039 DownstreamQueueAttributeList: dsQueueAttributeList}
1040}
1041
Neha Sharma96b7bf22020-06-15 10:37:32 +00001042func (t *TechProfileMgr) GetprotoBufParamValue(ctx context.Context, paramType string, paramKey string) int32 {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001043 var result int32 = -1
1044
1045 if paramType == "direction" {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001046 for key, val := range tp_pb.Direction_value {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001047 if key == paramKey {
1048 result = val
1049 }
1050 }
1051 } else if paramType == "discard_policy" {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001052 for key, val := range tp_pb.DiscardPolicy_value {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001053 if key == paramKey {
1054 result = val
1055 }
1056 }
1057 } else if paramType == "sched_policy" {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001058 for key, val := range tp_pb.SchedulingPolicy_value {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001059 if key == paramKey {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001060 logger.Debugw(ctx, "Got value in proto", log.Fields{"key": key, "value": val})
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001061 result = val
1062 }
1063 }
1064 } else if paramType == "additional_bw" {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001065 for key, val := range tp_pb.AdditionalBW_value {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001066 if key == paramKey {
1067 result = val
1068 }
1069 }
1070 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001071 logger.Error(ctx, "Could not find proto parameter", log.Fields{"paramType": paramType, "key": paramKey})
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001072 return -1
1073 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 logger.Debugw(ctx, "Got value in proto", log.Fields{"key": paramKey, "value": result})
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001075 return result
1076}
1077
Neha Sharma96b7bf22020-06-15 10:37:32 +00001078func (t *TechProfileMgr) GetUsScheduler(ctx context.Context, tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error) {
1079 dir := tp_pb.Direction(t.GetprotoBufParamValue(ctx, "direction", tpInstance.UsScheduler.Direction))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001080 if dir == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001081 logger.Errorf(ctx, "Error in getting proto id for direction %s for upstream scheduler", tpInstance.UsScheduler.Direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001082 return nil, fmt.Errorf("unable to get proto id for direction %s for upstream scheduler", tpInstance.UsScheduler.Direction)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001083 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001084
Neha Sharma96b7bf22020-06-15 10:37:32 +00001085 bw := tp_pb.AdditionalBW(t.GetprotoBufParamValue(ctx, "additional_bw", tpInstance.UsScheduler.AdditionalBw))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001086 if bw == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001087 logger.Errorf(ctx, "Error in getting proto id for bandwidth %s for upstream scheduler", tpInstance.UsScheduler.AdditionalBw)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001088 return nil, fmt.Errorf("unable to get proto id for bandwidth %s for upstream scheduler", tpInstance.UsScheduler.AdditionalBw)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001089 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001090
Neha Sharma96b7bf22020-06-15 10:37:32 +00001091 policy := tp_pb.SchedulingPolicy(t.GetprotoBufParamValue(ctx, "sched_policy", tpInstance.UsScheduler.QSchedPolicy))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001092 if policy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001093 logger.Errorf(ctx, "Error in getting proto id for scheduling policy %s for upstream scheduler", tpInstance.UsScheduler.QSchedPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001094 return nil, fmt.Errorf("unable to get proto id for scheduling policy %s for upstream scheduler", tpInstance.UsScheduler.QSchedPolicy)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001095 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001096
Manikkaraj kb1d51442019-07-23 10:41:02 -04001097 return &tp_pb.SchedulerConfig{
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001098 Direction: dir,
1099 AdditionalBw: bw,
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001100 Priority: tpInstance.UsScheduler.Priority,
1101 Weight: tpInstance.UsScheduler.Weight,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001102 SchedPolicy: policy}, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001103}
1104
Neha Sharma96b7bf22020-06-15 10:37:32 +00001105func (t *TechProfileMgr) GetDsScheduler(ctx context.Context, tpInstance *TechProfile) (*tp_pb.SchedulerConfig, error) {
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001106
Neha Sharma96b7bf22020-06-15 10:37:32 +00001107 dir := tp_pb.Direction(t.GetprotoBufParamValue(ctx, "direction", tpInstance.DsScheduler.Direction))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001108 if dir == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001109 logger.Errorf(ctx, "Error in getting proto id for direction %s for downstream scheduler", tpInstance.DsScheduler.Direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001110 return nil, fmt.Errorf("unable to get proto id for direction %s for downstream scheduler", tpInstance.DsScheduler.Direction)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001111 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001112
Neha Sharma96b7bf22020-06-15 10:37:32 +00001113 bw := tp_pb.AdditionalBW(t.GetprotoBufParamValue(ctx, "additional_bw", tpInstance.DsScheduler.AdditionalBw))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001114 if bw == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001115 logger.Errorf(ctx, "Error in getting proto id for bandwidth %s for downstream scheduler", tpInstance.DsScheduler.AdditionalBw)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001116 return nil, fmt.Errorf("unable to get proto id for bandwidth %s for downstream scheduler", tpInstance.DsScheduler.AdditionalBw)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001117 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001118
Neha Sharma96b7bf22020-06-15 10:37:32 +00001119 policy := tp_pb.SchedulingPolicy(t.GetprotoBufParamValue(ctx, "sched_policy", tpInstance.DsScheduler.QSchedPolicy))
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001120 if policy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001121 logger.Errorf(ctx, "Error in getting proto id for scheduling policy %s for downstream scheduler", tpInstance.DsScheduler.QSchedPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001122 return nil, fmt.Errorf("unable to get proto id for scheduling policy %s for downstream scheduler", tpInstance.DsScheduler.QSchedPolicy)
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001123 }
1124
Manikkaraj kb1d51442019-07-23 10:41:02 -04001125 return &tp_pb.SchedulerConfig{
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001126 Direction: dir,
1127 AdditionalBw: bw,
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001128 Priority: tpInstance.DsScheduler.Priority,
1129 Weight: tpInstance.DsScheduler.Weight,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001130 SchedPolicy: policy}, nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001131}
1132
Manikkaraj kb1d51442019-07-23 10:41:02 -04001133func (t *TechProfileMgr) GetTrafficScheduler(tpInstance *TechProfile, SchedCfg *tp_pb.SchedulerConfig,
1134 ShapingCfg *tp_pb.TrafficShapingInfo) *tp_pb.TrafficScheduler {
1135
1136 tSched := &tp_pb.TrafficScheduler{
1137 Direction: SchedCfg.Direction,
1138 AllocId: tpInstance.UsScheduler.AllocID,
1139 TrafficShapingInfo: ShapingCfg,
1140 Scheduler: SchedCfg}
1141
1142 return tSched
1143}
1144
Neha Sharma96b7bf22020-06-15 10:37:32 +00001145func (tpm *TechProfileMgr) GetTrafficQueues(ctx context.Context, tp *TechProfile, Dir tp_pb.Direction) ([]*tp_pb.TrafficQueue, error) {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001146
1147 var encryp bool
1148 if Dir == tp_pb.Direction_UPSTREAM {
1149 // upstream GEM ports
1150 NumGemPorts := len(tp.UpstreamGemPortAttributeList)
1151 GemPorts := make([]*tp_pb.TrafficQueue, 0)
1152 for Count := 0; Count < NumGemPorts; Count++ {
1153 if tp.UpstreamGemPortAttributeList[Count].AesEncryption == "True" {
1154 encryp = true
1155 } else {
1156 encryp = false
1157 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001158
Neha Sharma96b7bf22020-06-15 10:37:32 +00001159 schedPolicy := tpm.GetprotoBufParamValue(ctx, "sched_policy", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001160 if schedPolicy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001161 logger.Errorf(ctx, "Error in getting Proto Id for scheduling policy %s for Upstream Gem Port %d", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy, Count)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001162 return nil, fmt.Errorf("upstream gem port traffic queue creation failed due to unrecognized scheduling policy %s", tp.UpstreamGemPortAttributeList[Count].SchedulingPolicy)
1163 }
1164
Neha Sharma96b7bf22020-06-15 10:37:32 +00001165 discardPolicy := tpm.GetprotoBufParamValue(ctx, "discard_policy", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001166 if discardPolicy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001167 logger.Errorf(ctx, "Error in getting Proto Id for discard policy %s for Upstream Gem Port %d", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy, Count)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001168 return nil, fmt.Errorf("upstream gem port traffic queue creation failed due to unrecognized discard policy %s", tp.UpstreamGemPortAttributeList[Count].DiscardPolicy)
1169 }
1170
Manikkaraj kb1d51442019-07-23 10:41:02 -04001171 GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
Neha Sharma96b7bf22020-06-15 10:37:32 +00001172 Direction: tp_pb.Direction(tpm.GetprotoBufParamValue(ctx, "direction", tp.UsScheduler.Direction)),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001173 GemportId: tp.UpstreamGemPortAttributeList[Count].GemportID,
1174 PbitMap: tp.UpstreamGemPortAttributeList[Count].PbitMap,
1175 AesEncryption: encryp,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001176 SchedPolicy: tp_pb.SchedulingPolicy(schedPolicy),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001177 Priority: tp.UpstreamGemPortAttributeList[Count].PriorityQueue,
1178 Weight: tp.UpstreamGemPortAttributeList[Count].Weight,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001179 DiscardPolicy: tp_pb.DiscardPolicy(discardPolicy),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001180 })
1181 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 logger.Debugw(ctx, "Upstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
Girish Kumar8f73fe02019-12-09 13:19:37 +00001183 return GemPorts, nil
Manikkaraj kb1d51442019-07-23 10:41:02 -04001184 } else if Dir == tp_pb.Direction_DOWNSTREAM {
1185 //downstream GEM ports
1186 NumGemPorts := len(tp.DownstreamGemPortAttributeList)
1187 GemPorts := make([]*tp_pb.TrafficQueue, 0)
1188 for Count := 0; Count < NumGemPorts; Count++ {
Scott Bakeree7c0a02020-01-07 11:12:26 -08001189 if isMulticastGem(tp.DownstreamGemPortAttributeList[Count].IsMulticast) {
1190 //do not take multicast GEM ports. They are handled separately.
1191 continue
1192 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001193 if tp.DownstreamGemPortAttributeList[Count].AesEncryption == "True" {
1194 encryp = true
1195 } else {
1196 encryp = false
1197 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001198
Neha Sharma96b7bf22020-06-15 10:37:32 +00001199 schedPolicy := tpm.GetprotoBufParamValue(ctx, "sched_policy", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001200 if schedPolicy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001201 logger.Errorf(ctx, "Error in getting Proto Id for scheduling policy %s for Downstream Gem Port %d", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy, Count)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001202 return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unrecognized scheduling policy %s", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)
1203 }
1204
Neha Sharma96b7bf22020-06-15 10:37:32 +00001205 discardPolicy := tpm.GetprotoBufParamValue(ctx, "discard_policy", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001206 if discardPolicy == -1 {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001207 logger.Errorf(ctx, "Error in getting Proto Id for discard policy %s for Downstream Gem Port %d", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy, Count)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001208 return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unrecognized discard policy %s", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)
1209 }
1210
Manikkaraj kb1d51442019-07-23 10:41:02 -04001211 GemPorts = append(GemPorts, &tp_pb.TrafficQueue{
Neha Sharma96b7bf22020-06-15 10:37:32 +00001212 Direction: tp_pb.Direction(tpm.GetprotoBufParamValue(ctx, "direction", tp.DsScheduler.Direction)),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001213 GemportId: tp.DownstreamGemPortAttributeList[Count].GemportID,
1214 PbitMap: tp.DownstreamGemPortAttributeList[Count].PbitMap,
1215 AesEncryption: encryp,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001216 SchedPolicy: tp_pb.SchedulingPolicy(schedPolicy),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001217 Priority: tp.DownstreamGemPortAttributeList[Count].PriorityQueue,
1218 Weight: tp.DownstreamGemPortAttributeList[Count].Weight,
Girish Kumar8f73fe02019-12-09 13:19:37 +00001219 DiscardPolicy: tp_pb.DiscardPolicy(discardPolicy),
Manikkaraj kb1d51442019-07-23 10:41:02 -04001220 })
1221 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001222 logger.Debugw(ctx, "Downstream Traffic queue list ", log.Fields{"queuelist": GemPorts})
Girish Kumar8f73fe02019-12-09 13:19:37 +00001223 return GemPorts, nil
Manikkaraj kb1d51442019-07-23 10:41:02 -04001224 }
Girish Kumar8f73fe02019-12-09 13:19:37 +00001225
Neha Sharma96b7bf22020-06-15 10:37:32 +00001226 logger.Errorf(ctx, "Unsupported direction %s used for generating Traffic Queue list", Dir)
Girish Kumar8f73fe02019-12-09 13:19:37 +00001227 return nil, fmt.Errorf("downstream gem port traffic queue creation failed due to unsupported direction %s", Dir)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001228}
1229
Scott Bakeree7c0a02020-01-07 11:12:26 -08001230//isMulticastGem returns true if isMulticast attribute value of a GEM port is true; false otherwise
1231func isMulticastGem(isMulticastAttrValue string) bool {
1232 return isMulticastAttrValue != "" &&
1233 (isMulticastAttrValue == "True" || isMulticastAttrValue == "true" || isMulticastAttrValue == "TRUE")
1234}
1235
Neha Sharma96b7bf22020-06-15 10:37:32 +00001236func (tpm *TechProfileMgr) GetMulticastTrafficQueues(ctx context.Context, tp *TechProfile) []*tp_pb.TrafficQueue {
Scott Bakeree7c0a02020-01-07 11:12:26 -08001237 var encryp bool
1238 NumGemPorts := len(tp.DownstreamGemPortAttributeList)
1239 mcastTrafficQueues := make([]*tp_pb.TrafficQueue, 0)
1240 for Count := 0; Count < NumGemPorts; Count++ {
1241 if !isMulticastGem(tp.DownstreamGemPortAttributeList[Count].IsMulticast) {
1242 continue
1243 }
1244 if tp.DownstreamGemPortAttributeList[Count].AesEncryption == "True" {
1245 encryp = true
1246 } else {
1247 encryp = false
1248 }
1249 mcastTrafficQueues = append(mcastTrafficQueues, &tp_pb.TrafficQueue{
Neha Sharma96b7bf22020-06-15 10:37:32 +00001250 Direction: tp_pb.Direction(tpm.GetprotoBufParamValue(ctx, "direction", tp.DsScheduler.Direction)),
Scott Bakeree7c0a02020-01-07 11:12:26 -08001251 GemportId: tp.DownstreamGemPortAttributeList[Count].McastGemID,
1252 PbitMap: tp.DownstreamGemPortAttributeList[Count].PbitMap,
1253 AesEncryption: encryp,
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 SchedPolicy: tp_pb.SchedulingPolicy(tpm.GetprotoBufParamValue(ctx, "sched_policy", tp.DownstreamGemPortAttributeList[Count].SchedulingPolicy)),
Scott Bakeree7c0a02020-01-07 11:12:26 -08001255 Priority: tp.DownstreamGemPortAttributeList[Count].PriorityQueue,
1256 Weight: tp.DownstreamGemPortAttributeList[Count].Weight,
Neha Sharma96b7bf22020-06-15 10:37:32 +00001257 DiscardPolicy: tp_pb.DiscardPolicy(tpm.GetprotoBufParamValue(ctx, "discard_policy", tp.DownstreamGemPortAttributeList[Count].DiscardPolicy)),
Scott Bakeree7c0a02020-01-07 11:12:26 -08001258 })
1259 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001260 logger.Debugw(ctx, "Downstream Multicast Traffic queue list ", log.Fields{"queuelist": mcastTrafficQueues})
Scott Bakeree7c0a02020-01-07 11:12:26 -08001261 return mcastTrafficQueues
1262}
1263
Neha Sharma96b7bf22020-06-15 10:37:32 +00001264func (tpm *TechProfileMgr) GetUsTrafficScheduler(ctx context.Context, tp *TechProfile) *tp_pb.TrafficScheduler {
1265 UsScheduler, _ := tpm.GetUsScheduler(ctx, tp)
Manikkaraj kb1d51442019-07-23 10:41:02 -04001266
1267 return &tp_pb.TrafficScheduler{Direction: UsScheduler.Direction,
1268 AllocId: tp.UsScheduler.AllocID,
1269 Scheduler: UsScheduler}
1270}
1271
Gamze Abaka7650be62021-02-26 10:50:36 +00001272func (t *TechProfileMgr) GetGemportForPbit(ctx context.Context, tp interface{}, dir tp_pb.Direction, pbit uint32) interface{} {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001273 /*
Gamze Abaka7650be62021-02-26 10:50:36 +00001274 Function to get the Gemport mapped to a pbit.
Manikkaraj kb1d51442019-07-23 10:41:02 -04001275 */
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001276 switch tp := tp.(type) {
1277 case *TechProfile:
1278 if dir == tp_pb.Direction_UPSTREAM {
1279 // upstream GEM ports
1280 numGemPorts := len(tp.UpstreamGemPortAttributeList)
1281 for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
1282 lenOfPbitMap := len(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap)
1283 for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
1284 // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
1285 // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
1286 if p, err := strconv.Atoi(string(tp.UpstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
1287 if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
Neha Sharma96b7bf22020-06-15 10:37:32 +00001288 logger.Debugw(ctx, "Found-US-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.UpstreamGemPortAttributeList[gemCnt].GemportID})
Gamze Abaka7650be62021-02-26 10:50:36 +00001289 return tp.UpstreamGemPortAttributeList[gemCnt]
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001290 }
1291 }
1292 }
1293 }
1294 } else if dir == tp_pb.Direction_DOWNSTREAM {
1295 //downstream GEM ports
1296 numGemPorts := len(tp.DownstreamGemPortAttributeList)
1297 for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
1298 lenOfPbitMap := len(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap)
1299 for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
1300 // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
1301 // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
1302 if p, err := strconv.Atoi(string(tp.DownstreamGemPortAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
1303 if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
Neha Sharma96b7bf22020-06-15 10:37:32 +00001304 logger.Debugw(ctx, "Found-DS-GEMport-for-Pcp", log.Fields{"pbit": pbit, "GEMport": tp.DownstreamGemPortAttributeList[gemCnt].GemportID})
Gamze Abaka7650be62021-02-26 10:50:36 +00001305 return tp.DownstreamGemPortAttributeList[gemCnt]
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001306 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001307 }
1308 }
1309 }
1310 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001311 logger.Errorw(ctx, "No-GemportId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001312 case *EponProfile:
1313 if dir == tp_pb.Direction_UPSTREAM {
1314 // upstream GEM ports
1315 numGemPorts := len(tp.UpstreamQueueAttributeList)
1316 for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
1317 lenOfPbitMap := len(tp.UpstreamQueueAttributeList[gemCnt].PbitMap)
1318 for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
1319 // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
1320 // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
1321 if p, err := strconv.Atoi(string(tp.UpstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
1322 if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
Neha Sharma96b7bf22020-06-15 10:37:32 +00001323 logger.Debugw(ctx, "Found-US-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.UpstreamQueueAttributeList[gemCnt].GemportID})
Gamze Abaka7650be62021-02-26 10:50:36 +00001324 return tp.UpstreamQueueAttributeList[gemCnt]
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001325 }
1326 }
1327 }
1328 }
1329 } else if dir == tp_pb.Direction_DOWNSTREAM {
1330 //downstream GEM ports
1331 numGemPorts := len(tp.DownstreamQueueAttributeList)
1332 for gemCnt := 0; gemCnt < numGemPorts; gemCnt++ {
1333 lenOfPbitMap := len(tp.DownstreamQueueAttributeList[gemCnt].PbitMap)
1334 for pbitMapIdx := 2; pbitMapIdx < lenOfPbitMap; pbitMapIdx++ {
1335 // Given a sample pbit map string "0b00000001", lenOfPbitMap is 10
1336 // "lenOfPbitMap - pbitMapIdx + 1" will give pbit-i th value from LSB position in the pbit map string
1337 if p, err := strconv.Atoi(string(tp.DownstreamQueueAttributeList[gemCnt].PbitMap[lenOfPbitMap-pbitMapIdx+1])); err == nil {
1338 if uint32(pbitMapIdx-2) == pbit && p == 1 { // Check this p-bit is set
Neha Sharma96b7bf22020-06-15 10:37:32 +00001339 logger.Debugw(ctx, "Found-DS-Queue-for-Pcp", log.Fields{"pbit": pbit, "Queue": tp.DownstreamQueueAttributeList[gemCnt].GemportID})
Gamze Abaka7650be62021-02-26 10:50:36 +00001340 return tp.DownstreamQueueAttributeList[gemCnt]
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001341 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001342 }
1343 }
1344 }
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001345 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001346 logger.Errorw(ctx, "No-QueueId-Found-For-Pcp", log.Fields{"pcpVlan": pbit})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001347 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +00001348 logger.Errorw(ctx, "unknown-tech", log.Fields{"tp": tp})
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001349 }
Gamze Abaka7650be62021-02-26 10:50:36 +00001350 return nil
Matt Jeanneretcab955f2019-04-10 15:45:57 -04001351}
Girish Gowdra54934262019-11-13 14:19:55 +05301352
1353// FindAllTpInstances returns all TechProfile instances for a given TechProfile table-id, pon interface ID and onu ID.
Gamze Abakacb0e6772021-06-10 08:32:12 +00001354func (t *TechProfileMgr) FindAllTpInstances(ctx context.Context, oltDeviceID string, tpID uint32, ponIntf uint32, onuID uint32) interface{} {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001355 var tpTech TechProfile
1356 var tpEpon EponProfile
1357
Gamze Abakacb0e6772021-06-10 08:32:12 +00001358 onuTpInstancePath := fmt.Sprintf("%s/%d/olt-{%s}/pon-{%d}/onu-{%d}", t.resourceMgr.GetTechnology(), tpID, oltDeviceID, ponIntf, onuID)
Girish Gowdra54934262019-11-13 14:19:55 +05301359
npujarec5762e2020-01-01 14:08:48 +05301360 if kvPairs, _ := t.config.KVBackend.List(ctx, onuTpInstancePath); kvPairs != nil {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001361 tech := t.resourceMgr.GetTechnology()
1362 tpInstancesTech := make([]TechProfile, 0, len(kvPairs))
1363 tpInstancesEpon := make([]EponProfile, 0, len(kvPairs))
1364
Girish Gowdra54934262019-11-13 14:19:55 +05301365 for kvPath, kvPair := range kvPairs {
1366 if value, err := kvstore.ToByte(kvPair.Value); err == nil {
Andrea Campanella974d7452020-06-26 19:32:30 +02001367 if tech == xgspon || tech == gpon {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001368 if err = json.Unmarshal(value, &tpTech); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001369 logger.Errorw(ctx, "error-unmarshal-kv-pair", log.Fields{"kvPath": kvPath, "value": value})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001370 continue
1371 } else {
1372 tpInstancesTech = append(tpInstancesTech, tpTech)
1373 }
1374 } else if tech == epon {
1375 if err = json.Unmarshal(value, &tpEpon); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001376 logger.Errorw(ctx, "error-unmarshal-kv-pair", log.Fields{"kvPath": kvPath, "value": value})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001377 continue
1378 } else {
1379 tpInstancesEpon = append(tpInstancesEpon, tpEpon)
1380 }
Girish Gowdra54934262019-11-13 14:19:55 +05301381 }
1382 }
1383 }
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001384
1385 switch tech {
Andrea Campanella974d7452020-06-26 19:32:30 +02001386 case xgspon, gpon:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001387 return tpInstancesTech
1388 case epon:
1389 return tpInstancesEpon
1390 default:
Girish Kumar935f7af2020-08-18 11:59:42 +00001391 logger.Errorw(ctx, "unknown-technology", log.Fields{"tech": tech})
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001392 return nil
1393 }
Girish Gowdra54934262019-11-13 14:19:55 +05301394 }
1395 return nil
1396}
Matteo Scandolo84585372021-03-18 14:21:22 -07001397
1398func (t *TechProfileMgr) GetResourceID(ctx context.Context, IntfID uint32, ResourceType string, NumIDs uint32) ([]uint32, error) {
1399 logger.Debugw(ctx, "getting-resource-id", log.Fields{
1400 "intf-id": IntfID,
1401 "resource-type": ResourceType,
1402 "num": NumIDs,
1403 })
1404 var err error
1405 var ids []uint32
1406 switch ResourceType {
1407 case t.resourceMgr.GetResourceTypeAllocID():
1408 t.AllocIDMgmtLock.Lock()
1409 ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
1410 t.AllocIDMgmtLock.Unlock()
1411 case t.resourceMgr.GetResourceTypeGemPortID():
1412 t.GemPortIDMgmtLock.Lock()
1413 ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
1414 t.GemPortIDMgmtLock.Unlock()
1415 case t.resourceMgr.GetResourceTypeOnuID():
1416 t.OnuIDMgmtLock.Lock()
1417 ids, err = t.resourceMgr.GetResourceID(ctx, IntfID, ResourceType, NumIDs)
1418 t.OnuIDMgmtLock.Unlock()
1419 default:
1420 return nil, fmt.Errorf("ResourceType %s not supported", ResourceType)
1421 }
1422 if err != nil {
1423 return nil, err
1424 }
1425 return ids, nil
1426}
1427
1428func (t *TechProfileMgr) FreeResourceID(ctx context.Context, IntfID uint32, ResourceType string, ReleaseContent []uint32) error {
1429 logger.Debugw(ctx, "freeing-resource-id", log.Fields{
1430 "intf-id": IntfID,
1431 "resource-type": ResourceType,
1432 "release-content": ReleaseContent,
1433 })
1434 var err error
1435 switch ResourceType {
1436 case t.resourceMgr.GetResourceTypeAllocID():
1437 t.AllocIDMgmtLock.Lock()
1438 err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
1439 t.AllocIDMgmtLock.Unlock()
1440 case t.resourceMgr.GetResourceTypeGemPortID():
1441 t.GemPortIDMgmtLock.Lock()
1442 err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
1443 t.GemPortIDMgmtLock.Unlock()
1444 case t.resourceMgr.GetResourceTypeOnuID():
1445 t.OnuIDMgmtLock.Lock()
1446 err = t.resourceMgr.FreeResourceID(ctx, IntfID, ResourceType, ReleaseContent)
1447 t.OnuIDMgmtLock.Unlock()
1448 default:
1449 return fmt.Errorf("ResourceType %s not supported", ResourceType)
1450 }
1451 if err != nil {
1452 return err
1453 }
1454 return nil
1455}