blob: 6ad3e7beaedb1b54722cf6e9e58303519371c935 [file] [log] [blame]
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +00001/*
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
Himani Chawla4d908332020-08-31 12:30:20 +053017//Package adaptercoreonu provides the utility for onu devices, flows and statistics
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000018package adaptercoreonu
19
dbainbri4d3a0dc2020-12-02 00:33:42 +000020import "context"
21
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000022//Attention: this file is more or less a coopy of file olt_platform.go from the voltha-openolt-adapter
23// which includes system wide definitions and thus normally should be stored more centrally (within some voltha libs)!!
24
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000025/*=====================================================================
26
27@TODO: Looks like this Flow id concept below is not used anywhere
28 Propose to remove the below documentation of Flow Id on confirmation
29 of the same
30
31Flow id
32
33 Identifies a flow within a single OLT
34 Flow Id is unique per OLT
35 Multiple GEM ports can map to same flow id
36
37 13 11 4 0
38 +--------+--------------+------+
39 | pon id | onu id | Flow |
40 | | | idx |
41 +--------+--------------+------+
42
43 14 bits = 16384 flows (per OLT).
44
45 pon id = 4 bits = 16 PON ports
46 onu id = 7 bits = 128 ONUss per PON port
47 Flow index = 3 bits = 4 bi-directional flows per ONU
48 = 8 uni-directional flows per ONU
49
50
51Logical (OF) UNI port number
52
53 OpenFlow port number corresponding to PON UNI
54
55 20 12 4 0
56 +--+--------+--------------+------+
57 |0 | pon id | onu id |uni id|
58 +--+--------+--------------+------+
59
60 pon id = 8 bits = 256 PON ports
61 onu id = 8 bits = 256 ONUs per PON port
62
63Logical (OF) NNI port number
64
65 OpenFlow port number corresponding to PON NNI
66
67 20 0
68 +--+----------------------------+
69 |1 | intf_id |
70 +--+----------------------------+
71
72 No overlap with UNI port number space
73
74
75PON OLT (OF) port number
76
77 OpenFlow port number corresponding to PON OLT ports
78
79 31 28 0
80 +--------+------------------------~~~------+
81 | 0x2 | pon intf id |
82 +--------+------------------------~~~------+
83*/
84
85const (
86 // Number of bits for the physical UNI of the ONUs
87 bitsForUniID = 4
88 // Number of bits for the ONU ID
89 bitsForONUID = 8
90 // Number of bits for PON ID
91 bitsForPONID = 8
Himani Chawla4d908332020-08-31 12:30:20 +053092 /*
93 // Number of bits to differentiate between UNI and NNI Logical Port
94 bitsForUNINNIDiff = 1
95 */
Himani Chawla6d2ae152020-09-02 13:11:20 +053096 //maxOnusPerPon is Max number of ONUs on any PON port
97 maxOnusPerPon = (1 << bitsForONUID)
98 //maxPonsPerOlt is Max number of PON ports on any OLT
99 maxPonsPerOlt = (1 << bitsForPONID)
100 //maxUnisPerOnu is the Max number of UNI ports on any ONU
101 maxUnisPerOnu = (1 << bitsForUniID)
102 /*
103 //Bit position where the differentiation bit is located
104 nniUniDiffPos = (bitsForUniID + bitsForONUID + bitsForPONID)
105 //Bit position where the marker for PON port type of OF port is present
106 ponIntfMarkerPos = 28
107 //Value of marker used to distinguish PON port type of OF port
108 ponIntfMarkerValue = 0x2
109 // Number of bits for NNI ID
110 bitsforNNIID = 20
111 // minNniIntPortNum is used to store start range of nni port number (1 << 20) 1048576
112 minNniIntPortNum = (1 << bitsforNNIID)
113 // maxNniPortNum is used to store the maximum range of nni port number ((1 << 21)-1) 2097151
114 maxNniPortNum = ((1 << (bitsforNNIID + 1)) - 1)
115 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000116)
117
Himani Chawla6d2ae152020-09-02 13:11:20 +0530118/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000119//MinUpstreamPortID value
Himani Chawla6d2ae152020-09-02 13:11:20 +0530120var minUpstreamPortID = 0xfffd
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000121
122//MaxUpstreamPortID value
Himani Chawla6d2ae152020-09-02 13:11:20 +0530123var maxUpstreamPortID = 0xfffffffd
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000124
125var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530126*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000127
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000128//mkUniPortNum returns new UNIportNum based on intfID, onuID and uniID
dbainbri4d3a0dc2020-12-02 00:33:42 +0000129func mkUniPortNum(ctx context.Context, intfID, onuID, uniID uint32) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000130 //extended for checks available in the python onu adapter:!!
131 var limit = int(intfID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530132 if limit > maxPonsPerOlt {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000133 logger.Warn(ctx, "Warning: exceeded the MAX pons per OLT")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000134 }
135 limit = int(onuID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530136 if limit > maxOnusPerPon {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000137 logger.Warn(ctx, "Warning: exceeded the MAX ONUS per PON")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000138 }
139 limit = int(uniID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530140 if limit > maxUnisPerOnu {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000141 logger.Warn(ctx, "Warning: exceeded the MAX UNIS per ONU")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000142 }
143 return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
144}
145
Himani Chawla6d2ae152020-09-02 13:11:20 +0530146/*
147//onuIDFromPortNum returns ONUID derived from portNumber
148func onuIDFromPortNum(portNum uint32) uint32 {
149 return (portNum >> bitsForUniID) & (maxOnusPerPon - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000150}
151
Himani Chawla6d2ae152020-09-02 13:11:20 +0530152//intfIDFromUniPortNum returns IntfID derived from portNum
153func intfIDFromUniPortNum(portNum uint32) uint32 {
154 return (portNum >> (bitsForUniID + bitsForONUID)) & (maxPonsPerOlt - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000155}
156
Himani Chawla6d2ae152020-09-02 13:11:20 +0530157//uniIDFromPortNum return UniID derived from portNum
158func uniIDFromPortNum(portNum uint32) uint32 {
159 return (portNum) & (maxUnisPerOnu - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000160}
161
Himani Chawla6d2ae152020-09-02 13:11:20 +0530162//intfIDToPortNo returns portId derived from intftype, intfId and portType
163func intfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000164 if (intfType) == voltha.Port_ETHERNET_NNI {
165 return (1 << nniUniDiffPos) | intfID
166 }
167 if (intfType) == voltha.Port_PON_OLT {
168 return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
169 }
170 return 0
171}
172
Himani Chawla6d2ae152020-09-02 13:11:20 +0530173//portNoToIntfID returns portnumber derived from interfaceID
174func portNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000175 if (intfType) == voltha.Port_ETHERNET_NNI {
176 return (1 << nniUniDiffPos) ^ portno
177 }
178 if (intfType) == voltha.Port_PON_OLT {
179 return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
180 }
181 return 0
182}
183
Himani Chawla6d2ae152020-09-02 13:11:20 +0530184//intfIDFromNniPortNum returns Intf ID derived from portNum
185func intfIDFromNniPortNum(portNum uint32) (uint32, error) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000186 if portNum < minNniIntPortNum || portNum > maxNniPortNum {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000187 logger.Errorw(ctx,"NNIPortNumber is not in valid range", log.Fields{"portNum": portNum})
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000188 return uint32(0), errors.New("invalid-port-range") //olterrors.ErrInvalidPortRange
189 }
190 return (portNum & 0xFFFF), nil
191}
192
Himani Chawla6d2ae152020-09-02 13:11:20 +0530193//intfIDToPortTypeName returns port type derived from the intfId
194func intfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
195 if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < maxPonsPerOlt {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000196 return voltha.Port_PON_OLT
197 }
198 if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
199 return voltha.Port_ETHERNET_NNI
200 }
201 return voltha.Port_ETHERNET_UNI
202}
203
Himani Chawla6d2ae152020-09-02 13:11:20 +0530204//extractAccessFromFlow returns AccessDevice information
205func extractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
206 if isUpstream(outPort) {
207 return inPort, intfIDFromUniPortNum(inPort), onuIDFromPortNum(inPort), uniIDFromPortNum(inPort)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000208 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530209 return outPort, intfIDFromUniPortNum(outPort), onuIDFromPortNum(outPort), uniIDFromPortNum(outPort)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000210}
211
Himani Chawla6d2ae152020-09-02 13:11:20 +0530212//isUpstream returns true for Upstream and false for downstream
213func isUpstream(outPort uint32) bool {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000214 for _, port := range controllerPorts {
215 if port == outPort {
216 return true
217 }
218 }
219 return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
220}
221
Himani Chawla6d2ae152020-09-02 13:11:20 +0530222//isControllerBoundFlow returns true/false
223func isControllerBoundFlow(outPort uint32) bool {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000224 for _, port := range controllerPorts {
225 if port == outPort {
226 return true
227 }
228 }
229 return false
230}
231
Himani Chawla6d2ae152020-09-02 13:11:20 +0530232//onuIDFromUniPortNum returns onuId from give portNum information.
233func onuIDFromUniPortNum(portNum uint32) uint32 {
234 return (portNum >> bitsForUniID) & (maxOnusPerPon - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000235}
236
Himani Chawla6d2ae152020-09-02 13:11:20 +0530237//flowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
238func flowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000239 var uniPortNo uint32
240 var ponIntf uint32
241 var onuID uint32
242 var uniID uint32
243 var inPort uint32
244 var ethType uint32
245
246 if flowDirection == "upstream" {
247 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
248 for _, field := range flows.GetOfbFields(flow) {
249 if field.GetType() == flows.IN_PORT {
250 uniPortNo = field.GetPort()
251 break
252 }
253 }
254 }
255 } else if flowDirection == "downstream" {
256 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
257 for _, field := range flows.GetOfbFields(flow) {
258 if field.GetType() == flows.METADATA {
259 for _, action := range flows.GetActions(flow) {
260 if action.Type == flows.OUTPUT {
261 if out := action.GetOutput(); out != nil {
262 uniPortNo = out.GetPort()
263 }
264 break
265 }
266 }
267 } else if field.GetType() == flows.IN_PORT {
268 inPort = field.GetPort()
269 } else if field.GetType() == flows.ETH_TYPE {
270 ethType = field.GetEthType()
271 }
272 }
273 }
274 }
275
276 if uniPortNo == 0 {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530277 return 0, 0, 0, 0, 0, 0, errors.New("notFound: pon-interface (flowDirection)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000278 // olterrors.NewErrNotFound("pon-interface", log.Fields{"flow-direction": flowDirection}, nil)
279 }
280
Himani Chawla6d2ae152020-09-02 13:11:20 +0530281 ponIntf = intfIDFromUniPortNum(uniPortNo)
282 onuID = onuIDFromUniPortNum(uniPortNo)
283 uniID = uniIDFromPortNum(uniPortNo)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000284
dbainbri4d3a0dc2020-12-02 00:33:42 +0000285 logger.Debugw(ctx,"flow extract info result",
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000286 log.Fields{"uniPortNo": uniPortNo, "ponIntf": ponIntf,
287 "onuID": onuID, "uniID": uniID, "inPort": inPort, "ethType": ethType})
288
289 return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
290}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530291*/