blob: a223c02ff43b329fd073f95201d3d2010ab89871 [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"
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030025 "github.com/opencord/voltha-lib-go/v3/pkg/log"
26 "github.com/opencord/voltha-lib-go/v3/pkg/ponresourcemanager"
27 oop "github.com/opencord/voltha-protos/v3/go/openolt"
28 tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053029 "golang.org/x/net/context"
30 "google.golang.org/grpc/codes"
31 "google.golang.org/grpc/status"
32)
33
34const (
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053035 DhcpIPProto = 17
Girish Gowdraef1b7c42020-01-23 16:27:48 +053036
37 //Constants utilised while forming HSIA Flow
38 HsiaFlow = "HSIA_FLOW"
39
40 //Constants utilised while forming DHCP IPV4 Flow
41 DhcpFlowIPV4 = "DHCP_FLOW_IPV4"
42 IPv4EthType = 0x800 //2048
43 DhcpSrcPortIPV4 = 68
44 DhcpDstPortIPV4 = 67
45
46 //Constants utilised while forming DHCP IPV6 Flow
47 DhcpFlowIPV6 = "DHCP_FLOW_IPV6"
48 IPv6EthType = 0x86dd //34525
49 DhcpSrcPortIPV6 = 547
50 DhcpDstPortIPV6 = 546
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053051
52 //Constants utilised while forming EAPOL Flow
53 EapolFlow = "EAPOL_FLOW"
54 EapEthType = 0x888e //34958
55
56 //Direction constant
57 Upstream = "upstream"
58 Downstream = "downstream"
59
60 //PacketTagType constant
61 PacketTagType = "pkt_tag_type"
62 Untagged = "untagged"
63 SingleTag = "single_tag"
64 DoubleTag = "double_tag"
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030065
66 VoipFlow = "VOIP_FLOW"
67
68 VodFlow = "VOD_FLOW"
69
70 MgmtFlow = "MGMT_FLOW"
71
72 IgmpProto = 2
73 IgmpFlow = "IGMP_FLOW"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053074)
75
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +030076const (
77 MacSize = 6
78 MacMin = 0x0
79 MacMax = 0xFF
80)
81
82type GroupData struct {
83 Subs Subscriber `json:"subscriber"`
84 GroupID uint32 `json:"groupID"`
85 Weight uint32 `json:"weight"`
86 Priority uint32 `json:"priority"`
87 OnuID uint32 `json:"onuID"`
88 UniID uint32 `json:"uniID"`
89 AllocID uint32 `json:"allocId"`
90 GemPortID uint32 `json:"gemPortIds"`
91 SchedPolicy tp_pb.SchedulingPolicy `json:"schedPolicy"`
92 AddGroup bool `json:"addGroup"`
93 AddFlow bool `json:"addFlow"`
94 AddSched bool `json:"addSched"`
95 AddQueue bool `json:"addQueue"`
96 AddMember bool `json:"addMember"`
97}
98
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053099func getTrafficSched(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficScheduler {
100 var SchedCfg *tp_pb.SchedulerConfig
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300101 var err error
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530102
103 if direction == tp_pb.Direction_DOWNSTREAM {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300104 SchedCfg, err = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530105 GetDsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530106 } else {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300107 SchedCfg, err = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530108 GetUsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
109 }
110
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300111 if err != nil {
112 log.Errorw("Failed to create traffic schedulers", log.Fields{"direction": direction, "error": err})
113 return nil
114 }
115
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530116 // hard-code for now
117 cir := 16000
118 cbs := 5000
119 eir := 16000
120 ebs := 5000
121 pir := cir + eir
122 pbs := cbs + ebs
123
124 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
125
126 TrafficSched := []*tp_pb.TrafficScheduler{subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
127 GetTrafficScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]], SchedCfg, TrafficShaping)}
128
129 return TrafficSched
130}
131
132func getTrafficQueues(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficQueue {
133
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300134 trafficQueues, err := subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530135 GetTrafficQueues(subs.TpInstance[subs.TestConfig.TpIDList[0]], direction)
136
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300137 if err == nil {
138 return trafficQueues
139 }
140
141 log.Errorw("Failed to create traffic queues", log.Fields{"direction": direction, "error": err})
142 return nil
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530143}
144
145func FormatClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
146 var flowClassifier oop.Classifier
147 var actionCmd oop.ActionCmd
148 var actionInfo oop.Action
149
150 if direction == Upstream {
151 switch flowType {
152 case EapolFlow:
153 flowClassifier.EthType = EapEthType
154 flowClassifier.OVid = subs.Ctag
155 flowClassifier.PktTagType = SingleTag
156 actionCmd.TrapToHost = true
157 actionInfo.Cmd = &actionCmd
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530158 case DhcpFlowIPV4:
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530159 flowClassifier.EthType = IPv4EthType
160 flowClassifier.IpProto = DhcpIPProto
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530161 flowClassifier.SrcPort = DhcpSrcPortIPV4
162 flowClassifier.DstPort = DhcpDstPortIPV4
163 flowClassifier.PktTagType = SingleTag
164 actionCmd.TrapToHost = true
165 actionInfo.Cmd = &actionCmd
166 case DhcpFlowIPV6:
167 flowClassifier.EthType = IPv6EthType
168 flowClassifier.IpProto = DhcpIPProto
169 flowClassifier.SrcPort = DhcpSrcPortIPV6
170 flowClassifier.DstPort = DhcpDstPortIPV6
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530171 flowClassifier.PktTagType = SingleTag
172 actionCmd.TrapToHost = true
173 actionInfo.Cmd = &actionCmd
174 case HsiaFlow:
175 flowClassifier.OVid = subs.Ctag
176 flowClassifier.PktTagType = SingleTag
177 actionCmd.AddOuterTag = true
178 actionInfo.Cmd = &actionCmd
179 actionInfo.OVid = subs.Stag
180 default:
181 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
182 "direction": direction})
183 }
184 } else if direction == Downstream {
185 switch flowType {
186 case EapolFlow:
187 log.Errorw("Downstream EAP flows are not required instead controller "+
188 "packet outs EAP response directly to onu in downstream", log.Fields{"flowtype": flowType,
189 "direction": direction})
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530190 case DhcpFlowIPV4:
191 log.Errorw("Downstream DHCPIPV4 flows are not required instead we have "+
192 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
193 "direction": direction})
194 case DhcpFlowIPV6:
195 log.Errorw("Downstream DHCPIPV6 flows are not required instead we have "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530196 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
197 "direction": direction})
198 case HsiaFlow:
199 flowClassifier.OVid = subs.Stag
200 flowClassifier.IVid = subs.Ctag
201 flowClassifier.PktTagType = DoubleTag
202 actionCmd.RemoveOuterTag = true
203 actionInfo.Cmd = &actionCmd
Girish Gowdra187322d2020-01-20 18:59:21 +0530204 actionInfo.OVid = subs.Stag
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530205 default:
206 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
207 "direction": direction})
208 }
209 }
210 return flowClassifier, actionInfo
211}
212
213func AddFlow(subs *Subscriber, flowType string, direction string, flowID uint32,
Girish Gowdrad4bdd372020-03-09 14:56:15 -0700214 allocID uint32, gemID uint32, pcp uint32) error {
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530215 log.Infow("add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
216 "direction": direction, "flowID": flowID})
217 var err error
218
219 flowClassifier, actionInfo := FormatClassfierAction(flowType, direction, subs)
Girish Gowdrad4bdd372020-03-09 14:56:15 -0700220 // Update the o_pbit for which this flow has to be classified
221 flowClassifier.OPbits = pcp
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530222 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
223 UniId: int32(subs.UniID), FlowId: flowID,
224 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
225 Classifier: &flowClassifier, Action: &actionInfo,
226 Priority: 1000, PortNo: subs.UniPortNo}
227
228 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
229
230 st, _ := status.FromError(err)
231 if st.Code() == codes.AlreadyExists {
232 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
233 return nil
234 }
235
236 if err != nil {
237 log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
238 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
239 }
240 log.Debugw("Flow added to device successfully ", log.Fields{"flow": flow})
241
242 return nil
243}
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530244
245func AddLldpFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
246 var flowID []uint32
247 var err error
248
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300249 if flowID, err = rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].GetResourceID(context.Background(), uint32(config.NniIntfID),
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530250 ponresourcemanager.FLOW_ID, 1); err != nil {
251 return err
252 }
253
254 flowClassifier := &oop.Classifier{EthType: 35020, PktTagType: "untagged"}
255 actionCmd := &oop.ActionCmd{TrapToHost: true}
256 actionInfo := &oop.Action{Cmd: actionCmd}
257
258 flow := oop.Flow{AccessIntfId: -1, OnuId: -1, UniId: -1, FlowId: flowID[0],
259 FlowType: "downstream", AllocId: -1, GemportId: -1,
260 Classifier: flowClassifier, Action: actionInfo,
261 Priority: 1000, PortNo: uint32(config.NniIntfID)}
262
263 _, err = oo.FlowAdd(context.Background(), &flow)
264
265 st, _ := status.FromError(err)
266 if st.Code() == codes.AlreadyExists {
267 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
268 return nil
269 }
270
271 if err != nil {
272 log.Errorw("Failed to Add LLDP flow to device", log.Fields{"err": err, "deviceFlow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300273 rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].FreeResourceID(context.Background(), uint32(config.NniIntfID),
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530274 ponresourcemanager.FLOW_ID, flowID)
275 return err
276 }
277 log.Debugw("LLDP flow added to device successfully ", log.Fields{"flow": flow})
278
279 return nil
280}
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300281
282func GenerateMac(isRand bool) []byte {
283 var mac []byte
284
285 if isRand {
286 for i := 0; i < MacSize; i++ {
287 mac = append(mac, byte(rand.Intn(MacMax-MacMin)+MacMin))
288 }
289 } else {
290 mac = []byte{0x12, 0xAB, 0x34, 0xCD, 0x56, 0xEF}
291 }
292
293 return mac
294}
295
296func GenerateMulticastMac(onu_id uint32, group_id uint32) []byte {
297 var mac []byte
298
299 mac = []byte{0x01, 0x00, 0x5E}
300
301 mac = append(mac, byte(onu_id%255))
302 mac = append(mac, byte(rand.Intn(MacMax-MacMin)+MacMin))
303 mac = append(mac, byte(group_id))
304
305 return mac
306}
307
308func PerformGroupOperation(grp *GroupData, groupCfg *oop.Group) (*oop.Empty, error) {
309 oo := grp.Subs.OpenOltClient
310
311 var err error
312 var res *oop.Empty
313
314 if res, err = oop.OpenoltClient.PerformGroupOperation(oo, context.Background(), groupCfg); err != nil {
315 log.Errorw("Failed to perform - PerformGroupOperation()", log.Fields{"err": err})
316 return nil, err
317 }
318
319 log.Info("Successfully called - PerformGroupOperation()")
320
321 return res, nil
322}
323
324func CreateGroup(grp *GroupData) (*oop.Empty, error) {
325 var groupCfg oop.Group
326
327 log.Infow("creating group", log.Fields{"GroupID": grp.GroupID})
328
329 groupCfg.Command = oop.Group_SET_MEMBERS
330 groupCfg.GroupId = grp.GroupID
331
332 return PerformGroupOperation(grp, &groupCfg)
333}
334
335func OpMulticastTrafficQueue(grp *GroupData, isCreating bool) (*oop.Empty, error) {
336 log.Infow("operating on multicast traffic queue", log.Fields{"Creating": isCreating, "GroupID": grp.GroupID})
337
338 oo := grp.Subs.OpenOltClient
339
340 var request tp_pb.TrafficQueues
341 request.IntfId = grp.Subs.PonIntf
342 request.OnuId = grp.Subs.OnuID
343 request.UniId = grp.Subs.UniID
344
345 var trafficQueues []*tp_pb.TrafficQueue
346
347 var trafficQueue tp_pb.TrafficQueue
348 trafficQueue.Direction = tp_pb.Direction_DOWNSTREAM
349 trafficQueue.Priority = grp.Priority
350 trafficQueue.Weight = grp.Weight
351 trafficQueue.GemportId = grp.GemPortID
352 trafficQueue.SchedPolicy = grp.SchedPolicy
353
354 trafficQueues = append(trafficQueues, &trafficQueue)
355
356 request.TrafficQueues = trafficQueues
357
358 var err error
359 var res *oop.Empty
360
361 if isCreating {
362 if res, err = oop.OpenoltClient.CreateTrafficQueues(oo, context.Background(), &request); err != nil {
363 log.Errorw("Failed to perform - CreateTrafficQueues()", log.Fields{"err": err})
364 return nil, err
365 }
366
367 log.Info("Successfully called - CreateTrafficQueues()")
368 } else {
369 if res, err = oop.OpenoltClient.RemoveTrafficQueues(oo, context.Background(), &request); err != nil {
370 log.Errorw("Failed to perform - RemoveTrafficQueues()", log.Fields{"err": err})
371 return nil, err
372 }
373
374 log.Info("Successfully called - RemoveTrafficQueues()")
375 }
376
377 return res, nil
378}
379
380func AddMulticastFlow(grp *GroupData) error {
381 log.Infow("add multicast flow", log.Fields{"GroupID": grp.GroupID})
382
383 oo := grp.Subs.OpenOltClient
384 config := grp.Subs.TestConfig
385 rsrMgr := grp.Subs.RsrMgr
386
387 var flowID []uint32
388 var err error
389
390 if flowID, err = rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].GetResourceID(context.Background(), uint32(config.NniIntfID),
391 ponresourcemanager.FLOW_ID, 1); err != nil {
392 return err
393 }
394
395 flowClassifier := &oop.Classifier{
396 IPbits: 255,
397 OPbits: 255,
398 IVid: 55,
399 OVid: 255,
400 DstMac: GenerateMulticastMac(grp.Subs.OnuID, grp.GroupID),
401 PktTagType: DoubleTag}
402
403 flow := oop.Flow{AccessIntfId: int32(grp.Subs.PonIntf), OnuId: int32(grp.Subs.OnuID), UniId: int32(grp.Subs.UniID), FlowId: flowID[0],
404 FlowType: "multicast", AllocId: int32(grp.AllocID), GemportId: int32(grp.GemPortID),
405 Classifier: flowClassifier, Priority: int32(grp.Priority), PortNo: uint32(grp.Subs.UniPortNo), GroupId: uint32(grp.GroupID)}
406
407 _, err = oo.FlowAdd(context.Background(), &flow)
408
409 st, _ := status.FromError(err)
410 if st.Code() == codes.AlreadyExists {
411 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
412 return nil
413 }
414
415 if err != nil {
416 log.Errorw("Failed to add multicast flow to device", log.Fields{"err": err, "deviceFlow": flow})
417 rsrMgr.ResourceMgrs[uint32(grp.Subs.PonIntf)].FreeResourceID(context.Background(), uint32(config.NniIntfID),
418 ponresourcemanager.FLOW_ID, flowID)
419 return err
420 }
421
422 log.Debugw("Multicast flow added to device successfully ", log.Fields{"flow": flow})
423
424 return nil
425}
426
427func AddMulticastSched(grp *GroupData) error {
428 log.Infow("creating multicast sched", log.Fields{"GroupID": grp.GroupID})
429
430 SchedCfg := &tp_pb.SchedulerConfig{
431 Direction: tp_pb.Direction_DOWNSTREAM,
432 AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_BestEffort,
433 Priority: grp.Priority,
434 Weight: grp.Weight,
435 SchedPolicy: tp_pb.SchedulingPolicy_WRR}
436
437 // hard-code for now
438 cir := 1948
439 cbs := 31768
440 eir := 100
441 ebs := 1000
442 pir := cir + eir
443 pbs := cbs + ebs
444
445 TfShInfo := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
446
447 TrafficSched := []*tp_pb.TrafficScheduler{grp.Subs.RsrMgr.ResourceMgrs[grp.Subs.PonIntf].TechProfileMgr.
448 GetTrafficScheduler(grp.Subs.TpInstance[grp.Subs.TestConfig.TpIDList[0]], SchedCfg, TfShInfo)}
449
450 if TrafficSched == nil {
451 log.Error("Create scheduler for multicast traffic failed")
452 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
453 }
454
455 log.Debugw("Sending Traffic scheduler create to device",
456 log.Fields{"Direction": tp_pb.Direction_DOWNSTREAM, "TrafficScheds": TrafficSched})
457
458 if _, err := grp.Subs.OpenOltClient.CreateTrafficSchedulers(context.Background(), &tp_pb.TrafficSchedulers{
459 IntfId: grp.Subs.PonIntf, OnuId: grp.Subs.OnuID,
460 UniId: grp.Subs.UniID, PortNo: grp.Subs.UniPortNo,
461 TrafficScheds: TrafficSched}); err != nil {
462 log.Errorw("Failed to create traffic schedulers", log.Fields{"error": err})
463 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
464 }
465
466 return nil
467}
468
469func OpMemberToGroup(grp *GroupData, isAdding bool) (*oop.Empty, error) {
470 log.Infow("operating on group", log.Fields{"Adding": isAdding})
471
472 var groupCfg oop.Group
473
474 if isAdding {
475 groupCfg.Command = oop.Group_ADD_MEMBERS
476 } else {
477 groupCfg.Command = oop.Group_REMOVE_MEMBERS
478 }
479
480 groupCfg.GroupId = grp.GroupID
481
482 var members []*oop.GroupMember
483
484 var member0 oop.GroupMember
485 member0.InterfaceId = grp.Subs.PonIntf
486 member0.GemPortId = grp.GemPortID
487 member0.Priority = grp.Priority
488 //member0.SchedPolicy = tp_pb.SchedulingPolicy_WRR
489 member0.InterfaceType = oop.GroupMember_PON
490
491 members = append(members, &member0)
492
493 groupCfg.Members = members
494
495 return PerformGroupOperation(grp, &groupCfg)
496}
497
498func AddMulticastQueueFlow(grp *GroupData) error {
499 var err error
500
501 log.Debugw("Create multicast queue flow", log.Fields{"GroupID": grp.GroupID, "AddGroup": grp.AddGroup,
502 "AddFlow": grp.AddFlow, "AddSched": grp.AddSched, "AddQueue": grp.AddQueue, "AddMember": grp.AddMember})
503
504 if grp.AddGroup {
505 if _, err = CreateGroup(grp); err != nil {
506 log.Error("Failed to add group to device")
507 return err
508 }
509 }
510
511 if grp.AddFlow {
512 if err = AddMulticastFlow(grp); err != nil {
513 log.Error("Failed to add multicast flow to device")
514 return err
515 }
516 }
517
518 if grp.AddSched {
519 if err = AddMulticastSched(grp); err != nil {
520 log.Error("Failed to add multicast sched to device")
521 return err
522 }
523 }
524
525 if grp.AddQueue {
526 if _, err = OpMulticastTrafficQueue(grp, true); err != nil {
527 log.Error("Failed to add multicast queue to device")
528 return err
529 }
530 }
531
532 if grp.AddMember {
533 if _, err = OpMemberToGroup(grp, true); err != nil {
534 log.Error("Failed to add member to group")
535 return err
536 }
537 }
538
539 return nil
540}
Girish Gowdraaeceb842020-08-21 12:10:39 -0700541
542func CreateTrafficSchedWithRetry(OpenOltClient oop.OpenoltClient, sched *oop.TrafficSchedulers) error {
543 maxRetry := 20
544 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err == nil {
545 log.Info("succeeded in first attempt")
546 return nil
547 } else {
548 log.Info("going for a retry")
549 }
550 for i := 0; i < maxRetry; i++ {
551 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err != nil {
552 log.Error("retying after delay")
553 time.Sleep(50 * time.Millisecond)
554 continue
555 } else {
556 log.Infow("succeeded in retry iteration=%d!!", log.Fields{"i": i})
557 return nil
558 }
559 }
560
561 return errors.New("failed-to-create-traffic-sched-after-all-retries")
562}
563
564func CreateTrafficQueuesWithRetry(OpenOltClient oop.OpenoltClient, queue *oop.TrafficQueues) error {
565 maxRetry := 20
566 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err == nil {
567 log.Info("succeeded in first attempt")
568 return nil
569 }
570 for i := 0; i < maxRetry; i++ {
571 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err != nil {
572 time.Sleep(50 * time.Millisecond)
573 continue
574 } else {
575 log.Infow("succeeded in retry iteration=%d!!", log.Fields{"i": i})
576 return nil
577 }
578 }
579
580 return errors.New("failed-to-create-traffic-queue-after-all-retries")
581}
582
583func AddFlowWithRetry(OpenOltClient oop.OpenoltClient, flow *oop.Flow) error {
584
585 var err error
586 maxRetry := 20
587
588 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
589
590 st, _ := status.FromError(err)
591 if st.Code() == codes.AlreadyExists {
592 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
593 return nil
594 }
595 if st.Code() == codes.ResourceExhausted {
596 for i := 0; i < maxRetry; i++ {
597 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
598 st, _ := status.FromError(err)
599 if st.Code() == codes.ResourceExhausted {
600 log.Error("flow-install-failed--retrying")
601 continue
602 } else if st.Code() == codes.OK {
603 log.Infow("flow-install-succeeded-on-retry", log.Fields{"i": i, "flow": flow})
604 return nil
605 }
606 }
607
608 }
609
610 log.Debugw("Flow install failed on all retries ", log.Fields{"flow": flow})
611
612 return err
613}