blob: 818b3ecd6909a978c6c7c01741db51efc7554725 [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 Gowdra5d7d6442020-09-08 17:03:11 -070025 "github.com/opencord/voltha-lib-go/v4/pkg/log"
26 oop "github.com/opencord/voltha-protos/v4/go/openolt"
27 tp_pb "github.com/opencord/voltha-protos/v4/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
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300100 var err error
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530101
102 if direction == tp_pb.Direction_DOWNSTREAM {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300103 SchedCfg, err = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700104 GetDsScheduler(nil, subs.TpInstance[subs.TestConfig.TpIDList[0]])
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530105 } else {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300106 SchedCfg, err = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700107 GetUsScheduler(nil, subs.TpInstance[subs.TestConfig.TpIDList[0]])
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530108 }
109
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300110 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700111 logger.Errorw(nil, "Failed to create traffic schedulers", log.Fields{"direction": direction, "error": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300112 return nil
113 }
114
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530115 // hard-code for now
116 cir := 16000
117 cbs := 5000
118 eir := 16000
119 ebs := 5000
120 pir := cir + eir
121 pbs := cbs + ebs
122
123 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
124
125 TrafficSched := []*tp_pb.TrafficScheduler{subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
126 GetTrafficScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]], SchedCfg, TrafficShaping)}
127
128 return TrafficSched
129}
130
131func getTrafficQueues(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficQueue {
132
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300133 trafficQueues, err := subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700134 GetTrafficQueues(nil, subs.TpInstance[subs.TestConfig.TpIDList[0]], direction)
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530135
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300136 if err == nil {
137 return trafficQueues
138 }
139
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700140 logger.Errorw(nil, "Failed to create traffic queues", log.Fields{"direction": direction, "error": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300141 return nil
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530142}
143
144func FormatClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
145 var flowClassifier oop.Classifier
146 var actionCmd oop.ActionCmd
147 var actionInfo oop.Action
148
149 if direction == Upstream {
150 switch flowType {
151 case EapolFlow:
152 flowClassifier.EthType = EapEthType
153 flowClassifier.OVid = subs.Ctag
154 flowClassifier.PktTagType = SingleTag
155 actionCmd.TrapToHost = true
156 actionInfo.Cmd = &actionCmd
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530157 case DhcpFlowIPV4:
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530158 flowClassifier.EthType = IPv4EthType
159 flowClassifier.IpProto = DhcpIPProto
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530160 flowClassifier.SrcPort = DhcpSrcPortIPV4
161 flowClassifier.DstPort = DhcpDstPortIPV4
162 flowClassifier.PktTagType = SingleTag
163 actionCmd.TrapToHost = true
164 actionInfo.Cmd = &actionCmd
165 case DhcpFlowIPV6:
166 flowClassifier.EthType = IPv6EthType
167 flowClassifier.IpProto = DhcpIPProto
168 flowClassifier.SrcPort = DhcpSrcPortIPV6
169 flowClassifier.DstPort = DhcpDstPortIPV6
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530170 flowClassifier.PktTagType = SingleTag
171 actionCmd.TrapToHost = true
172 actionInfo.Cmd = &actionCmd
173 case HsiaFlow:
174 flowClassifier.OVid = subs.Ctag
175 flowClassifier.PktTagType = SingleTag
176 actionCmd.AddOuterTag = true
177 actionInfo.Cmd = &actionCmd
178 actionInfo.OVid = subs.Stag
179 default:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700180 logger.Errorw(nil, "Unsupported flow type", log.Fields{"flowtype": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530181 "direction": direction})
182 }
183 } else if direction == Downstream {
184 switch flowType {
185 case EapolFlow:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700186 logger.Errorw(nil, "Downstream EAP flows are not required instead controller "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530187 "packet outs EAP response directly to onu in downstream", log.Fields{"flowtype": flowType,
188 "direction": direction})
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530189 case DhcpFlowIPV4:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700190 logger.Errorw(nil, "Downstream DHCPIPV4 flows are not required instead we have "+
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530191 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
192 "direction": direction})
193 case DhcpFlowIPV6:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700194 logger.Errorw(nil, "Downstream DHCPIPV6 flows are not required instead we have "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530195 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
196 "direction": direction})
197 case HsiaFlow:
198 flowClassifier.OVid = subs.Stag
199 flowClassifier.IVid = subs.Ctag
200 flowClassifier.PktTagType = DoubleTag
201 actionCmd.RemoveOuterTag = true
202 actionInfo.Cmd = &actionCmd
Girish Gowdra187322d2020-01-20 18:59:21 +0530203 actionInfo.OVid = subs.Stag
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530204 default:
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700205 logger.Errorw(nil, "Unsupported flow type", log.Fields{"flowtype": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530206 "direction": direction})
207 }
208 }
209 return flowClassifier, actionInfo
210}
211
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700212func AddFlow(subs *Subscriber, flowType string, direction string, flowID uint64,
213 allocID uint32, gemID uint32, pcp uint32, replicateFlow bool, symmetricFlowID uint64,
214 pbitToGem map[uint32]uint32) error {
215 logger.Infow(nil, "add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530216 "direction": direction, "flowID": flowID})
217 var err error
218
219 flowClassifier, actionInfo := FormatClassfierAction(flowType, direction, subs)
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700220 // Update the o_pbit (if valid) for which this flow has to be classified
221 if pcp != 0xff {
222 flowClassifier.OPbits = pcp
223 }
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530224 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
225 UniId: int32(subs.UniID), FlowId: flowID,
226 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
227 Classifier: &flowClassifier, Action: &actionInfo,
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700228 Priority: 1000, PortNo: subs.UniPortNo, SymmetricFlowId: symmetricFlowID,
229 ReplicateFlow: replicateFlow, PbitToGemport: pbitToGem}
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530230
231 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
232
233 st, _ := status.FromError(err)
234 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700235 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530236 return nil
237 }
238
239 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700240 logger.Errorw(nil, "Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530241 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
242 }
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700243 logger.Debugw(nil, "Flow added to device successfully ", log.Fields{"flow": flow})
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530244
245 return nil
246}
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530247
248func AddLldpFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700249 var flowID uint64
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530250 var err error
251
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700252 if flowID, err = rsrMgr.GetFlowID(context.Background(), uint32(config.NniIntfID)); err != nil {
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530253 return err
254 }
255
256 flowClassifier := &oop.Classifier{EthType: 35020, PktTagType: "untagged"}
257 actionCmd := &oop.ActionCmd{TrapToHost: true}
258 actionInfo := &oop.Action{Cmd: actionCmd}
259
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700260 flow := oop.Flow{AccessIntfId: -1, OnuId: -1, UniId: -1, FlowId: flowID,
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530261 FlowType: "downstream", AllocId: -1, GemportId: -1,
262 Classifier: flowClassifier, Action: actionInfo,
263 Priority: 1000, PortNo: uint32(config.NniIntfID)}
264
265 _, err = oo.FlowAdd(context.Background(), &flow)
266
267 st, _ := status.FromError(err)
268 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700269 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530270 return nil
271 }
272
273 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700274 logger.Errorw(nil, "Failed to Add LLDP flow to device", log.Fields{"err": err, "deviceFlow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530275 return err
276 }
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700277 logger.Debugw(nil, "LLDP flow added to device successfully ", log.Fields{"flow": flow})
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530278
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 {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700315 logger.Errorw(nil, "Failed to perform - PerformGroupOperation()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300316 return nil, err
317 }
318
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700319 logger.Info(nil, "Successfully called - PerformGroupOperation()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300320
321 return res, nil
322}
323
324func CreateGroup(grp *GroupData) (*oop.Empty, error) {
325 var groupCfg oop.Group
326
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700327 logger.Infow(nil, "creating group", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300328
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) {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700336 logger.Infow(nil, "operating on multicast traffic queue", log.Fields{"Creating": isCreating, "GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300337
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 {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700363 logger.Errorw(nil, "Failed to perform - CreateTrafficQueues()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300364 return nil, err
365 }
366
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700367 logger.Info(nil, "Successfully called - CreateTrafficQueues()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300368 } else {
369 if res, err = oop.OpenoltClient.RemoveTrafficQueues(oo, context.Background(), &request); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700370 logger.Errorw(nil, "Failed to perform - RemoveTrafficQueues()", log.Fields{"err": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300371 return nil, err
372 }
373
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700374 logger.Info(nil, "Successfully called - RemoveTrafficQueues()")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300375 }
376
377 return res, nil
378}
379
380func AddMulticastFlow(grp *GroupData) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700381 logger.Infow(nil, "add multicast flow", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300382
383 oo := grp.Subs.OpenOltClient
384 config := grp.Subs.TestConfig
385 rsrMgr := grp.Subs.RsrMgr
386
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700387 var flowID uint64
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300388 var err error
389
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700390 if flowID, err = rsrMgr.GetFlowID(context.Background(), uint32(config.NniIntfID)); err != nil {
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300391 return err
392 }
393
394 flowClassifier := &oop.Classifier{
395 IPbits: 255,
396 OPbits: 255,
397 IVid: 55,
398 OVid: 255,
399 DstMac: GenerateMulticastMac(grp.Subs.OnuID, grp.GroupID),
400 PktTagType: DoubleTag}
401
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700402 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 +0300403 FlowType: "multicast", AllocId: int32(grp.AllocID), GemportId: int32(grp.GemPortID),
404 Classifier: flowClassifier, Priority: int32(grp.Priority), PortNo: uint32(grp.Subs.UniPortNo), GroupId: uint32(grp.GroupID)}
405
406 _, err = oo.FlowAdd(context.Background(), &flow)
407
408 st, _ := status.FromError(err)
409 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700410 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300411 return nil
412 }
413
414 if err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700415 logger.Errorw(nil, "Failed to add multicast flow to device", log.Fields{"err": err, "deviceFlow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300416 return err
417 }
418
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700419 logger.Debugw(nil, "Multicast flow added to device successfully ", log.Fields{"flow": flow})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300420
421 return nil
422}
423
424func AddMulticastSched(grp *GroupData) error {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700425 logger.Infow(nil, "creating multicast sched", log.Fields{"GroupID": grp.GroupID})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300426
427 SchedCfg := &tp_pb.SchedulerConfig{
428 Direction: tp_pb.Direction_DOWNSTREAM,
429 AdditionalBw: tp_pb.AdditionalBW_AdditionalBW_BestEffort,
430 Priority: grp.Priority,
431 Weight: grp.Weight,
432 SchedPolicy: tp_pb.SchedulingPolicy_WRR}
433
434 // hard-code for now
435 cir := 1948
436 cbs := 31768
437 eir := 100
438 ebs := 1000
439 pir := cir + eir
440 pbs := cbs + ebs
441
442 TfShInfo := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
443
444 TrafficSched := []*tp_pb.TrafficScheduler{grp.Subs.RsrMgr.ResourceMgrs[grp.Subs.PonIntf].TechProfileMgr.
445 GetTrafficScheduler(grp.Subs.TpInstance[grp.Subs.TestConfig.TpIDList[0]], SchedCfg, TfShInfo)}
446
447 if TrafficSched == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700448 logger.Error(nil, "Create scheduler for multicast traffic failed")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300449 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
450 }
451
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700452 logger.Debugw(nil, "Sending Traffic scheduler create to device",
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300453 log.Fields{"Direction": tp_pb.Direction_DOWNSTREAM, "TrafficScheds": TrafficSched})
454
455 if _, err := grp.Subs.OpenOltClient.CreateTrafficSchedulers(context.Background(), &tp_pb.TrafficSchedulers{
456 IntfId: grp.Subs.PonIntf, OnuId: grp.Subs.OnuID,
457 UniId: grp.Subs.UniID, PortNo: grp.Subs.UniPortNo,
458 TrafficScheds: TrafficSched}); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700459 logger.Errorw(nil, "Failed to create traffic schedulers", log.Fields{"error": err})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300460 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
461 }
462
463 return nil
464}
465
466func OpMemberToGroup(grp *GroupData, isAdding bool) (*oop.Empty, error) {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700467 logger.Infow(nil, "operating on group", log.Fields{"Adding": isAdding})
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300468
469 var groupCfg oop.Group
470
471 if isAdding {
472 groupCfg.Command = oop.Group_ADD_MEMBERS
473 } else {
474 groupCfg.Command = oop.Group_REMOVE_MEMBERS
475 }
476
477 groupCfg.GroupId = grp.GroupID
478
479 var members []*oop.GroupMember
480
481 var member0 oop.GroupMember
482 member0.InterfaceId = grp.Subs.PonIntf
483 member0.GemPortId = grp.GemPortID
484 member0.Priority = grp.Priority
485 //member0.SchedPolicy = tp_pb.SchedulingPolicy_WRR
486 member0.InterfaceType = oop.GroupMember_PON
487
488 members = append(members, &member0)
489
490 groupCfg.Members = members
491
492 return PerformGroupOperation(grp, &groupCfg)
493}
494
495func AddMulticastQueueFlow(grp *GroupData) error {
496 var err error
497
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700498 logger.Debugw(nil, "Create multicast queue flow", log.Fields{"GroupID": grp.GroupID, "AddGroup": grp.AddGroup,
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300499 "AddFlow": grp.AddFlow, "AddSched": grp.AddSched, "AddQueue": grp.AddQueue, "AddMember": grp.AddMember})
500
501 if grp.AddGroup {
502 if _, err = CreateGroup(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700503 logger.Error(nil, "Failed to add group to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300504 return err
505 }
506 }
507
508 if grp.AddFlow {
509 if err = AddMulticastFlow(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700510 logger.Error(nil, "Failed to add multicast flow to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300511 return err
512 }
513 }
514
515 if grp.AddSched {
516 if err = AddMulticastSched(grp); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700517 logger.Error(nil, "Failed to add multicast sched to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300518 return err
519 }
520 }
521
522 if grp.AddQueue {
523 if _, err = OpMulticastTrafficQueue(grp, true); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700524 logger.Error(nil, "Failed to add multicast queue to device")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300525 return err
526 }
527 }
528
529 if grp.AddMember {
530 if _, err = OpMemberToGroup(grp, true); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700531 logger.Error(nil, "Failed to add member to group")
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +0300532 return err
533 }
534 }
535
536 return nil
537}
Girish Gowdraaeceb842020-08-21 12:10:39 -0700538
539func CreateTrafficSchedWithRetry(OpenOltClient oop.OpenoltClient, sched *oop.TrafficSchedulers) error {
540 maxRetry := 20
541 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700542 logger.Info(nil, "succeeded in first attempt")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700543 return nil
544 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700545 logger.Info(nil, "going for a retry")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700546 }
547 for i := 0; i < maxRetry; i++ {
548 if _, err := OpenOltClient.CreateTrafficSchedulers(context.Background(), sched); err != nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700549 logger.Error(nil, "retying after delay")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700550 time.Sleep(50 * time.Millisecond)
551 continue
552 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700553 logger.Infow(nil, "succeeded in retry iteration=%d!!", log.Fields{"i": i})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700554 return nil
555 }
556 }
557
558 return errors.New("failed-to-create-traffic-sched-after-all-retries")
559}
560
561func CreateTrafficQueuesWithRetry(OpenOltClient oop.OpenoltClient, queue *oop.TrafficQueues) error {
562 maxRetry := 20
563 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err == nil {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700564 logger.Info(nil, "succeeded in first attempt")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700565 return nil
566 }
567 for i := 0; i < maxRetry; i++ {
568 if _, err := OpenOltClient.CreateTrafficQueues(context.Background(), queue); err != nil {
569 time.Sleep(50 * time.Millisecond)
570 continue
571 } else {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700572 logger.Infow(nil, "succeeded in retry iteration=%d!!", log.Fields{"i": i})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700573 return nil
574 }
575 }
576
577 return errors.New("failed-to-create-traffic-queue-after-all-retries")
578}
579
580func AddFlowWithRetry(OpenOltClient oop.OpenoltClient, flow *oop.Flow) error {
581
582 var err error
583 maxRetry := 20
584
585 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
586
587 st, _ := status.FromError(err)
588 if st.Code() == codes.AlreadyExists {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700589 logger.Debugw(nil, "Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700590 return nil
591 }
592 if st.Code() == codes.ResourceExhausted {
593 for i := 0; i < maxRetry; i++ {
594 _, err = OpenOltClient.FlowAdd(context.Background(), flow)
595 st, _ := status.FromError(err)
596 if st.Code() == codes.ResourceExhausted {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700597 logger.Error(nil, "flow-install-failed--retrying")
Girish Gowdraaeceb842020-08-21 12:10:39 -0700598 continue
599 } else if st.Code() == codes.OK {
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700600 logger.Infow(nil, "flow-install-succeeded-on-retry", log.Fields{"i": i, "flow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700601 return nil
602 }
603 }
604
605 }
606
Girish Gowdra5d7d6442020-09-08 17:03:11 -0700607 logger.Debugw(nil, "Flow install failed on all retries ", log.Fields{"flow": flow})
Girish Gowdraaeceb842020-08-21 12:10:39 -0700608
609 return err
610}