blob: e078e6d3acaff00b5668b33f3e0d9d14fc0d7004 [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
22 "github.com/opencord/voltha-lib-go/v2/pkg/log"
23 oop "github.com/opencord/voltha-protos/v2/go/openolt"
24 tp_pb "github.com/opencord/voltha-protos/v2/go/tech_profile"
25 "golang.org/x/net/context"
26 "google.golang.org/grpc/codes"
27 "google.golang.org/grpc/status"
28)
29
30const (
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053031 DhcpIPProto = 17
Girish Gowdraef1b7c42020-01-23 16:27:48 +053032
33 //Constants utilised while forming HSIA Flow
34 HsiaFlow = "HSIA_FLOW"
35
36 //Constants utilised while forming DHCP IPV4 Flow
37 DhcpFlowIPV4 = "DHCP_FLOW_IPV4"
38 IPv4EthType = 0x800 //2048
39 DhcpSrcPortIPV4 = 68
40 DhcpDstPortIPV4 = 67
41
42 //Constants utilised while forming DHCP IPV6 Flow
43 DhcpFlowIPV6 = "DHCP_FLOW_IPV6"
44 IPv6EthType = 0x86dd //34525
45 DhcpSrcPortIPV6 = 547
46 DhcpDstPortIPV6 = 546
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +053047
48 //Constants utilised while forming EAPOL Flow
49 EapolFlow = "EAPOL_FLOW"
50 EapEthType = 0x888e //34958
51
52 //Direction constant
53 Upstream = "upstream"
54 Downstream = "downstream"
55
56 //PacketTagType constant
57 PacketTagType = "pkt_tag_type"
58 Untagged = "untagged"
59 SingleTag = "single_tag"
60 DoubleTag = "double_tag"
61)
62
63func getTrafficSched(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficScheduler {
64 var SchedCfg *tp_pb.SchedulerConfig
65
66 if direction == tp_pb.Direction_DOWNSTREAM {
67 SchedCfg = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
68 GetDsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
69
70 } else {
71 SchedCfg = subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
72 GetUsScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]])
73 }
74
75 // hard-code for now
76 cir := 16000
77 cbs := 5000
78 eir := 16000
79 ebs := 5000
80 pir := cir + eir
81 pbs := cbs + ebs
82
83 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: uint32(cir), Cbs: uint32(cbs), Pir: uint32(pir), Pbs: uint32(pbs)}
84
85 TrafficSched := []*tp_pb.TrafficScheduler{subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
86 GetTrafficScheduler(subs.TpInstance[subs.TestConfig.TpIDList[0]], SchedCfg, TrafficShaping)}
87
88 return TrafficSched
89}
90
91func getTrafficQueues(subs *Subscriber, direction tp_pb.Direction) []*tp_pb.TrafficQueue {
92
93 trafficQueues := subs.RsrMgr.ResourceMgrs[subs.PonIntf].TechProfileMgr.
94 GetTrafficQueues(subs.TpInstance[subs.TestConfig.TpIDList[0]], direction)
95
96 return trafficQueues
97}
98
99func FormatClassfierAction(flowType string, direction string, subs *Subscriber) (oop.Classifier, oop.Action) {
100 var flowClassifier oop.Classifier
101 var actionCmd oop.ActionCmd
102 var actionInfo oop.Action
103
104 if direction == Upstream {
105 switch flowType {
106 case EapolFlow:
107 flowClassifier.EthType = EapEthType
108 flowClassifier.OVid = subs.Ctag
109 flowClassifier.PktTagType = SingleTag
110 actionCmd.TrapToHost = true
111 actionInfo.Cmd = &actionCmd
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530112 case DhcpFlowIPV4:
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530113 flowClassifier.EthType = IPv4EthType
114 flowClassifier.IpProto = DhcpIPProto
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530115 flowClassifier.SrcPort = DhcpSrcPortIPV4
116 flowClassifier.DstPort = DhcpDstPortIPV4
117 flowClassifier.PktTagType = SingleTag
118 actionCmd.TrapToHost = true
119 actionInfo.Cmd = &actionCmd
120 case DhcpFlowIPV6:
121 flowClassifier.EthType = IPv6EthType
122 flowClassifier.IpProto = DhcpIPProto
123 flowClassifier.SrcPort = DhcpSrcPortIPV6
124 flowClassifier.DstPort = DhcpDstPortIPV6
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530125 flowClassifier.PktTagType = SingleTag
126 actionCmd.TrapToHost = true
127 actionInfo.Cmd = &actionCmd
128 case HsiaFlow:
129 flowClassifier.OVid = subs.Ctag
130 flowClassifier.PktTagType = SingleTag
131 actionCmd.AddOuterTag = true
132 actionInfo.Cmd = &actionCmd
133 actionInfo.OVid = subs.Stag
134 default:
135 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
136 "direction": direction})
137 }
138 } else if direction == Downstream {
139 switch flowType {
140 case EapolFlow:
141 log.Errorw("Downstream EAP flows are not required instead controller "+
142 "packet outs EAP response directly to onu in downstream", log.Fields{"flowtype": flowType,
143 "direction": direction})
Girish Gowdraef1b7c42020-01-23 16:27:48 +0530144 case DhcpFlowIPV4:
145 log.Errorw("Downstream DHCPIPV4 flows are not required instead we have "+
146 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
147 "direction": direction})
148 case DhcpFlowIPV6:
149 log.Errorw("Downstream DHCPIPV6 flows are not required instead we have "+
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530150 "NNI trap flows already installed", log.Fields{"flowtype": flowType,
151 "direction": direction})
152 case HsiaFlow:
153 flowClassifier.OVid = subs.Stag
154 flowClassifier.IVid = subs.Ctag
155 flowClassifier.PktTagType = DoubleTag
156 actionCmd.RemoveOuterTag = true
157 actionInfo.Cmd = &actionCmd
Girish Gowdra187322d2020-01-20 18:59:21 +0530158 actionInfo.OVid = subs.Stag
Thiyagarajan Subramanib83b0432020-01-08 13:43:28 +0530159 default:
160 log.Errorw("Unsupported flow type", log.Fields{"flowtype": flowType,
161 "direction": direction})
162 }
163 }
164 return flowClassifier, actionInfo
165}
166
167func AddFlow(subs *Subscriber, flowType string, direction string, flowID uint32,
168 allocID uint32, gemID uint32) error {
169 log.Infow("add-flow", log.Fields{"WorkFlow": subs.TestConfig.WorkflowName, "FlowType": flowType,
170 "direction": direction, "flowID": flowID})
171 var err error
172
173 flowClassifier, actionInfo := FormatClassfierAction(flowType, direction, subs)
174 flow := oop.Flow{AccessIntfId: int32(subs.PonIntf), OnuId: int32(subs.OnuID),
175 UniId: int32(subs.UniID), FlowId: flowID,
176 FlowType: direction, AllocId: int32(allocID), GemportId: int32(gemID),
177 Classifier: &flowClassifier, Action: &actionInfo,
178 Priority: 1000, PortNo: subs.UniPortNo}
179
180 _, err = subs.OpenOltClient.FlowAdd(context.Background(), &flow)
181
182 st, _ := status.FromError(err)
183 if st.Code() == codes.AlreadyExists {
184 log.Debugw("Flow already exists", log.Fields{"err": err, "deviceFlow": flow})
185 return nil
186 }
187
188 if err != nil {
189 log.Errorw("Failed to Add flow to device", log.Fields{"err": err, "deviceFlow": flow})
190 return errors.New(ReasonCodeToReasonString(FLOW_ADD_FAILED))
191 }
192 log.Debugw("Flow added to device successfully ", log.Fields{"flow": flow})
193
194 return nil
195}