blob: 648db1dc5b0c8db3055f122e8272e3995c1c0522 [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 */
16package adaptercore
Girish Gowdru0c588b22019-04-23 23:24:56 -040017
18import (
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -040019 "errors"
20 "github.com/opencord/voltha-go/rw_core/utils"
21 ofp "github.com/opencord/voltha-protos/go/openflow_13"
Girish Gowdru0c588b22019-04-23 23:24:56 -040022 voltha "github.com/opencord/voltha-protos/go/voltha"
23)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053024
25/*=====================================================================
26
27Flow id
28
29 Identifies a flow within a single OLT
30 Flow Id is unique per OLT
31 Multiple GEM ports can map to same flow id
32
33 13 11 4 0
34 +--------+--------------+------+
35 | pon id | onu id | Flow |
36 | | | idx |
37 +--------+--------------+------+
38
39 14 bits = 16384 flows (per OLT).
40
41 pon id = 4 bits = 16 PON ports
42 onu id = 7 bits = 128 ONUss per PON port
43 Flow index = 3 bits = 4 bi-directional flows per ONU
44 = 8 uni-directional flows per ONU
45
46
47Logical (OF) UNI port number
48
49 OpenFlow port number corresponding to PON UNI
50
51 15 11 4 0
52 +--+--------+--------------+------+
53 |0 | pon id | onu id | 0 |
54 +--+--------+--------------+------+
55
56 pon id = 4 bits = 16 PON ports
57 onu id = 7 bits = 128 ONUs per PON port
58
59Logical (OF) NNI port number
60
61 OpenFlow port number corresponding to PON UNI
62
63 16 0
64 +--+----------------------------+
65 |1 | intf_id |
66 +--+----------------------------+
67
68 No overlap with UNI port number space
69
70
71PON OLT (OF) port number
72
73 OpenFlow port number corresponding to PON OLT ports
74
75 31 28 0
76 +--------+------------------------~~~------+
77 | 0x2 | pon intf id |
78 +--------+------------------------~~~------+
79*/
80
Girish Gowdru0c588b22019-04-23 23:24:56 -040081var MAX_ONUS_PER_PON = 32
82var MIN_UPSTREAM_PORT_ID = 0xfffd
83var MAX_UPSTREAM_PORT_ID = 0xfffffffd
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053084
manikkaraj k17652a72019-05-06 09:06:36 -040085var controllerPorts []uint32 = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
86
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053087func MkUniPortNum(intfId uint32, onuId uint32, uniId uint32) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -040088 /* TODO: Add checks */
89 return ((intfId << 11) | (onuId << 4) | uniId)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053090}
91
92func MkFlowId(intfId uint32, onuId uint32, idx uint32) uint32 {
93 return (((intfId << 9) | (onuId << 4)) | idx)
94}
95
96func OnuIdFromPortNum(portNum uint32) uint32 {
97 return ((portNum >> 4) & 127)
98}
99
100func IntfIdFromUniPortNum(portNum uint32) uint32 {
101 return ((portNum >> 11) & 15)
102}
103
104func UniIdFromPortNum(portNum uint32) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400105 return ((portNum) & 0xF)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530106}
107
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530108func IntfIdFromPonPortNo(portNo uint32) uint32 {
109 return (portNo & 15)
110}
111
112func IntfIdToPortNo(intfId uint32, intfType voltha.Port_PortType) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400113 if (intfType) == voltha.Port_ETHERNET_NNI {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530114 return ((1 << 16) | intfId)
115 } else {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400116 if (intfType) == voltha.Port_PON_OLT {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530117 return ((2 << 28) | intfId)
118 } else {
119 return 0
120 }
121 }
122}
123
124func IntfIdFromNniPortNum(portNum uint32) uint32 {
125 return (portNum & 0xFFFF)
126}
127
128func IntfIdToPortTypeName(intfId uint32) voltha.Port_PortType {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400129 if ((2 << 28) ^ intfId) < 16 {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530130 return voltha.Port_PON_OLT
131 } else {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400132 if (intfId & (1 << 16)) == (1 << 16) {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530133 return voltha.Port_ETHERNET_NNI
134 } else {
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400135 return voltha.Port_ETHERNET_UNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530136 }
137 }
138}
139
140func PortTypeNameByPortIndex(portIndex int32) string {
141 return voltha.Port_PortType_name[portIndex]
142}
143
144func ExtractAccessFromFlow(inPort uint32, outPort uint32) (uint32, uint32, uint32, uint32) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400145 if IsUpstream(outPort) {
146 return inPort, IntfIdFromUniPortNum(inPort), OnuIdFromPortNum(inPort), UniIdFromPortNum(inPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530147 } else {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400148 return outPort, IntfIdFromUniPortNum(outPort), OnuIdFromPortNum(outPort), UniIdFromPortNum(outPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530149 }
150}
151
152func IsUpstream(outPort uint32) bool {
manikkaraj k17652a72019-05-06 09:06:36 -0400153 for _, port := range controllerPorts {
154 if port == outPort {
155 return true
156 }
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530157 }
Girish Gowdru0c588b22019-04-23 23:24:56 -0400158 if (outPort & (1 << 16)) == (1 << 16) {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530159 return true
160 }
161 return false
162}
manikkaraj k17652a72019-05-06 09:06:36 -0400163
164func IsControllerBoundFlow(outPort uint32) bool {
165 for _, port := range controllerPorts {
166 if port == outPort {
167 return true
168 }
169 }
170 return false
171}
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400172
173func OnuIdFromUniPortNum(portNum uint32) uint32 {
174 return (portNum >> 4) & 0x7F
175}
176
177func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, error) {
178 var uniPortNo uint32 = 0
179 var ponIntf uint32 = 0
180 var onuId uint32 = 0
181 var uniId uint32 = 0
182
183 if flowDirection == "upstream" {
184 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
185 for _, field := range utils.GetOfbFields(flow) {
186 if field.GetType() == utils.IN_PORT {
187 uniPortNo = field.GetPort()
188 break
189 }
190 }
191 }
192 } else if flowDirection == "downstream" {
193 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
194 for _, action := range utils.GetActions(flow) {
195 if action.Type == utils.OUTPUT {
196 if out := action.GetOutput(); out != nil {
197 uniPortNo = out.GetPort()
198 }
199 break
200 }
201 }
202 }
203 }
204
205 if uniPortNo == 0 {
206 return 0, 0, 0, errors.New("Failed to extract Pon Interface, ONU Id and Uni Id from flow")
207 }
208
209 ponIntf = IntfIdFromUniPortNum(uniPortNo)
210 onuId = OnuIdFromUniPortNum(uniPortNo)
211 uniId = UniIdFromPortNum(uniPortNo)
212
213 return ponIntf, onuId, uniId, nil
214}