blob: 4077e05911ab58e74485a41bd905477a4db03dce [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
17//Package adaptercore provides the utility for olt devices, flows and statistics
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053018package adaptercore
Girish Gowdru0c588b22019-04-23 23:24:56 -040019
20import (
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -040021 "errors"
22 "github.com/opencord/voltha-go/rw_core/utils"
Scott Bakerf8424cc2019-10-18 11:26:50 -070023 "github.com/opencord/voltha-lib-go/pkg/log"
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -040024 ofp "github.com/opencord/voltha-protos/go/openflow_13"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070025 "github.com/opencord/voltha-protos/go/voltha"
Girish Gowdru0c588b22019-04-23 23:24:56 -040026)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053027
28/*=====================================================================
29
30Flow id
31
32 Identifies a flow within a single OLT
33 Flow Id is unique per OLT
34 Multiple GEM ports can map to same flow id
35
36 13 11 4 0
37 +--------+--------------+------+
38 | pon id | onu id | Flow |
39 | | | idx |
40 +--------+--------------+------+
41
42 14 bits = 16384 flows (per OLT).
43
44 pon id = 4 bits = 16 PON ports
45 onu id = 7 bits = 128 ONUss per PON port
46 Flow index = 3 bits = 4 bi-directional flows per ONU
47 = 8 uni-directional flows per ONU
48
49
50Logical (OF) UNI port number
51
52 OpenFlow port number corresponding to PON UNI
53
54 15 11 4 0
55 +--+--------+--------------+------+
56 |0 | pon id | onu id | 0 |
57 +--+--------+--------------+------+
58
59 pon id = 4 bits = 16 PON ports
60 onu id = 7 bits = 128 ONUs per PON port
61
62Logical (OF) NNI port number
63
64 OpenFlow port number corresponding to PON UNI
65
66 16 0
67 +--+----------------------------+
68 |1 | intf_id |
69 +--+----------------------------+
70
71 No overlap with UNI port number space
72
73
74PON OLT (OF) port number
75
76 OpenFlow port number corresponding to PON OLT ports
77
78 31 28 0
79 +--------+------------------------~~~------+
80 | 0x2 | pon intf id |
81 +--------+------------------------~~~------+
82*/
83
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070084//MaxOnusPerPon value
gerardo.laurenzi72c84382019-07-11 15:03:46 +000085var MaxOnusPerPon = 128
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053086
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070087//MinUpstreamPortID value
88var MinUpstreamPortID = 0xfffd
manikkaraj k17652a72019-05-06 09:06:36 -040089
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070090//MaxUpstreamPortID value
91var MaxUpstreamPortID = 0xfffffffd
92
93var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
94
95//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
96func MkUniPortNum(intfID, onuID, uniID uint32) uint32 {
gerardo.laurenzi72c84382019-07-11 15:03:46 +000097 var limit = int(onuID)
98 if limit > MaxOnusPerPon {
99 log.Warn("Warning: exceeded the MAX ONUS per PON")
100 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700101 return (intfID << 11) | (onuID << 4) | uniID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530102}
103
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700104//OnuIDFromPortNum returns ONUID derived from portNumber
105func OnuIDFromPortNum(portNum uint32) uint32 {
106 return (portNum >> 4) & 127
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530107}
108
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700109//IntfIDFromUniPortNum returns IntfID derived from portNum
110func IntfIDFromUniPortNum(portNum uint32) uint32 {
111 return (portNum >> 11) & 15
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530112}
113
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114//UniIDFromPortNum return UniID derived from portNum
115func UniIDFromPortNum(portNum uint32) uint32 {
116 return (portNum) & 0xF
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530117}
118
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700119//IntfIDToPortNo returns portId derived from intftype, intfId and portType
120func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400121 if (intfType) == voltha.Port_ETHERNET_NNI {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700122 return (1 << 16) | intfID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530123 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700124 if (intfType) == voltha.Port_PON_OLT {
125 return (2 << 28) | intfID
126 }
127 return 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530128}
129
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700130//IntfIDFromNniPortNum returns Intf ID derived from portNum
131func IntfIDFromNniPortNum(portNum uint32) uint32 {
132 return portNum & 0xFFFF
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530133}
134
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700135//IntfIDToPortTypeName returns port type derived from the intfId
136func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
137 if ((2 << 28) ^ intfID) < 16 {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530138 return voltha.Port_PON_OLT
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530139 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700140 if (intfID & (1 << 16)) == (1 << 16) {
141 return voltha.Port_ETHERNET_NNI
142 }
143 return voltha.Port_ETHERNET_UNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530144}
145
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700146//ExtractAccessFromFlow returns AccessDevice information
147func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400148 if IsUpstream(outPort) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700149 return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530150 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700151 return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530152}
153
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700154//IsUpstream returns true for Upstream and false for downstream
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530155func IsUpstream(outPort uint32) bool {
manikkaraj k17652a72019-05-06 09:06:36 -0400156 for _, port := range controllerPorts {
157 if port == outPort {
158 return true
159 }
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530160 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700161 return (outPort & (1 << 16)) == (1 << 16)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530162}
manikkaraj k17652a72019-05-06 09:06:36 -0400163
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700164//IsControllerBoundFlow returns true/false
manikkaraj k17652a72019-05-06 09:06:36 -0400165func IsControllerBoundFlow(outPort uint32) bool {
166 for _, port := range controllerPorts {
167 if port == outPort {
168 return true
169 }
170 }
171 return false
172}
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400173
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700174//OnuIDFromUniPortNum returns onuId from give portNum information.
175func OnuIDFromUniPortNum(portNum uint32) uint32 {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400176 return (portNum >> 4) & 0x7F
177}
178
Humera Kouser94d7a842019-08-25 19:04:32 -0400179//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
180func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700181 var uniPortNo uint32
182 var ponIntf uint32
183 var onuID uint32
184 var uniID uint32
Humera Kouser94d7a842019-08-25 19:04:32 -0400185 var inPort uint32
186 var ethType uint32
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400187
188 if flowDirection == "upstream" {
189 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
190 for _, field := range utils.GetOfbFields(flow) {
191 if field.GetType() == utils.IN_PORT {
192 uniPortNo = field.GetPort()
193 break
194 }
195 }
196 }
197 } else if flowDirection == "downstream" {
198 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
Humera Kouser94d7a842019-08-25 19:04:32 -0400199 for _, field := range utils.GetOfbFields(flow) {
200 if field.GetType() == utils.METADATA {
201 for _, action := range utils.GetActions(flow) {
202 if action.Type == utils.OUTPUT {
203 if out := action.GetOutput(); out != nil {
204 uniPortNo = out.GetPort()
205 }
206 break
207 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400208 }
Humera Kouser94d7a842019-08-25 19:04:32 -0400209 } else if field.GetType() == utils.IN_PORT {
210 inPort = field.GetPort()
211 } else if field.GetType() == utils.ETH_TYPE {
212 ethType = field.GetEthType()
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400213 }
214 }
215 }
216 }
217
218 if uniPortNo == 0 {
Humera Kouser94d7a842019-08-25 19:04:32 -0400219 return 0, 0, 0, 0, 0, 0, errors.New("failed to extract Pon Interface, ONU Id and Uni Id from flow")
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400220 }
221
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700222 ponIntf = IntfIDFromUniPortNum(uniPortNo)
223 onuID = OnuIDFromUniPortNum(uniPortNo)
224 uniID = UniIDFromPortNum(uniPortNo)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400225
Humera Kouser94d7a842019-08-25 19:04:32 -0400226 return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400227}