blob: 6f0d58c0b90bb88c7d9c15bf21c99b73a441a697 [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"
Scott Baker51290152019-10-24 14:23:20 -070022 "github.com/opencord/voltha-lib-go/v2/pkg/flows"
23 "github.com/opencord/voltha-lib-go/v2/pkg/log"
Scott Bakerc6e54cb2019-11-04 09:31:25 -080024 ofp "github.com/opencord/voltha-protos/v2/go/openflow_13"
25 "github.com/opencord/voltha-protos/v2/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
Naga Manjunath7615e552019-10-11 22:35:47 +0530130//PortNoToIntfID returns portnumber derived from interfaceID
131func PortNoToIntfID(portno uint32, intfType voltha.Port_PortType) uint32 {
132 if (intfType) == voltha.Port_ETHERNET_NNI {
133 return (1 << 16) ^ portno
134 }
135 if (intfType) == voltha.Port_PON_OLT {
136 return (2 << 28) ^ portno
137 }
138 return 0
139}
140
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700141//IntfIDFromNniPortNum returns Intf ID derived from portNum
142func IntfIDFromNniPortNum(portNum uint32) uint32 {
143 return portNum & 0xFFFF
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530144}
145
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700146//IntfIDToPortTypeName returns port type derived from the intfId
147func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
148 if ((2 << 28) ^ intfID) < 16 {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530149 return voltha.Port_PON_OLT
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530150 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700151 if (intfID & (1 << 16)) == (1 << 16) {
152 return voltha.Port_ETHERNET_NNI
153 }
154 return voltha.Port_ETHERNET_UNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530155}
156
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700157//ExtractAccessFromFlow returns AccessDevice information
158func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400159 if IsUpstream(outPort) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700160 return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530161 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700162 return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530163}
164
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700165//IsUpstream returns true for Upstream and false for downstream
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530166func IsUpstream(outPort uint32) bool {
manikkaraj k17652a72019-05-06 09:06:36 -0400167 for _, port := range controllerPorts {
168 if port == outPort {
169 return true
170 }
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530171 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700172 return (outPort & (1 << 16)) == (1 << 16)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530173}
manikkaraj k17652a72019-05-06 09:06:36 -0400174
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700175//IsControllerBoundFlow returns true/false
manikkaraj k17652a72019-05-06 09:06:36 -0400176func IsControllerBoundFlow(outPort uint32) bool {
177 for _, port := range controllerPorts {
178 if port == outPort {
179 return true
180 }
181 }
182 return false
183}
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400184
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700185//OnuIDFromUniPortNum returns onuId from give portNum information.
186func OnuIDFromUniPortNum(portNum uint32) uint32 {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400187 return (portNum >> 4) & 0x7F
188}
189
Humera Kouser94d7a842019-08-25 19:04:32 -0400190//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID, uniID, inPort and ethType
191func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, uint32, uint32, uint32, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700192 var uniPortNo uint32
193 var ponIntf uint32
194 var onuID uint32
195 var uniID uint32
Humera Kouser94d7a842019-08-25 19:04:32 -0400196 var inPort uint32
197 var ethType uint32
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400198
199 if flowDirection == "upstream" {
Scott Baker355d1742019-10-24 10:57:52 -0700200 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
201 for _, field := range flows.GetOfbFields(flow) {
202 if field.GetType() == flows.IN_PORT {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400203 uniPortNo = field.GetPort()
204 break
205 }
206 }
207 }
208 } else if flowDirection == "downstream" {
Scott Baker355d1742019-10-24 10:57:52 -0700209 if uniPortNo = flows.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
210 for _, field := range flows.GetOfbFields(flow) {
211 if field.GetType() == flows.METADATA {
212 for _, action := range flows.GetActions(flow) {
213 if action.Type == flows.OUTPUT {
Humera Kouser94d7a842019-08-25 19:04:32 -0400214 if out := action.GetOutput(); out != nil {
215 uniPortNo = out.GetPort()
216 }
217 break
218 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400219 }
Scott Baker355d1742019-10-24 10:57:52 -0700220 } else if field.GetType() == flows.IN_PORT {
Humera Kouser94d7a842019-08-25 19:04:32 -0400221 inPort = field.GetPort()
Scott Baker355d1742019-10-24 10:57:52 -0700222 } else if field.GetType() == flows.ETH_TYPE {
Humera Kouser94d7a842019-08-25 19:04:32 -0400223 ethType = field.GetEthType()
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400224 }
225 }
226 }
227 }
228
229 if uniPortNo == 0 {
Humera Kouser94d7a842019-08-25 19:04:32 -0400230 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 -0400231 }
232
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700233 ponIntf = IntfIDFromUniPortNum(uniPortNo)
234 onuID = OnuIDFromUniPortNum(uniPortNo)
235 uniID = UniIDFromPortNum(uniPortNo)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400236
Humera Kouser94d7a842019-08-25 19:04:32 -0400237 return uniPortNo, ponIntf, onuID, uniID, inPort, ethType, nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400238}