blob: 8cbc7eaba2527a58d730a80cc660d9dc224e7eef [file] [log] [blame]
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +05301/*
2 * Copyright 2018-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 core
18
19import (
20 "errors"
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030021 "math/rand"
Girish Gowdraaeceb842020-08-21 12:10:39 -070022 "time"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053023
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +053024 "github.com/opencord/openolt-scale-tester/config"
Girish Gowdra390f12f2021-07-01 15:53:49 -070025 "github.com/opencord/voltha-lib-go/v7/pkg/log"
26 oop "github.com/opencord/voltha-protos/v5/go/openolt"
27 tp_pb "github.com/opencord/voltha-protos/v5/go/tech_profile"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053028 "golang.org/x/net/context"
29 "google.golang.org/grpc/codes"
30 "google.golang.org/grpc/status"
31)
32
33const (
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053034 DhcpIPProto = 17
Girish Gowdraef1b7c42020-01-23 16:27:48 +053035
36 //Constants utilised while forming HSIA Flow
37 HsiaFlow = "HSIA_FLOW"
38
39 //Constants utilised while forming DHCP IPV4 Flow
40 DhcpFlowIPV4 = "DHCP_FLOW_IPV4"
41 IPv4EthType = 0x800 //2048
42 DhcpSrcPortIPV4 = 68
43 DhcpDstPortIPV4 = 67
44
45 //Constants utilised while forming DHCP IPV6 Flow
46 DhcpFlowIPV6 = "DHCP_FLOW_IPV6"
47 IPv6EthType = 0x86dd //34525
48 DhcpSrcPortIPV6 = 547
49 DhcpDstPortIPV6 = 546
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053050
51 //Constants utilised while forming EAPOL Flow
52 EapolFlow = "EAPOL_FLOW"
53 EapEthType = 0x888e //34958
54
55 //Direction constant
56 Upstream = "upstream"
57 Downstream = "downstream"
58
59 //PacketTagType constant
60 PacketTagType = "pkt_tag_type"
61 Untagged = "untagged"
62 SingleTag = "single_tag"
63 DoubleTag = "double_tag"
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030064
65 VoipFlow = "VOIP_FLOW"
66
67 VodFlow = "VOD_FLOW"
68
69 MgmtFlow = "MGMT_FLOW"
70
71 IgmpProto = 2
72 IgmpFlow = "IGMP_FLOW"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053073)
74
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030075const (
76 MacSize = 6
77 MacMin = 0x0
78 MacMax = 0xFF
79)
80
81type GroupData struct {
82 Subs Subscriber `json:"subscriber"`
83 GroupID uint32 `json:"groupID"`
84 Weight uint32 `json:"weight"`
85 Priority uint32 `json:"priority"`
86 OnuID uint32 `json:"onuID"`
87 UniID uint32 `json:"uniID"`
88 AllocID uint32 `json:"allocId"`
89 GemPortID uint32 `json:"gemPortIds"`
90 SchedPolicy tp_pb.SchedulingPolicy `json:"schedPolicy"`
91 AddGroup bool `json:"addGroup"`
92 AddFlow bool `json:"addFlow"`
93 AddSched bool `json:"addSched"`
94 AddQueue bool `json:"addQueue"`
95 AddMember bool `json:"addMember"`
96}
97
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053098func getTrafficSched(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficScheduler {
99 var SchedCfg *tp_pb.SchedulerConfig
100
101 if direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra390f12f2021-07-01 15:53:49 -0700102 SchedCfg = subs.RsrMgr.TechprofileRef.
103 GetDsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530104 } else {
Girish Gowdra390f12f2021-07-01 15:53:49 -0700105 SchedCfg = subs.RsrMgr.TechprofileRef.
106 GetUsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530107 }
108
Girish Gowdra390f12f2021-07-01 15:53:49 -0700109 if SchedCfg == nil {
110 logger.Errorw(nil, "Failed to create traffic schedulers", log.Fields{"direction": direction})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300111 return nil
112 }
113
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530114 // hard-code for now
115 cir := 16000
116 cbs := 5000
117 eir := 16000
118 ebs := 5000
119 pir := cir + eir
120 pbs := cbs + ebs
121
122 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
123
Girish Gowdra390f12f2021-07-01 15:53:49 -0700124 TrafficSched := []*tp_pb.TrafficScheduler{subs.RsrMgr.TechprofileRef.
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530125 GetTrafficScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]], SchedCfg, TrafficShaping)}
126
127 return TrafficSched
128}
129
130func getTrafficQueues(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficQueue {
131
Girish Gowdra390f12f2021-07-01 15:53:49 -0700132 trafficQueues, err := subs.RsrMgr.TechprofileRef.
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700133 GetTrafficQueues(nil, subs.TpInstance[subs.TestConfig.TpIDList[0]], direction)
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530134
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300135 if err == nil {
136 return trafficQueues
137 }
138
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700139 logger.Errorw(nil, "Failed to create traffic queues", log.Fields{"direction": direction, "error": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300140 return nil
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530141}
142
143func FormatClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
144 var flowClassifier oop.Classifier
145 var actionCmd oop.ActionCmd
146 var actionInfo oop.Action
147
148 if direction == Upstream {
149 switch flowType {
150 case EapolFlow:
151 flowClassifier.EthType = EapEthType
152 flowClassifier.OVid = subs.Ctag
153 flowClassifier.PktTagType = SingleTag
154 actionCmd.TrapToHost = true
155 actionInfo.Cmd = &actionCmd
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530156 case DhcpFlowIPV4:
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530157 flowClassifier.EthType = IPv4EthType
158 flowClassifier.IpProto = DhcpIPProto
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530159 flowClassifier.SrcPort = DhcpSrcPortIPV4
160 flowClassifier.DstPort = DhcpDstPortIPV4
161 flowClassifier.PktTagType = SingleTag
162 actionCmd.TrapToHost = true
163 actionInfo.Cmd = &actionCmd
164 case DhcpFlowIPV6:
165 flowClassifier.EthType = IPv6EthType
166 flowClassifier.IpProto = DhcpIPProto
167 flowClassifier.SrcPort = DhcpSrcPortIPV6
168 flowClassifier.DstPort = DhcpDstPortIPV6
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530169 flowClassifier.PktTagType = SingleTag
170 actionCmd.TrapToHost = true
171 actionInfo.Cmd = &actionCmd
172 case HsiaFlow:
173 flowClassifier.OVid = subs.Ctag
174 flowClassifier.PktTagType = SingleTag
175 actionCmd.AddOuterTag = true
176 actionInfo.Cmd = &actionCmd
177 actionInfo.OVid = subs.Stag
178 default:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700179 logger.Errorw(nil, "Unsupported flow type", log.Fields{"flowtype": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530180 "direction": direction})
181 }
182 } else if direction == Downstream {
183 switch flowType {
184 case EapolFlow:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700185 logger.Errorw(nil, "Downstream EAP flows are not required instead controller "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530186 "packet outs EAP response directly to onu in downstream", log.Fields{"flowtype": flowType,
187 "direction": direction})
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530188 case DhcpFlowIPV4:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700189 logger.Errorw(nil, "Downstream DHCPIPV4 flows are not required instead we have "+
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530190 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
191 "direction": direction})
192 case DhcpFlowIPV6:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700193 logger.Errorw(nil, "Downstream DHCPIPV6 flows are not required instead we have "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530194 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
195 "direction": direction})
196 case HsiaFlow:
197 flowClassifier.OVid = subs.Stag
198 flowClassifier.IVid = subs.Ctag
199 flowClassifier.PktTagType = DoubleTag
200 actionCmd.RemoveOuterTag = true
201 actionInfo.Cmd = &actionCmd
Girish Gowdra187322d2020-01-20 18:59:21 +0530202 actionInfo.OVid = subs.Stag
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530203 default:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700204 logger.Errorw(nil, "Unsupported flow type", log.Fields{"flowtype": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530205 "direction": direction})
206 }
207 }
208 return flowClassifier, actionInfo
209}
210
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700211func AddFlow(subs *Subscriber, flowType string, direction string, flowID uint64,
212 allocID uint32, gemID uint32, pcp uint32, replicateFlow bool, symmetricFlowID uint64,
213 pbitToGem map[uint32]uint32) error {
214 logger.Infow(nil, "add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530215 "direction": direction, "flowID": flowID})
216 var err error
217
218 flowClassifier, actionInfo := FormatClassfierAction(flowType, direction, subs)
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700219 // Update the o_pbit (if valid) for which this flow has to be classified
220 if pcp != 0xff {
221 flowClassifier.OPbits = pcp
222 }
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530223 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
224 UniId: int32(subs.UniID), FlowId: flowID,
225 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
226 Classifier: &flowClassifier, Action: &actionInfo,
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700227 Priority: 1000, PortNo: subs.UniPortNo, SymmetricFlowId: symmetricFlowID,
228 ReplicateFlow: replicateFlow, PbitToGemport: pbitToGem}
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530229
230 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
231
232 st, _ := status.FromError(err)
233 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700234 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530235 return nil
236 }
237
238 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700239 logger.Errorw(nil, "Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530240 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
241 }
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700242 logger.Debugw(nil, "Flow added to device successfully ", log.Fields{"flow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530243
244 return nil
245}
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530246
247func AddLldpFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700248 var flowID uint64
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530249 var err error
250
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700251 if flowID, err = rsrMgr.GetFlowID(context.Background(), uint32(config.NniIntfID)); err != nil {
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530252 return err
253 }
254
255 flowClassifier := &oop.Classifier{EthType: 35020, PktTagType: "untagged"}
256 actionCmd := &oop.ActionCmd{TrapToHost: true}
257 actionInfo := &oop.Action{Cmd: actionCmd}
258
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700259 flow := oop.Flow{AccessIntfId: -1, OnuId: -1, UniId: -1, FlowId: flowID,
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530260 FlowType: "downstream", AllocId: -1, GemportId: -1,
261 Classifier: flowClassifier, Action: actionInfo,
262 Priority: 1000, PortNo: uint32(config.NniIntfID)}
263
264 _, err = oo.FlowAdd(context.Background(), &flow)
265
266 st, _ := status.FromError(err)
267 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700268 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530269 return nil
270 }
271
272 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700273 logger.Errorw(nil, "Failed to Add LLDP flow to device", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530274 return err
275 }
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700276 logger.Debugw(nil, "LLDP flow added to device successfully ", log.Fields{"flow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530277
278 return nil
279}
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300280
281func GenerateMac(isRand bool) []byte {
282 var mac []byte
283
284 if isRand {
285 for i := 0; i < MacSize; i++ {
286 mac = append(mac, byte(rand.Intn(MacMax-MacMin)+MacMin))
287 }
288 } else {
289 mac = []byte{0x12, 0xAB, 0x34, 0xCD, 0x56, 0xEF}
290 }
291
292 return mac
293}
294
295func GenerateMulticastMac(onu_id uint32, group_id uint32) []byte {
296 var mac []byte
297
298 mac = []byte{0x01, 0x00, 0x5E}
299
300 mac = append(mac, byte(onu_id%255))
301 mac = append(mac, byte(rand.Intn(MacMax-MacMin)+MacMin))
302 mac = append(mac, byte(group_id))
303
304 return mac
305}
306
307func PerformGroupOperation(grp *GroupData, groupCfg *oop.Group) (*oop.Empty, error) {
308 oo := grp.Subs.OpenOltClient
309
310 var err error
311 var res *oop.Empty
312
313 if res, err = oop.OpenoltClient.PerformGroupOperation(oo, context.Background(), groupCfg); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700314 logger.Errorw(nil, "Failed to perform - PerformGroupOperation()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300315 return nil, err
316 }
317
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700318 logger.Info(nil, "Successfully called - PerformGroupOperation()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300319
320 return res, nil
321}
322
323func CreateGroup(grp *GroupData) (*oop.Empty, error) {
324 var groupCfg oop.Group
325
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700326 logger.Infow(nil, "creating group", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300327
328 groupCfg.Command = oop.Group_SET_MEMBERS
329 groupCfg.GroupId = grp.GroupID
330
331 return PerformGroupOperation(grp, &groupCfg)
332}
333
334func OpMulticastTrafficQueue(grp *GroupData, isCreating bool) (*oop.Empty, error) {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700335 logger.Infow(nil, "operating on multicast traffic queue", log.Fields{"Creating": isCreating, "GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300336
337 oo := grp.Subs.OpenOltClient
338
339 var request tp_pb.TrafficQueues
340 request.IntfId = grp.Subs.PonIntf
341 request.OnuId = grp.Subs.OnuID
342 request.UniId = grp.Subs.UniID
343
344 var trafficQueues []*tp_pb.TrafficQueue
345
346 var trafficQueue tp_pb.TrafficQueue
347 trafficQueue.Direction = tp_pb.Direction_DOWNSTREAM
348 trafficQueue.Priority = grp.Priority
349 trafficQueue.Weight = grp.Weight
350 trafficQueue.GemportId = grp.GemPortID
351 trafficQueue.SchedPolicy = grp.SchedPolicy
352
353 trafficQueues = append(trafficQueues, &trafficQueue)
354
355 request.TrafficQueues = trafficQueues
356
357 var err error
358 var res *oop.Empty
359
360 if isCreating {
361 if res, err = oop.OpenoltClient.CreateTrafficQueues(oo, context.Background(), &request); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700362 logger.Errorw(nil, "Failed to perform - CreateTrafficQueues()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300363 return nil, err
364 }
365
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700366 logger.Info(nil, "Successfully called - CreateTrafficQueues()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300367 } else {
368 if res, err = oop.OpenoltClient.RemoveTrafficQueues(oo, context.Background(), &request); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700369 logger.Errorw(nil, "Failed to perform - RemoveTrafficQueues()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300370 return nil, err
371 }
372
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700373 logger.Info(nil, "Successfully called - RemoveTrafficQueues()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300374 }
375
376 return res, nil
377}
378
379func AddMulticastFlow(grp *GroupData) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700380 logger.Infow(nil, "add multicast flow", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300381
382 oo := grp.Subs.OpenOltClient
383 config := grp.Subs.TestConfig
384 rsrMgr := grp.Subs.RsrMgr
385
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700386 var flowID uint64
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300387 var err error
388
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700389 if flowID, err = rsrMgr.GetFlowID(context.Background(), uint32(config.NniIntfID)); err != nil {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300390 return err
391 }
392
393 flowClassifier := &oop.Classifier{
394 IPbits: 255,
395 OPbits: 255,
396 IVid: 55,
397 OVid: 255,
398 DstMac: GenerateMulticastMac(grp.Subs.OnuID, grp.GroupID),
399 PktTagType: DoubleTag}
400
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700401 flow := oop.Flow{AccessIntfId: int32(grp.Subs.PonIntf), OnuId: int32(grp.Subs.OnuID), UniId: int32(grp.Subs.UniID), FlowId: flowID,
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300402 FlowType: "multicast", AllocId: int32(grp.AllocID), GemportId: int32(grp.GemPortID),
403 Classifier: flowClassifier, Priority: int32(grp.Priority), PortNo: uint32(grp.Subs.UniPortNo), GroupId: uint32(grp.GroupID)}
404
405 _, err = oo.FlowAdd(context.Background(), &flow)
406
407 st, _ := status.FromError(err)
408 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700409 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300410 return nil
411 }
412
413 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700414 logger.Errorw(nil, "Failed to add multicast flow to device", log.Fields{"err": err, "deviceFlow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300415 return err
416 }
417
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700418 logger.Debugw(nil, "Multicast flow added to device successfully ", log.Fields{"flow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300419
420 return nil
421}
422
423func AddMulticastSched(grp *GroupData) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700424 logger.Infow(nil, "creating multicast sched", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300425
426 SchedCfg := &tp_pb.SchedulerConfig{
427 Direction: tp_pb.Direction_DOWNSTREAM,
428 AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_BestEffort,
429 Priority: grp.Priority,
430 Weight: grp.Weight,
431 SchedPolicy: tp_pb.SchedulingPolicy_WRR}
432
433 // hard-code for now
434 cir := 1948
435 cbs := 31768
436 eir := 100
437 ebs := 1000
438 pir := cir + eir
439 pbs := cbs + ebs
440
441 TfShInfo := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
442
Girish Gowdra390f12f2021-07-01 15:53:49 -0700443 TrafficSched := []*tp_pb.TrafficScheduler{grp.Subs.RsrMgr.TechprofileRef.
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300444 GetTrafficScheduler(grp.Subs.TpInstance[grp.Subs.TestConfig.TpIDList[0]], SchedCfg, TfShInfo)}
445
446 if TrafficSched == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700447 logger.Error(nil, "Create scheduler for multicast traffic failed")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300448 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
449 }
450
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700451 logger.Debugw(nil, "Sending Traffic scheduler create to device",
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300452 log.Fields{"Direction": tp_pb.Direction_DOWNSTREAM, "TrafficScheds": TrafficSched})
453
454 if _, err := grp.Subs.OpenOltClient.CreateTrafficSchedulers(context.Background(), &tp_pb.TrafficSchedulers{
455 IntfId: grp.Subs.PonIntf, OnuId: grp.Subs.OnuID,
456 UniId: grp.Subs.UniID, PortNo: grp.Subs.UniPortNo,
457 TrafficScheds: TrafficSched}); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700458 logger.Errorw(nil, "Failed to create traffic schedulers", log.Fields{"error": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300459 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
460 }
461
462 return nil
463}
464
465func OpMemberToGroup(grp *GroupData, isAdding bool) (*oop.Empty, error) {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700466 logger.Infow(nil, "operating on group", log.Fields{"Adding": isAdding})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300467
468 var groupCfg oop.Group
469
470 if isAdding {
471 groupCfg.Command = oop.Group_ADD_MEMBERS
472 } else {
473 groupCfg.Command = oop.Group_REMOVE_MEMBERS
474 }
475
476 groupCfg.GroupId = grp.GroupID
477
478 var members []*oop.GroupMember
479
480 var member0 oop.GroupMember
481 member0.InterfaceId = grp.Subs.PonIntf
482 member0.GemPortId = grp.GemPortID
483 member0.Priority = grp.Priority
484 //member0.SchedPolicy = tp_pb.SchedulingPolicy_WRR
485 member0.InterfaceType = oop.GroupMember_PON
486
487 members = append(members, &member0)
488
489 groupCfg.Members = members
490
491 return PerformGroupOperation(grp, &groupCfg)
492}
493
494func AddMulticastQueueFlow(grp *GroupData) error {
495 var err error
496
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700497 logger.Debugw(nil, "Create multicast queue flow", log.Fields{"GroupID": grp.GroupID, "AddGroup": grp.AddGroup,
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300498 "AddFlow": grp.AddFlow, "AddSched": grp.AddSched, "AddQueue": grp.AddQueue, "AddMember": grp.AddMember})
499
500 if grp.AddGroup {
501 if _, err = CreateGroup(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700502 logger.Error(nil, "Failed to add group to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300503 return err
504 }
505 }
506
507 if grp.AddFlow {
508 if err = AddMulticastFlow(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700509 logger.Error(nil, "Failed to add multicast flow to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300510 return err
511 }
512 }
513
514 if grp.AddSched {
515 if err = AddMulticastSched(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700516 logger.Error(nil, "Failed to add multicast sched to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300517 return err
518 }
519 }
520
521 if grp.AddQueue {
522 if _, err = OpMulticastTrafficQueue(grp, true); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700523 logger.Error(nil, "Failed to add multicast queue to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300524 return err
525 }
526 }
527
528 if grp.AddMember {
529 if _, err = OpMemberToGroup(grp, true); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700530 logger.Error(nil, "Failed to add member to group")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300531 return err
532 }
533 }
534
535 return nil
536}
Girish Gowdraaeceb842020-08-21 12:10:39 -0700537
538func CreateTrafficSchedWithRetry(OpenOltClient oop.OpenoltClient, sched *oop.TrafficSchedulers) error {
539 maxRetry := 20
540 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700541 logger.Info(nil, "succeeded in first attempt")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700542 return nil
543 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700544 logger.Info(nil, "going for a retry")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700545 }
546 for i := 0; i < maxRetry; i++ {
547 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700548 logger.Error(nil, "retying after delay")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700549 time.Sleep(50 * time.Millisecond)
550 continue
551 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700552 logger.Infow(nil, "succeeded in retry iteration=%d!!", log.Fields{"i": i})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700553 return nil
554 }
555 }
556
557 return errors.New("failed-to-create-traffic-sched-after-all-retries")
558}
559
560func CreateTrafficQueuesWithRetry(OpenOltClient oop.OpenoltClient, queue *oop.TrafficQueues) error {
561 maxRetry := 20
562 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700563 logger.Info(nil, "succeeded in first attempt")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700564 return nil
565 }
566 for i := 0; i < maxRetry; i++ {
567 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err != nil {
568 time.Sleep(50 * time.Millisecond)
569 continue
570 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700571 logger.Infow(nil, "succeeded in retry iteration=%d!!", log.Fields{"i": i})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700572 return nil
573 }
574 }
575
576 return errors.New("failed-to-create-traffic-queue-after-all-retries")
577}
578
579func AddFlowWithRetry(OpenOltClient oop.OpenoltClient, flow *oop.Flow) error {
580
581 var err error
582 maxRetry := 20
583
584 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
585
586 st, _ := status.FromError(err)
587 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700588 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700589 return nil
590 }
591 if st.Code() == codes.ResourceExhausted {
592 for i := 0; i < maxRetry; i++ {
593 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
594 st, _ := status.FromError(err)
595 if st.Code() == codes.ResourceExhausted {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700596 logger.Error(nil, "flow-install-failed--retrying")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700597 continue
598 } else if st.Code() == codes.OK {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700599 logger.Infow(nil, "flow-install-succeeded-on-retry", log.Fields{"i": i, "flow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700600 return nil
601 }
602 }
603
604 }
605
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700606 logger.Debugw(nil, "Flow install failed on all retries ", log.Fields{"flow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700607
608 return err
609}