blob: 862da20618b81b46658752b12d48ce56a87e3486 [file] [log] [blame]
Orhan Kupusoglu66b00d82020-03-13 12:06:33 +03001/*
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"
21 "strings"
22 "sync/atomic"
23
24 "github.com/opencord/openolt-scale-tester/config"
25 "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"
29 "golang.org/x/net/context"
30 "google.golang.org/grpc/codes"
31 "google.golang.org/grpc/status"
32)
33
34var lastPonIntf *uint32 = new(uint32)
35
36func init() {
37 _, _ = log.AddPackage(log.JSON, log.DebugLevel, nil)
38}
39
40// A dummy struct to comply with the WorkFlow interface.
41type TtWorkFlow struct {
42}
43
44func AddTtDhcpIPV4Flow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
45 var flowID []uint32
46 var err error
47
48 if flowID, err = rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].GetResourceID(context.Background(), uint32(config.NniIntfID),
49 ponresourcemanager.FLOW_ID, 1); err != nil {
50 return err
51 }
52
53 // DHCP IPV4
54 flowClassifier := &oop.Classifier{EthType: 2048, IpProto: 17, SrcPort: 67, DstPort: 68, PktTagType: "double_tag"}
55 actionCmd := &oop.ActionCmd{TrapToHost: true}
56 actionInfo := &oop.Action{Cmd: actionCmd}
57
58 flow := oop.Flow{AccessIntfId: -1, OnuId: -1, UniId: -1, FlowId: flowID[0],
59 FlowType: "downstream", AllocId: -1, GemportId: -1,
60 Classifier: flowClassifier, Action: actionInfo,
61 Priority: 1000, PortNo: uint32(config.NniIntfID)}
62
63 _, err = oo.FlowAdd(context.Background(), &flow)
64
65 st, _ := status.FromError(err)
66 if st.Code() == codes.AlreadyExists {
67 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
68 return nil
69 }
70
71 if err != nil {
72 log.Errorw("Failed to Add DHCP IPv4 to device", log.Fields{"err": err, "deviceFlow": flow})
73 rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].FreeResourceID(context.Background(), uint32(config.NniIntfID),
74 ponresourcemanager.FLOW_ID, flowID)
75 return err
76 }
77 log.Debugw("DHCP IPV4 added to device successfully ", log.Fields{"flow": flow})
78
79 return nil
80}
81
82func AddTtDhcpIPV6Flow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
83 log.Info("tt-workflow-does-not-require-dhcp-ipv6-support--nothing-to-do")
84 return nil
85}
86
87func ProvisionTtNniTrapFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
88 _ = AddTtDhcpIPV4Flow(oo, config, rsrMgr)
89 return nil
90}
91
92func FormatTtClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
93 var flowClassifier oop.Classifier
94 var actionCmd oop.ActionCmd
95 var actionInfo oop.Action
96
97 if direction == Upstream {
98 switch flowType {
99 case IgmpFlow:
100 flowClassifier.EthType = IPv4EthType
101 flowClassifier.IpProto = IgmpProto
102 flowClassifier.SrcPort = 0
103 flowClassifier.DstPort = 0
104 flowClassifier.PktTagType = SingleTag
105 actionCmd.TrapToHost = true
106 actionInfo.Cmd = &actionCmd
107 case HsiaFlow:
108 actionCmd.AddOuterTag = true
109 actionInfo.Cmd = &actionCmd
110 actionInfo.IVid = 33
111 actionInfo.OVid = 7
112 flowClassifier.IPbits = 255
113 flowClassifier.OVid = 33
114 flowClassifier.PktTagType = SingleTag
115 case VoipFlow:
116 actionCmd.AddOuterTag = true
117 actionInfo.Cmd = &actionCmd
118 actionInfo.OPbits = 7
119 actionInfo.IVid = 63
120 actionInfo.OVid = 10
121 flowClassifier.IPbits = 255
122 flowClassifier.OPbits = 7
123 flowClassifier.OVid = 63
124 flowClassifier.PktTagType = SingleTag
125 case VodFlow:
126 actionCmd.AddOuterTag = true
127 actionInfo.Cmd = &actionCmd
128 actionInfo.OPbits = 5
129 actionInfo.IVid = 55
130 actionInfo.OVid = 555
131 flowClassifier.IPbits = 255
132 flowClassifier.OPbits = 5
133 flowClassifier.OVid = 55
134 flowClassifier.PktTagType = SingleTag
135 case MgmtFlow:
136 actionCmd.AddOuterTag = true
137 actionInfo.Cmd = &actionCmd
138 actionInfo.OPbits = 7
139 actionInfo.IVid = 75
140 actionInfo.OVid = 575
141 flowClassifier.IPbits = 255
142 flowClassifier.OPbits = 7
143 flowClassifier.OVid = 75
144 flowClassifier.PktTagType = SingleTag
145 default:
146 log.Errorw("Unsupported TT flow type", log.Fields{"flowtype": flowType,
147 "direction": direction})
148 }
149 } else if direction == Downstream {
150 switch flowType {
151 case IgmpFlow:
152 log.Errorw("Downstream IGMP flows are not required instead we have "+
153 "IGMP trap flows already installed", log.Fields{"flowtype": flowType,
154 "direction": direction})
155 case HsiaFlow:
156 actionCmd.RemoveOuterTag = true
157 actionInfo.Cmd = &actionCmd
158 actionInfo.IVid = 33
159 flowClassifier.IPbits = 255
160 flowClassifier.OPbits = 255
161 flowClassifier.IVid = 33
162 flowClassifier.OVid = 7
163 flowClassifier.PktTagType = DoubleTag
164 case VoipFlow:
165 actionCmd.RemoveOuterTag = true
166 actionInfo.Cmd = &actionCmd
167 actionInfo.IPbits = 7
168 actionInfo.IVid = 63
169 flowClassifier.IPbits = 255
170 flowClassifier.OPbits = 255
171 flowClassifier.IVid = 63
172 flowClassifier.OVid = 10
173 flowClassifier.DstMac = GenerateMac(true)
174 flowClassifier.PktTagType = DoubleTag
175 case VodFlow:
176 actionCmd.RemoveOuterTag = true
177 actionInfo.Cmd = &actionCmd
178 actionInfo.IPbits = 5
179 actionInfo.IVid = 55
180 flowClassifier.IPbits = 255
181 flowClassifier.OPbits = 255
182 flowClassifier.IVid = 55
183 flowClassifier.OVid = 555
184 flowClassifier.DstMac = GenerateMac(true)
185 flowClassifier.PktTagType = DoubleTag
186 case MgmtFlow:
187 actionCmd.RemoveOuterTag = true
188 actionInfo.Cmd = &actionCmd
189 actionInfo.IPbits = 7
190 actionInfo.IVid = 75
191 flowClassifier.IPbits = 255
192 flowClassifier.OPbits = 255
193 flowClassifier.IVid = 75
194 flowClassifier.OVid = 575
195 flowClassifier.DstMac = GenerateMac(true)
196 flowClassifier.PktTagType = DoubleTag
197 default:
198 log.Errorw("Unsupported TT flow type", log.Fields{"flowtype": flowType,
199 "direction": direction})
200 }
201 }
202 return flowClassifier, actionInfo
203}
204
205func AddTtFlow(subs *Subscriber, flowType string, direction string, flowID uint32,
206 allocID uint32, gemID uint32, pcp uint32) error {
207 log.Infow("add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
208 "direction": direction, "flowID": flowID})
209 var err error
210
211 flowClassifier, actionInfo := FormatTtClassfierAction(flowType, direction, subs)
212 // Update the o_pbit for which this flow has to be classified
213 flowClassifier.OPbits = pcp
214 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
215 UniId: int32(subs.UniID), FlowId: flowID,
216 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
217 Classifier: &flowClassifier, Action: &actionInfo,
218 Priority: 1000, PortNo: subs.UniPortNo}
219
220 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
221
222 st, _ := status.FromError(err)
223 if st.Code() == codes.AlreadyExists {
224 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
225 return nil
226 }
227
228 if err != nil {
229 log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
230 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
231 }
232 log.Debugw("Flow added to device successfully ", log.Fields{"flow": flow})
233
234 return nil
235}
236
237func (tt TtWorkFlow) ProvisionScheds(subs *Subscriber) error {
238 var trafficSched []*tp_pb.TrafficScheduler
239
240 log.Info("provisioning-scheds")
241
242 if trafficSched = getTrafficSched(subs, tp_pb.Direction_DOWNSTREAM); trafficSched == nil {
243 log.Error("ds-traffic-sched-is-nil")
244 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
245 }
246
247 log.Debugw("Sending Traffic scheduler create to device",
248 log.Fields{"Direction": tp_pb.Direction_DOWNSTREAM, "TrafficScheds": trafficSched})
249 if _, err := subs.OpenOltClient.CreateTrafficSchedulers(context.Background(), &tp_pb.TrafficSchedulers{
250 IntfId: subs.PonIntf, OnuId: subs.OnuID,
251 UniId: subs.UniID, PortNo: subs.UniPortNo,
252 TrafficScheds: trafficSched}); err != nil {
253 log.Errorw("Failed to create traffic schedulers", log.Fields{"error": err})
254 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
255 }
256
257 if trafficSched = getTrafficSched(subs, tp_pb.Direction_UPSTREAM); trafficSched == nil {
258 log.Error("us-traffic-sched-is-nil")
259 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
260 }
261
262 log.Debugw("Sending Traffic scheduler create to device",
263 log.Fields{"Direction": tp_pb.Direction_UPSTREAM, "TrafficScheds": trafficSched})
264 if _, err := subs.OpenOltClient.CreateTrafficSchedulers(context.Background(), &tp_pb.TrafficSchedulers{
265 IntfId: subs.PonIntf, OnuId: subs.OnuID,
266 UniId: subs.UniID, PortNo: subs.UniPortNo,
267 TrafficScheds: trafficSched}); err != nil {
268 log.Errorw("Failed to create traffic schedulers", log.Fields{"error": err})
269 return errors.New(ReasonCodeToReasonString(SCHED_CREATION_FAILED))
270 }
271 return nil
272}
273
274func (tt TtWorkFlow) ProvisionQueues(subs *Subscriber) error {
275 log.Info("provisioning-queues")
276
277 var trafficQueues []*tp_pb.TrafficQueue
278 if trafficQueues = getTrafficQueues(subs, tp_pb.Direction_DOWNSTREAM); trafficQueues == nil {
279 log.Error("Failed to create traffic queues")
280 return errors.New(ReasonCodeToReasonString(QUEUE_CREATION_FAILED))
281 }
282
283 // On receiving the CreateTrafficQueues request, the driver should create corresponding
284 // downstream queues.
285 log.Debugw("Sending Traffic Queues create to device",
286 log.Fields{"Direction": tp_pb.Direction_DOWNSTREAM, "TrafficQueues": trafficQueues})
287 if _, err := subs.OpenOltClient.CreateTrafficQueues(context.Background(),
288 &tp_pb.TrafficQueues{IntfId: subs.PonIntf, OnuId: subs.OnuID,
289 UniId: subs.UniID, PortNo: subs.UniPortNo,
290 TrafficQueues: trafficQueues}); err != nil {
291 log.Errorw("Failed to create traffic queues in device", log.Fields{"error": err})
292 return errors.New(ReasonCodeToReasonString(QUEUE_CREATION_FAILED))
293 }
294
295 if trafficQueues = getTrafficQueues(subs, tp_pb.Direction_UPSTREAM); trafficQueues == nil {
296 log.Error("Failed to create traffic queues")
297 return errors.New(ReasonCodeToReasonString(QUEUE_CREATION_FAILED))
298 }
299
300 // On receiving the CreateTrafficQueues request, the driver should create corresponding
301 // upstream queues.
302 log.Debugw("Sending Traffic Queues create to device",
303 log.Fields{"Direction": tp_pb.Direction_UPSTREAM, "TrafficQueues": trafficQueues})
304 if _, err := subs.OpenOltClient.CreateTrafficQueues(context.Background(),
305 &tp_pb.TrafficQueues{IntfId: subs.PonIntf, OnuId: subs.OnuID,
306 UniId: subs.UniID, PortNo: subs.UniPortNo,
307 TrafficQueues: trafficQueues}); err != nil {
308 log.Errorw("Failed to create traffic queues in device", log.Fields{"error": err})
309 return errors.New(ReasonCodeToReasonString(QUEUE_CREATION_FAILED))
310 }
311
312 return nil
313}
314
315func (tt TtWorkFlow) ProvisionEapFlow(subs *Subscriber) error {
316 log.Info("tt-workflow-does-not-support-eap-yet--nothing-to-do")
317 return nil
318}
319
320func (tt TtWorkFlow) ProvisionDhcpIPV4Flow(subs *Subscriber) error {
321 log.Info("tt-workflow-does-not-require-dhcp-ipv4-yet--nothing-to-do")
322 return nil
323}
324
325func (tt TtWorkFlow) ProvisionDhcpIPV6Flow(subs *Subscriber) error {
326 log.Info("tt-workflow-does-not-require-dhcp-ipv6-support--nothing-to-do")
327 return nil
328}
329
330func (tt TtWorkFlow) ProvisionIgmpFlow(subs *Subscriber) error {
331 log.Info("tt-workflow-does-not-require-igmp-support--nothing-to-do")
332 return nil
333}
334
335func (tt TtWorkFlow) ProvisionHsiaFlow(subs *Subscriber) error {
336 var err error
337 var flowID []uint32
338 var gemPortIDs []uint32
339
340 var allocID = subs.TpInstance[subs.TestConfig.TpIDList[0]].UsScheduler.AllocID
341 for _, gem := range subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList {
342 gemPortIDs = append(gemPortIDs, gem.GemportID)
343 }
344
345 for idx, gemID := range gemPortIDs {
346 pBitMap := subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList[idx].PbitMap
347 for pos, pbitSet := range strings.TrimPrefix(pBitMap, "0b") {
348 if pbitSet == '1' {
349 pcp := uint32(len(strings.TrimPrefix(pBitMap, "0b"))) - 1 - uint32(pos)
350 if flowID, err = subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].GetResourceID(context.Background(), uint32(subs.PonIntf),
351 ponresourcemanager.FLOW_ID, 1); err != nil {
352 return errors.New(ReasonCodeToReasonString(FLOW_ID_GENERATION_FAILED))
353 } else {
354 var errUs, errDs error
355 if errUs = AddTtFlow(subs, HsiaFlow, Upstream, flowID[0], allocID, gemID, pcp); errUs != nil {
356 log.Errorw("failed to install US HSIA flow",
357 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
358 }
359 if errDs = AddTtFlow(subs, HsiaFlow, Downstream, flowID[0], allocID, gemID, pcp); errDs != nil {
360 log.Errorw("failed to install DS HSIA flow",
361 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
362 }
363 if errUs != nil && errDs != nil {
364 subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].FreeResourceID(context.Background(), uint32(subs.PonIntf),
365 ponresourcemanager.FLOW_ID, flowID)
366 }
367 if errUs != nil || errDs != nil {
368 if errUs != nil {
369 return errUs
370 }
371 return errDs
372 }
373 }
374 }
375 }
376 }
377 return nil
378}
379
380func (tt TtWorkFlow) ProvisionVoipFlow(subs *Subscriber) error {
381 var err error
382 var flowID []uint32
383 var gemPortIDs []uint32
384
385 var allocID = subs.TpInstance[subs.TestConfig.TpIDList[0]].UsScheduler.AllocID
386 for _, gem := range subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList {
387 gemPortIDs = append(gemPortIDs, gem.GemportID)
388 }
389
390 for idx, gemID := range gemPortIDs {
391 pBitMap := subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList[idx].PbitMap
392 for pos, pbitSet := range strings.TrimPrefix(pBitMap, "0b") {
393 if pbitSet == '1' {
394 pcp := uint32(len(strings.TrimPrefix(pBitMap, "0b"))) - 1 - uint32(pos)
395 if flowID, err = subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].GetResourceID(context.Background(), uint32(subs.PonIntf),
396 ponresourcemanager.FLOW_ID, 1); err != nil {
397 return errors.New(ReasonCodeToReasonString(FLOW_ID_GENERATION_FAILED))
398 } else {
399 var errUs, errDs, errDhcp error
400 if errUs = AddTtFlow(subs, VoipFlow, Upstream, flowID[0], allocID, gemID, pcp); errUs != nil {
401 log.Errorw("failed to install US VOIP flow",
402 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
403 }
404 if errDs = AddTtFlow(subs, VoipFlow, Downstream, flowID[0], allocID, gemID, pcp); errDs != nil {
405 log.Errorw("failed to install DS VOIP flow",
406 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
407 }
408 if errDhcp = AddFlow(subs, DhcpFlowIPV4, Upstream, flowID[0], allocID, gemID, pcp); errDhcp != nil {
409 log.Errorw("failed to install US VOIP-DHCP flow",
410 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
411 }
412 if errUs != nil && errDs != nil && errDhcp != nil {
413 subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].FreeResourceID(context.Background(), uint32(subs.PonIntf),
414 ponresourcemanager.FLOW_ID, flowID)
415 }
416 if errUs != nil || errDs != nil || errDhcp != nil {
417 if errUs != nil {
418 return errUs
419 }
420 if errDs != nil {
421 return errDs
422 }
423 return errDhcp
424 }
425 }
426 }
427 }
428 }
429 return nil
430}
431
432func (tt TtWorkFlow) ProvisionVodFlow(subs *Subscriber) error {
433 var err error
434 var flowID []uint32
435 var gemPortIDs []uint32
436
437 var allocID = subs.TpInstance[subs.TestConfig.TpIDList[0]].UsScheduler.AllocID
438 for _, gem := range subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList {
439 gemPortIDs = append(gemPortIDs, gem.GemportID)
440 }
441
442 for idx, gemID := range gemPortIDs {
443 pBitMap := subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList[idx].PbitMap
444 for pos, pbitSet := range strings.TrimPrefix(pBitMap, "0b") {
445 if pbitSet == '1' {
446 pcp := uint32(len(strings.TrimPrefix(pBitMap, "0b"))) - 1 - uint32(pos)
447 if flowID, err = subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].GetResourceID(context.Background(), uint32(subs.PonIntf),
448 ponresourcemanager.FLOW_ID, 1); err != nil {
449 return errors.New(ReasonCodeToReasonString(FLOW_ID_GENERATION_FAILED))
450 } else {
451 var errUs, errDs, errDhcp, errIgmp error
452 if errUs = AddTtFlow(subs, VodFlow, Upstream, flowID[0], allocID, gemID, pcp); errUs != nil {
453 log.Errorw("failed to install US VOIP flow",
454 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
455 }
456 if errDs = AddTtFlow(subs, VodFlow, Downstream, flowID[0], allocID, gemID, pcp); errDs != nil {
457 log.Errorw("failed to install DS VOIP flow",
458 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
459 }
460 if errDhcp = AddFlow(subs, DhcpFlowIPV4, Upstream, flowID[0], allocID, gemID, pcp); errDhcp != nil {
461 log.Errorw("failed to install US VOIP-DHCP flow",
462 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
463 }
464 if errIgmp = AddTtFlow(subs, IgmpFlow, Upstream, flowID[0], allocID, gemID, pcp); errIgmp != nil {
465 log.Errorw("failed to install US VOIP-IGMP flow",
466 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
467 }
468 if errUs != nil && errDs != nil && errDhcp != nil && errIgmp != nil {
469 subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].FreeResourceID(context.Background(), uint32(subs.PonIntf),
470 ponresourcemanager.FLOW_ID, flowID)
471 }
472 if errUs != nil || errDs != nil || errDhcp != nil || errIgmp != nil {
473 if errUs != nil {
474 return errUs
475 }
476 if errDs != nil {
477 return errDs
478 }
479 if errDhcp != nil {
480 return errDhcp
481 }
482 return errIgmp
483 }
484 }
485 }
486 }
487 }
488 return nil
489}
490
491func (tt TtWorkFlow) ProvisionMgmtFlow(subs *Subscriber) error {
492 var err error
493 var flowID []uint32
494 var gemPortIDs []uint32
495
496 var allocID = subs.TpInstance[subs.TestConfig.TpIDList[0]].UsScheduler.AllocID
497 for _, gem := range subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList {
498 gemPortIDs = append(gemPortIDs, gem.GemportID)
499 }
500
501 for idx, gemID := range gemPortIDs {
502 pBitMap := subs.TpInstance[subs.TestConfig.TpIDList[0]].UpstreamGemPortAttributeList[idx].PbitMap
503 for pos, pbitSet := range strings.TrimPrefix(pBitMap, "0b") {
504 if pbitSet == '1' {
505 pcp := uint32(len(strings.TrimPrefix(pBitMap, "0b"))) - 1 - uint32(pos)
506 if flowID, err = subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].GetResourceID(context.Background(), uint32(subs.PonIntf),
507 ponresourcemanager.FLOW_ID, 1); err != nil {
508 return errors.New(ReasonCodeToReasonString(FLOW_ID_GENERATION_FAILED))
509 } else {
510 var errUs, errDs, errDhcp error
511 if errUs = AddTtFlow(subs, MgmtFlow, Upstream, flowID[0], allocID, gemID, pcp); errUs != nil {
512 log.Errorw("failed to install US MGMT flow",
513 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
514 }
515 if errDs = AddTtFlow(subs, MgmtFlow, Downstream, flowID[0], allocID, gemID, pcp); errDs != nil {
516 log.Errorw("failed to install DS MGMT flow",
517 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
518 }
519 if errDhcp = AddFlow(subs, DhcpFlowIPV4, Upstream, flowID[0], allocID, gemID, pcp); errDhcp != nil {
520 log.Errorw("failed to install US MGMT-DHCP flow",
521 log.Fields{"onuID": subs.OnuID, "uniID": subs.UniID, "intf": subs.PonIntf})
522 }
523 if errUs != nil && errDs != nil && errDhcp != nil {
524 subs.RsrMgr.ResourceMgrs[uint32(subs.PonIntf)].FreeResourceID(context.Background(), uint32(subs.PonIntf),
525 ponresourcemanager.FLOW_ID, flowID)
526 }
527 if errUs != nil || errDs != nil || errDhcp != nil {
528 if errUs != nil {
529 return errUs
530 }
531 if errDs != nil {
532 return errDs
533 }
534 return errDhcp
535 }
536 }
537 }
538 }
539 }
540 return nil
541}
542
543func (tt TtWorkFlow) ProvisionMulticastFlow(subs *Subscriber) error {
544 var grp GroupData
545 var err error
546
547 numOfONUsPerPon := uint32(subs.TestConfig.NumOfOnu / uint(subs.RsrMgr.deviceInfo.GetPonPorts()))
548
549 grp.Subs = *subs
550 grp.Weight = 20
551 grp.Priority = 0
552 grp.OnuID = 6666
553 grp.UniID = 6666
554 grp.AllocID = 0
555 grp.GemPortID = 4069
556 grp.SchedPolicy = tp_pb.SchedulingPolicy_WRR
557
558 log.Debugw("Group data", log.Fields{"OnuID": subs.OnuID, "GroupID": grp.GroupID, "numOfONUsPerPon": numOfONUsPerPon})
559
560 grp.GroupID = subs.OnuID
561
562 if subs.PonIntf == 0 {
563 grp.AddGroup = true
564 grp.AddFlow = true
565 } else {
566 grp.AddFlow = false
567 grp.AddGroup = false
568 }
569
570 if subs.PonIntf == atomic.LoadUint32(lastPonIntf) {
571 _ = atomic.AddUint32(lastPonIntf, 1)
572 grp.AddSched = true
573 grp.AddQueue = true
574 } else {
575 grp.AddSched = false
576 grp.AddQueue = false
577 }
578
579 grp.AddMember = true
580
581 err = AddMulticastQueueFlow(&grp)
582
583 if err != nil {
584 log.Errorw("Failed to add multicast flow", log.Fields{"error": err})
585 }
586
587 return err
588}