blob: b5e8f361189710fe7608a21ec8d23c5aae32fde9 [file] [log] [blame]
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +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 */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070016
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
Girish Gowdru0c588b22019-04-23 23:24:56 -040019
20import (
Esin Karamanccb714b2019-11-29 15:02:06 +000021 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
22 "github.com/opencord/voltha-lib-go/v3/pkg/log"
Thomas Lee S94109f12020-03-03 16:39:29 +053023 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Esin Karamanccb714b2019-11-29 15:02:06 +000024 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
25 "github.com/opencord/voltha-protos/v3/go/voltha"
Girish Gowdru0c588b22019-04-23 23:24:56 -040026)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053027
28/*=====================================================================
29
Amit Ghoshd4cbe482019-11-21 12:07:14 +000030@TODO: Looks like this Flow id concept below is not used anywhere
31 Propose to remove the below documentation of Flow Id on confirmation
32 of the same
33
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053034Flow id
35
36 Identifies a flow within a single OLT
37 Flow Id is unique per OLT
38 Multiple GEM ports can map to same flow id
39
40 13 11 4 0
41 +--------+--------------+------+
42 | pon id | onu id | Flow |
43 | | | idx |
44 +--------+--------------+------+
45
46 14 bits = 16384 flows (per OLT).
47
48 pon id = 4 bits = 16 PON ports
49 onu id = 7 bits = 128 ONUss per PON port
50 Flow index = 3 bits = 4 bi-directional flows per ONU
51 = 8 uni-directional flows per ONU
52
53
54Logical (OF) UNI port number
55
56 OpenFlow port number corresponding to PON UNI
57
Amit Ghoshd4cbe482019-11-21 12:07:14 +000058 20 12 4 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053059 +--+--------+--------------+------+
Amit Ghoshd4cbe482019-11-21 12:07:14 +000060 |0 | pon id | onu id |uni id|
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053061 +--+--------+--------------+------+
62
Amit Ghoshd4cbe482019-11-21 12:07:14 +000063 pon id = 8 bits = 256 PON ports
64 onu id = 8 bits = 256 ONUs per PON port
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053065
66Logical (OF) NNI port number
67
Amit Ghoshd4cbe482019-11-21 12:07:14 +000068 OpenFlow port number corresponding to PON NNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053069
Amit Ghoshd4cbe482019-11-21 12:07:14 +000070 20 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053071 +--+----------------------------+
72 |1 | intf_id |
73 +--+----------------------------+
74
75 No overlap with UNI port number space
76
77
78PON OLT (OF) port number
79
80 OpenFlow port number corresponding to PON OLT ports
81
Amit Ghoshd4cbe482019-11-21 12:07:14 +000082 31 28 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053083 +--------+------------------------~~~------+
84 | 0x2 | pon intf id |
85 +--------+------------------------~~~------+
86*/
87
Amit Ghoshd4cbe482019-11-21 12:07:14 +000088const (
89 // Number of bits for the physical UNI of the ONUs
90 bitsForUniID = 4
91 // Number of bits for the ONU ID
92 bitsForONUID = 8
93 // Number of bits for PON ID
94 bitsForPONID = 8
95 // Number of bits to differentiate between UNI and NNI Logical Port
96 bitsForUNINNIDiff = 1
97 //MaxOnusPerPon is Max number of ONUs on any PON port
98 MaxOnusPerPon = (1 << bitsForONUID)
99 //MaxPonsPerOlt is Max number of PON ports on any OLT
100 MaxPonsPerOlt = (1 << bitsForPONID)
101 //MaxUnisPerOnu is the Max number of UNI ports on any ONU
102 MaxUnisPerOnu = (1 << bitsForUniID)
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
David K. Bainbridge794735f2020-02-11 21:01:37 -0800109 // 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)
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000115)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530116
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700117//MinUpstreamPortID value
118var MinUpstreamPortID = 0xfffd
manikkaraj k17652a72019-05-06 09:06:36 -0400119
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700120//MaxUpstreamPortID value
121var MaxUpstreamPortID = 0xfffffffd
122
123var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
124
125//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
126func MkUniPortNum(intfID, onuID, uniID uint32) uint32 {
gerardo.laurenzi72c84382019-07-11 15:03:46 +0000127 var limit = int(onuID)
128 if limit > MaxOnusPerPon {
Shrey Baid26912972020-04-16 21:02:31 +0530129 logger.Warn("exceeded-the-max-onus-per-pon")
gerardo.laurenzi72c84382019-07-11 15:03:46 +0000130 }
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000131 return (intfID << (bitsForUniID + bitsForONUID)) | (onuID << bitsForUniID) | uniID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530132}
133
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700134//OnuIDFromPortNum returns ONUID derived from portNumber
135func OnuIDFromPortNum(portNum uint32) uint32 {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000136 return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530137}
138
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700139//IntfIDFromUniPortNum returns IntfID derived from portNum
140func IntfIDFromUniPortNum(portNum uint32) uint32 {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000141 return (portNum >> (bitsForUniID + bitsForONUID)) & (MaxPonsPerOlt - 1)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530142}
143
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700144//UniIDFromPortNum return UniID derived from portNum
145func UniIDFromPortNum(portNum uint32) uint32 {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000146 return (portNum) & (MaxUnisPerOnu - 1)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530147}
148
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700149//IntfIDToPortNo returns portId derived from intftype, intfId and portType
150func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400151 if (intfType) == voltha.Port_ETHERNET_NNI {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000152 return (1 << nniUniDiffPos) | intfID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530153 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700154 if (intfType) == voltha.Port_PON_OLT {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000155 return (ponIntfMarkerValue << ponIntfMarkerPos) | intfID
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700156 }
157 return 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530158}
159
Naga Manjunath7615e552019-10-11 22:35:47 +0530160//PortNoToIntfID returns portnumber derived from interfaceID
161func PortNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
162 if (intfType) == voltha.Port_ETHERNET_NNI {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000163 return (1 << nniUniDiffPos) ^ portno
Naga Manjunath7615e552019-10-11 22:35:47 +0530164 }
165 if (intfType) == voltha.Port_PON_OLT {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000166 return (ponIntfMarkerValue << ponIntfMarkerPos) ^ portno
Naga Manjunath7615e552019-10-11 22:35:47 +0530167 }
168 return 0
169}
170
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700171//IntfIDFromNniPortNum returns Intf ID derived from portNum
David K. Bainbridge794735f2020-02-11 21:01:37 -0800172func IntfIDFromNniPortNum(portNum uint32) (uint32, error) {
173 if portNum < minNniIntPortNum || portNum > maxNniPortNum {
Shrey Baid26912972020-04-16 21:02:31 +0530174 logger.Errorw("nniportnumber-is-not-in-valid-range", log.Fields{"portnum": portNum})
Thomas Lee S94109f12020-03-03 16:39:29 +0530175 return uint32(0), olterrors.ErrInvalidPortRange
David K. Bainbridge794735f2020-02-11 21:01:37 -0800176 }
177 return (portNum & 0xFFFF), nil
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530178}
179
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700180//IntfIDToPortTypeName returns port type derived from the intfId
181func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000182 if ((ponIntfMarkerValue << ponIntfMarkerPos) ^ intfID) < MaxPonsPerOlt {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530183 return voltha.Port_PON_OLT
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530184 }
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000185 if (intfID & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700186 return voltha.Port_ETHERNET_NNI
187 }
188 return voltha.Port_ETHERNET_UNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530189}
190
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700191//ExtractAccessFromFlow returns AccessDevice information
192func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400193 if IsUpstream(outPort) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700194 return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530195 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700196 return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530197}
198
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700199//IsUpstream returns true for Upstream and false for downstream
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530200func IsUpstream(outPort uint32) bool {
manikkaraj k17652a72019-05-06 09:06:36 -0400201 for _, port := range controllerPorts {
202 if port == outPort {
203 return true
204 }
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530205 }
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000206 return (outPort & (1 << nniUniDiffPos)) == (1 << nniUniDiffPos)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530207}
manikkaraj k17652a72019-05-06 09:06:36 -0400208
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700209//IsControllerBoundFlow returns true/false
manikkaraj k17652a72019-05-06 09:06:36 -0400210func IsControllerBoundFlow(outPort uint32) bool {
211 for _, port := range controllerPorts {
212 if port == outPort {
213 return true
214 }
215 }
216 return false
217}
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400218
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700219//OnuIDFromUniPortNum returns onuId from give portNum information.
220func OnuIDFromUniPortNum(portNum uint32) uint32 {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000221 return (portNum >> bitsForUniID) & (MaxOnusPerPon - 1)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400222}
223
Humera Kouser94d7a842019-08-25 19:04:32 -0400224//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
225func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700226 var uniPortNo uint32
227 var ponIntf uint32
228 var onuID uint32
229 var uniID uint32
Humera Kouser94d7a842019-08-25 19:04:32 -0400230 var inPort uint32
231 var ethType uint32
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400232
233 if flowDirection == "upstream" {
Scott Baker355d1742019-10-24 10:57:52 -0700234 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
235 for _, field := range flows.GetOfbFields(flow) {
236 if field.GetType() == flows.IN_PORT {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400237 uniPortNo = field.GetPort()
238 break
239 }
240 }
241 }
242 } else if flowDirection == "downstream" {
Scott Baker355d1742019-10-24 10:57:52 -0700243 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
244 for _, field := range flows.GetOfbFields(flow) {
245 if field.GetType() == flows.METADATA {
246 for _, action := range flows.GetActions(flow) {
247 if action.Type == flows.OUTPUT {
Humera Kouser94d7a842019-08-25 19:04:32 -0400248 if out := action.GetOutput(); out != nil {
249 uniPortNo = out.GetPort()
250 }
251 break
252 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400253 }
Scott Baker355d1742019-10-24 10:57:52 -0700254 } else if field.GetType() == flows.IN_PORT {
Humera Kouser94d7a842019-08-25 19:04:32 -0400255 inPort = field.GetPort()
Scott Baker355d1742019-10-24 10:57:52 -0700256 } else if field.GetType() == flows.ETH_TYPE {
Humera Kouser94d7a842019-08-25 19:04:32 -0400257 ethType = field.GetEthType()
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400258 }
259 }
260 }
261 }
262
263 if uniPortNo == 0 {
Shrey Baid26912972020-04-16 21:02:31 +0530264 return 0, 0, 0, 0, 0, 0, olterrors.NewErrNotFound("pon-interface", log.Fields{"flow-direction": flowDirection}, nil)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400265 }
266
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700267 ponIntf = IntfIDFromUniPortNum(uniPortNo)
268 onuID = OnuIDFromUniPortNum(uniPortNo)
269 uniID = UniIDFromPortNum(uniPortNo)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400270
Shrey Baid26912972020-04-16 21:02:31 +0530271 logger.Debugw("flow-extract-info-result",
272 log.Fields{
273 "uniportno": uniPortNo,
274 "pon-intf": ponIntf,
275 "onu-id": onuID,
276 "uni-id": uniID,
277 "inport": inPort,
278 "ethtype": ethType})
Girish Gowdra3d633032019-12-10 16:37:05 +0530279
Humera Kouser94d7a842019-08-25 19:04:32 -0400280 return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400281}