blob: 7f457dc6f94c556046b512040949eb3b4c8a9c5c [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"
23 ofp "github.com/opencord/voltha-protos/go/openflow_13"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070024 "github.com/opencord/voltha-protos/go/voltha"
Girish Gowdru0c588b22019-04-23 23:24:56 -040025)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053026
27/*=====================================================================
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 15 11 4 0
54 +--+--------+--------------+------+
55 |0 | pon id | onu id | 0 |
56 +--+--------+--------------+------+
57
58 pon id = 4 bits = 16 PON ports
59 onu id = 7 bits = 128 ONUs per PON port
60
61Logical (OF) NNI port number
62
63 OpenFlow port number corresponding to PON UNI
64
65 16 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
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070083//MaxOnusPerPon value
84var MaxOnusPerPon = 32
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053085
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070086//MinUpstreamPortID value
87var MinUpstreamPortID = 0xfffd
manikkaraj k17652a72019-05-06 09:06:36 -040088
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070089//MaxUpstreamPortID value
90var MaxUpstreamPortID = 0xfffffffd
91
92var controllerPorts = []uint32{0xfffd, 0x7ffffffd, 0xfffffffd}
93
94//MkUniPortNum returns new UNIportNum based on intfID, inuID and uniID
95func MkUniPortNum(intfID, onuID, uniID uint32) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -040096 /* TODO: Add checks */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070097 return (intfID << 11) | (onuID << 4) | uniID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +053098}
99
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700100//OnuIDFromPortNum returns ONUID derived from portNumber
101func OnuIDFromPortNum(portNum uint32) uint32 {
102 return (portNum >> 4) & 127
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530103}
104
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700105//IntfIDFromUniPortNum returns IntfID derived from portNum
106func IntfIDFromUniPortNum(portNum uint32) uint32 {
107 return (portNum >> 11) & 15
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530108}
109
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110//UniIDFromPortNum return UniID derived from portNum
111func UniIDFromPortNum(portNum uint32) uint32 {
112 return (portNum) & 0xF
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530113}
114
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700115//IntfIDToPortNo returns portId derived from intftype, intfId and portType
116func IntfIDToPortNo(intfID uint32, intfType voltha.Port_PortType) uint32 {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400117 if (intfType) == voltha.Port_ETHERNET_NNI {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700118 return (1 << 16) | intfID
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530119 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700120 if (intfType) == voltha.Port_PON_OLT {
121 return (2 << 28) | intfID
122 }
123 return 0
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530124}
125
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700126//IntfIDFromNniPortNum returns Intf ID derived from portNum
127func IntfIDFromNniPortNum(portNum uint32) uint32 {
128 return portNum & 0xFFFF
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530129}
130
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700131//IntfIDToPortTypeName returns port type derived from the intfId
132func IntfIDToPortTypeName(intfID uint32) voltha.Port_PortType {
133 if ((2 << 28) ^ intfID) < 16 {
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530134 return voltha.Port_PON_OLT
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530135 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700136 if (intfID & (1 << 16)) == (1 << 16) {
137 return voltha.Port_ETHERNET_NNI
138 }
139 return voltha.Port_ETHERNET_UNI
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530140}
141
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700142//ExtractAccessFromFlow returns AccessDevice information
143func ExtractAccessFromFlow(inPort, outPort uint32) (uint32, uint32, uint32, uint32) {
Girish Gowdru0c588b22019-04-23 23:24:56 -0400144 if IsUpstream(outPort) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700145 return inPort, IntfIDFromUniPortNum(inPort), OnuIDFromPortNum(inPort), UniIDFromPortNum(inPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530146 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700147 return outPort, IntfIDFromUniPortNum(outPort), OnuIDFromPortNum(outPort), UniIDFromPortNum(outPort)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530148}
149
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700150//IsUpstream returns true for Upstream and false for downstream
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530151func IsUpstream(outPort uint32) bool {
manikkaraj k17652a72019-05-06 09:06:36 -0400152 for _, port := range controllerPorts {
153 if port == outPort {
154 return true
155 }
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530156 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700157 return (outPort & (1 << 16)) == (1 << 16)
Manjunath Vanaraj39ecd412019-03-15 20:05:41 +0530158}
manikkaraj k17652a72019-05-06 09:06:36 -0400159
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700160//IsControllerBoundFlow returns true/false
manikkaraj k17652a72019-05-06 09:06:36 -0400161func IsControllerBoundFlow(outPort uint32) bool {
162 for _, port := range controllerPorts {
163 if port == outPort {
164 return true
165 }
166 }
167 return false
168}
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400169
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700170//OnuIDFromUniPortNum returns onuId from give portNum information.
171func OnuIDFromUniPortNum(portNum uint32) uint32 {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400172 return (portNum >> 4) & 0x7F
173}
174
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700175//FlowExtractInfo fetches uniport from the flow, based on which it gets and returns ponInf, onuID and uniID
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400176func FlowExtractInfo(flow *ofp.OfpFlowStats, flowDirection string) (uint32, uint32, uint32, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700177 var uniPortNo uint32
178 var ponIntf uint32
179 var onuID uint32
180 var uniID uint32
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400181
182 if flowDirection == "upstream" {
183 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
184 for _, field := range utils.GetOfbFields(flow) {
185 if field.GetType() == utils.IN_PORT {
186 uniPortNo = field.GetPort()
187 break
188 }
189 }
190 }
191 } else if flowDirection == "downstream" {
192 if uniPortNo = utils.GetChildPortFromTunnelId(flow); uniPortNo == 0 {
193 for _, action := range utils.GetActions(flow) {
194 if action.Type == utils.OUTPUT {
195 if out := action.GetOutput(); out != nil {
196 uniPortNo = out.GetPort()
197 }
198 break
199 }
200 }
201 }
202 }
203
204 if uniPortNo == 0 {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700205 return 0, 0, 0, errors.New("failed to extract Pon Interface, ONU Id and Uni Id from flow")
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400206 }
207
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700208 ponIntf = IntfIDFromUniPortNum(uniPortNo)
209 onuID = OnuIDFromUniPortNum(uniPortNo)
210 uniID = UniIDFromPortNum(uniPortNo)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400211
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700212 return ponIntf, onuID, uniID, nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400213}