blob: 656b8ec87348e2c58b4eaf22dd964a47f25ba30b [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"
21
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +053022 "github.com/opencord/openolt-scale-tester/config"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053023 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +053024 "github.com/opencord/voltha-lib-go/v2/pkg/ponresourcemanager"
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053025 oop "github.com/opencord/voltha-protos/v2/go/openolt"
26 tp_pb "github.com/opencord/voltha-protos/v2/go/tech_profile"
27 "golang.org/x/net/context"
28 "google.golang.org/grpc/codes"
29 "google.golang.org/grpc/status"
30)
31
32const (
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053033 DhcpIPProto = 17
Girish Gowdraef1b7c42020-01-23 16:27:48 +053034
35 //Constants utilised while forming HSIA Flow
36 HsiaFlow = "HSIA_FLOW"
37
38 //Constants utilised while forming DHCP IPV4 Flow
39 DhcpFlowIPV4 = "DHCP_FLOW_IPV4"
40 IPv4EthType = 0x800 //2048
41 DhcpSrcPortIPV4 = 68
42 DhcpDstPortIPV4 = 67
43
44 //Constants utilised while forming DHCP IPV6 Flow
45 DhcpFlowIPV6 = "DHCP_FLOW_IPV6"
46 IPv6EthType = 0x86dd //34525
47 DhcpSrcPortIPV6 = 547
48 DhcpDstPortIPV6 = 546
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053049
50 //Constants utilised while forming EAPOL Flow
51 EapolFlow = "EAPOL_FLOW"
52 EapEthType = 0x888e //34958
53
54 //Direction constant
55 Upstream = "upstream"
56 Downstream = "downstream"
57
58 //PacketTagType constant
59 PacketTagType = "pkt_tag_type"
60 Untagged = "untagged"
61 SingleTag = "single_tag"
62 DoubleTag = "double_tag"
63)
64
65func getTrafficSched(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficScheduler {
66 var SchedCfg *tp_pb.SchedulerConfig
67
68 if direction == tp_pb.Direction_DOWNSTREAM {
69 SchedCfg = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
70 GetDsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
71
72 } else {
73 SchedCfg = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
74 GetUsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
75 }
76
77 // hard-code for now
78 cir := 16000
79 cbs := 5000
80 eir := 16000
81 ebs := 5000
82 pir := cir + eir
83 pbs := cbs + ebs
84
85 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
86
87 TrafficSched := []*tp_pb.TrafficScheduler{subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
88 GetTrafficScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]], SchedCfg, TrafficShaping)}
89
90 return TrafficSched
91}
92
93func getTrafficQueues(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficQueue {
94
95 trafficQueues := subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
96 GetTrafficQueues(subs.TpInstance[subs.TestConfig.TpIDList[0]], direction)
97
98 return trafficQueues
99}
100
101func FormatClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
102 var flowClassifier oop.Classifier
103 var actionCmd oop.ActionCmd
104 var actionInfo oop.Action
105
106 if direction == Upstream {
107 switch flowType {
108 case EapolFlow:
109 flowClassifier.EthType = EapEthType
110 flowClassifier.OVid = subs.Ctag
111 flowClassifier.PktTagType = SingleTag
112 actionCmd.TrapToHost = true
113 actionInfo.Cmd = &actionCmd
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530114 case DhcpFlowIPV4:
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530115 flowClassifier.EthType = IPv4EthType
116 flowClassifier.IpProto = DhcpIPProto
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530117 flowClassifier.SrcPort = DhcpSrcPortIPV4
118 flowClassifier.DstPort = DhcpDstPortIPV4
119 flowClassifier.PktTagType = SingleTag
120 actionCmd.TrapToHost = true
121 actionInfo.Cmd = &actionCmd
122 case DhcpFlowIPV6:
123 flowClassifier.EthType = IPv6EthType
124 flowClassifier.IpProto = DhcpIPProto
125 flowClassifier.SrcPort = DhcpSrcPortIPV6
126 flowClassifier.DstPort = DhcpDstPortIPV6
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530127 flowClassifier.PktTagType = SingleTag
128 actionCmd.TrapToHost = true
129 actionInfo.Cmd = &actionCmd
130 case HsiaFlow:
131 flowClassifier.OVid = subs.Ctag
132 flowClassifier.PktTagType = SingleTag
133 actionCmd.AddOuterTag = true
134 actionInfo.Cmd = &actionCmd
135 actionInfo.OVid = subs.Stag
136 default:
137 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
138 "direction": direction})
139 }
140 } else if direction == Downstream {
141 switch flowType {
142 case EapolFlow:
143 log.Errorw("Downstream EAP flows are not required instead controller "+
144 "packet outs EAP response directly to onu in downstream", log.Fields{"flowtype": flowType,
145 "direction": direction})
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530146 case DhcpFlowIPV4:
147 log.Errorw("Downstream DHCPIPV4 flows are not required instead we have "+
148 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
149 "direction": direction})
150 case DhcpFlowIPV6:
151 log.Errorw("Downstream DHCPIPV6 flows are not required instead we have "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530152 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
153 "direction": direction})
154 case HsiaFlow:
155 flowClassifier.OVid = subs.Stag
156 flowClassifier.IVid = subs.Ctag
157 flowClassifier.PktTagType = DoubleTag
158 actionCmd.RemoveOuterTag = true
159 actionInfo.Cmd = &actionCmd
Girish Gowdra187322d2020-01-20 18:59:21 +0530160 actionInfo.OVid = subs.Stag
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530161 default:
162 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
163 "direction": direction})
164 }
165 }
166 return flowClassifier, actionInfo
167}
168
169func AddFlow(subs *Subscriber, flowType string, direction string, flowID uint32,
170 allocID uint32, gemID uint32) error {
171 log.Infow("add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
172 "direction": direction, "flowID": flowID})
173 var err error
174
175 flowClassifier, actionInfo := FormatClassfierAction(flowType, direction, subs)
176 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
177 UniId: int32(subs.UniID), FlowId: flowID,
178 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
179 Classifier: &flowClassifier, Action: &actionInfo,
180 Priority: 1000, PortNo: subs.UniPortNo}
181
182 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
183
184 st, _ := status.FromError(err)
185 if st.Code() == codes.AlreadyExists {
186 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
187 return nil
188 }
189
190 if err != nil {
191 log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
192 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
193 }
194 log.Debugw("Flow added to device successfully ", log.Fields{"flow": flow})
195
196 return nil
197}
Thiyagarajan Subramanic4f8da82020-02-05 16:08:26 +0530198
199func AddLldpFlow(oo oop.OpenoltClient, config *config.OpenOltScaleTesterConfig, rsrMgr *OpenOltResourceMgr) error {
200 var flowID []uint32
201 var err error
202
203 if flowID, err = rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].GetResourceID(uint32(config.NniIntfID),
204 ponresourcemanager.FLOW_ID, 1); err != nil {
205 return err
206 }
207
208 flowClassifier := &oop.Classifier{EthType: 35020, PktTagType: "untagged"}
209 actionCmd := &oop.ActionCmd{TrapToHost: true}
210 actionInfo := &oop.Action{Cmd: actionCmd}
211
212 flow := oop.Flow{AccessIntfId: -1, OnuId: -1, UniId: -1, FlowId: flowID[0],
213 FlowType: "downstream", AllocId: -1, GemportId: -1,
214 Classifier: flowClassifier, Action: actionInfo,
215 Priority: 1000, PortNo: uint32(config.NniIntfID)}
216
217 _, err = oo.FlowAdd(context.Background(), &flow)
218
219 st, _ := status.FromError(err)
220 if st.Code() == codes.AlreadyExists {
221 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
222 return nil
223 }
224
225 if err != nil {
226 log.Errorw("Failed to Add LLDP flow to device", log.Fields{"err": err, "deviceFlow": flow})
227 rsrMgr.ResourceMgrs[uint32(config.NniIntfID)].FreeResourceID(uint32(config.NniIntfID),
228 ponresourcemanager.FLOW_ID, flowID)
229 return err
230 }
231 log.Debugw("LLDP flow added to device successfully ", log.Fields{"flow": flow})
232
233 return nil
234}