blob: cd4c923999ea667b77a29f31eb636e7aa3b1ab17 [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
20//Attention: this file is more or less a coopy of file olt_platform.go from the voltha-openolt-adapter
21// which includes system wide definitions and thus normally should be stored more centrally (within some voltha libs)!!
22
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +000023/*=====================================================================
24
25@TODO: Looks like this Flow id concept below is not used anywhere
26 Propose to remove the below documentation of Flow Id on confirmation
27 of the same
28
29Flow id
30
31 Identifies a flow within a single OLT
32 Flow Id is unique per OLT
33 Multiple GEM ports can map to same flow id
34
35 13 11 4 0
36 +--------+--------------+------+
37 | pon id | onu id | Flow |
38 | | | idx |
39 +--------+--------------+------+
40
41 14 bits = 16384 flows (per OLT).
42
43 pon id = 4 bits = 16 PON ports
44 onu id = 7 bits = 128 ONUss per PON port
45 Flow index = 3 bits = 4 bi-directional flows per ONU
46 = 8 uni-directional flows per ONU
47
48
49Logical (OF) UNI port number
50
51 OpenFlow port number corresponding to PON UNI
52
53 20 12 4 0
54 +--+--------+--------------+------+
55 |0 | pon id | onu id |uni id|
56 +--+--------+--------------+------+
57
58 pon id = 8 bits = 256 PON ports
59 onu id = 8 bits = 256 ONUs per PON port
60
61Logical (OF) NNI port number
62
63 OpenFlow port number corresponding to PON NNI
64
65 20 0
66 +--+----------------------------+
67 |1 | intf_id |
68 +--+----------------------------+
69
70 No overlap with UNI port number space
71
72
73PON OLT (OF) port number
74
75 OpenFlow port number corresponding to PON OLT ports
76
77 31 28 0
78 +--------+------------------------~~~------+
79 | 0x2 | pon intf id |
80 +--------+------------------------~~~------+
81*/
82
83const (
84 // Number of bits for the physical UNI of the ONUs
85 bitsForUniID = 4
86 // Number of bits for the ONU ID
87 bitsForONUID = 8
88 // Number of bits for PON ID
89 bitsForPONID = 8
Himani Chawla4d908332020-08-31 12:30:20 +053090 /*
91 // Number of bits to differentiate between UNI and NNI Logical Port
92 bitsForUNINNIDiff = 1
93 */
Himani Chawla6d2ae152020-09-02 13:11:20 +053094 //maxOnusPerPon is Max number of ONUs on any PON port
95 maxOnusPerPon = (1 << bitsForONUID)
96 //maxPonsPerOlt is Max number of PON ports on any OLT
97 maxPonsPerOlt = (1 << bitsForPONID)
98 //maxUnisPerOnu is the Max number of UNI ports on any ONU
99 maxUnisPerOnu = (1 << bitsForUniID)
100 /*
101 //Bit position where the differentiation bit is located
102 nniUniDiffPos = (bitsForUniID + bitsForONUID + bitsForPONID)
103 //Bit position where the marker for PON port type of OF port is present
104 ponIntfMarkerPos = 28
105 //Value of marker used to distinguish PON port type of OF port
106 ponIntfMarkerValue = 0x2
107 // Number of bits for NNI ID
108 bitsforNNIID = 20
109 // minNniIntPortNum is used to store start range of nni port number (1 << 20) 1048576
110 minNniIntPortNum = (1 << bitsforNNIID)
111 // maxNniPortNum is used to store the maximum range of nni port number ((1 << 21)-1) 2097151
112 maxNniPortNum = ((1 << (bitsforNNIID + 1)) - 1)
113 */
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000114)
115
Holger Hildebrandtbe674422020-05-05 13:05:30 +0000116//Mask to indicate which possibly active ONU UNI state is really reported to the core
117// compare python code - at the moment restrict active state to the first ONU UNI port
118// check is limited to max 16 uni ports - cmp above UNI limit!!!
Himani Chawla6d2ae152020-09-02 13:11:20 +0530119var activeUniPortStateUpdateMask = 0x0001
Holger Hildebrandtbe674422020-05-05 13:05:30 +0000120
Himani Chawla6d2ae152020-09-02 13:11:20 +0530121/*
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000122//MinUpstreamPortID value
Himani Chawla6d2ae152020-09-02 13:11:20 +0530123var minUpstreamPortID = 0xfffd
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000124
125//MaxUpstreamPortID value
Himani Chawla6d2ae152020-09-02 13:11:20 +0530126var maxUpstreamPortID = 0xfffffffd
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000127
128var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530129*/
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000130
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000131//mkUniPortNum returns new UNIportNum based on intfID, onuID and uniID
Himani Chawla6d2ae152020-09-02 13:11:20 +0530132func mkUniPortNum(intfID, onuID, uniID uint32) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000133 //extended for checks available in the python onu adapter:!!
134 var limit = int(intfID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530135 if limit > maxPonsPerOlt {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000136 logger.Warn("Warning: exceeded the MAX pons per OLT")
137 }
138 limit = int(onuID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530139 if limit > maxOnusPerPon {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000140 logger.Warn("Warning: exceeded the MAX ONUS per PON")
141 }
142 limit = int(uniID)
Himani Chawla6d2ae152020-09-02 13:11:20 +0530143 if limit > maxUnisPerOnu {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000144 logger.Warn("Warning: exceeded the MAX UNIS per ONU")
145 }
146 return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
147}
148
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149/*
150//onuIDFromPortNum returns ONUID derived from portNumber
151func onuIDFromPortNum(portNum uint32) uint32 {
152 return (portNum >> bitsForUniID) & (maxOnusPerPon - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000153}
154
Himani Chawla6d2ae152020-09-02 13:11:20 +0530155//intfIDFromUniPortNum returns IntfID derived from portNum
156func intfIDFromUniPortNum(portNum uint32) uint32 {
157 return (portNum >> (bitsForUniID + bitsForONUID)) & (maxPonsPerOlt - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000158}
159
Himani Chawla6d2ae152020-09-02 13:11:20 +0530160//uniIDFromPortNum return UniID derived from portNum
161func uniIDFromPortNum(portNum uint32) uint32 {
162 return (portNum) & (maxUnisPerOnu - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000163}
164
Himani Chawla6d2ae152020-09-02 13:11:20 +0530165//intfIDToPortNo returns portId derived from intftype, intfId and portType
166func intfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000167 if (intfType) == voltha.Port_ETHERNET_NNI {
168 return (1 << nniUniDiffPos) | intfID
169 }
170 if (intfType) == voltha.Port_PON_OLT {
171 return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
172 }
173 return 0
174}
175
Himani Chawla6d2ae152020-09-02 13:11:20 +0530176//portNoToIntfID returns portnumber derived from interfaceID
177func portNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000178 if (intfType) == voltha.Port_ETHERNET_NNI {
179 return (1 << nniUniDiffPos) ^ portno
180 }
181 if (intfType) == voltha.Port_PON_OLT {
182 return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
183 }
184 return 0
185}
186
Himani Chawla6d2ae152020-09-02 13:11:20 +0530187//intfIDFromNniPortNum returns Intf ID derived from portNum
188func intfIDFromNniPortNum(portNum uint32) (uint32, error) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000189 if portNum < minNniIntPortNum || portNum > maxNniPortNum {
190 logger.Errorw("NNIPortNumber is not in valid range", log.Fields{"portNum": portNum})
191 return uint32(0), errors.New("invalid-port-range") //olterrors.ErrInvalidPortRange
192 }
193 return (portNum & 0xFFFF), nil
194}
195
Himani Chawla6d2ae152020-09-02 13:11:20 +0530196//intfIDToPortTypeName returns port type derived from the intfId
197func intfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
198 if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < maxPonsPerOlt {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000199 return voltha.Port_PON_OLT
200 }
201 if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
202 return voltha.Port_ETHERNET_NNI
203 }
204 return voltha.Port_ETHERNET_UNI
205}
206
Himani Chawla6d2ae152020-09-02 13:11:20 +0530207//extractAccessFromFlow returns AccessDevice information
208func extractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
209 if isUpstream(outPort) {
210 return inPort, intfIDFromUniPortNum(inPort), onuIDFromPortNum(inPort), uniIDFromPortNum(inPort)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000211 }
Himani Chawla6d2ae152020-09-02 13:11:20 +0530212 return outPort, intfIDFromUniPortNum(outPort), onuIDFromPortNum(outPort), uniIDFromPortNum(outPort)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000213}
214
Himani Chawla6d2ae152020-09-02 13:11:20 +0530215//isUpstream returns true for Upstream and false for downstream
216func isUpstream(outPort uint32) bool {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000217 for _, port := range controllerPorts {
218 if port == outPort {
219 return true
220 }
221 }
222 return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
223}
224
Himani Chawla6d2ae152020-09-02 13:11:20 +0530225//isControllerBoundFlow returns true/false
226func isControllerBoundFlow(outPort uint32) bool {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000227 for _, port := range controllerPorts {
228 if port == outPort {
229 return true
230 }
231 }
232 return false
233}
234
Himani Chawla6d2ae152020-09-02 13:11:20 +0530235//onuIDFromUniPortNum returns onuId from give portNum information.
236func onuIDFromUniPortNum(portNum uint32) uint32 {
237 return (portNum >> bitsForUniID) & (maxOnusPerPon - 1)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000238}
239
Himani Chawla6d2ae152020-09-02 13:11:20 +0530240//flowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
241func flowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000242 var uniPortNo uint32
243 var ponIntf uint32
244 var onuID uint32
245 var uniID uint32
246 var inPort uint32
247 var ethType uint32
248
249 if flowDirection == "upstream" {
250 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
251 for _, field := range flows.GetOfbFields(flow) {
252 if field.GetType() == flows.IN_PORT {
253 uniPortNo = field.GetPort()
254 break
255 }
256 }
257 }
258 } else if flowDirection == "downstream" {
259 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
260 for _, field := range flows.GetOfbFields(flow) {
261 if field.GetType() == flows.METADATA {
262 for _, action := range flows.GetActions(flow) {
263 if action.Type == flows.OUTPUT {
264 if out := action.GetOutput(); out != nil {
265 uniPortNo = out.GetPort()
266 }
267 break
268 }
269 }
270 } else if field.GetType() == flows.IN_PORT {
271 inPort = field.GetPort()
272 } else if field.GetType() == flows.ETH_TYPE {
273 ethType = field.GetEthType()
274 }
275 }
276 }
277 }
278
279 if uniPortNo == 0 {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530280 return 0, 0, 0, 0, 0, 0, errors.New("notFound: pon-interface (flowDirection)")
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000281 // olterrors.NewErrNotFound("pon-interface", log.Fields{"flow-direction": flowDirection}, nil)
282 }
283
Himani Chawla6d2ae152020-09-02 13:11:20 +0530284 ponIntf = intfIDFromUniPortNum(uniPortNo)
285 onuID = onuIDFromUniPortNum(uniPortNo)
286 uniID = uniIDFromPortNum(uniPortNo)
Holger Hildebrandt0f9b88d2020-04-20 13:33:25 +0000287
288 logger.Debugw("flow extract info result",
289 log.Fields{"uniPortNo": uniPortNo, "ponIntf": ponIntf,
290 "onuID": onuID, "uniID": uniID, "inPort": inPort, "ethType": ethType})
291
292 return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
293}
Himani Chawla6d2ae152020-09-02 13:11:20 +0530294*/