blob: 336babcae66d611b2f96677e6f2040002d892871 [file] [log] [blame]
manikkaraj kbf256be2019-03-25 00:13:48 +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 */
16
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
manikkaraj kbf256be2019-03-25 00:13:48 +053019
20import (
21 "context"
22 "crypto/md5"
Matteo Scandolo6056e822019-11-13 14:05:29 -080023 "encoding/hex"
manikkaraj kbf256be2019-03-25 00:13:48 +053024 "encoding/json"
Girish Gowdracefae192020-03-19 18:14:10 -070025 "errors"
manikkaraj kbf256be2019-03-25 00:13:48 +053026 "fmt"
Manikkaraj kb1d51442019-07-23 10:41:02 -040027 "math/big"
Girish Gowdrafae935c2020-02-17 19:21:44 +053028 "strings"
William Kurkian740a09c2019-10-23 17:07:38 -040029 "sync"
Girish Gowdra3d633032019-12-10 16:37:05 +053030 "time"
Manikkaraj kb1d51442019-07-23 10:41:02 -040031
Esin Karamanccb714b2019-11-29 15:02:06 +000032 "github.com/opencord/voltha-lib-go/v3/pkg/flows"
33 "github.com/opencord/voltha-lib-go/v3/pkg/log"
34 tp "github.com/opencord/voltha-lib-go/v3/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080035 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Esin Karamanccb714b2019-11-29 15:02:06 +000036 "github.com/opencord/voltha-protos/v3/go/common"
37 ic "github.com/opencord/voltha-protos/v3/go/inter_container"
38 ofp "github.com/opencord/voltha-protos/v3/go/openflow_13"
39 openoltpb2 "github.com/opencord/voltha-protos/v3/go/openolt"
40 tp_pb "github.com/opencord/voltha-protos/v3/go/tech_profile"
41 "github.com/opencord/voltha-protos/v3/go/voltha"
Chaitrashree G S579fe732019-08-20 20:50:47 -040042
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -040043 //deepcopy "github.com/getlantern/deepcopy"
Girish Gowdra3d633032019-12-10 16:37:05 +053044 "github.com/EagleChen/mapmutex"
Thomas Lee S94109f12020-03-03 16:39:29 +053045 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000046 "google.golang.org/grpc/codes"
47 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053048)
49
50const (
51 // Flow categories
manikkaraj kbf256be2019-03-25 00:13:48 +053052
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070053 //HsiaFlow flow category
54 HsiaFlow = "HSIA_FLOW"
manikkaraj kbf256be2019-03-25 00:13:48 +053055
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070056 //EapolFlow flow category
57 EapolFlow = "EAPOL_FLOW"
manikkaraj kbf256be2019-03-25 00:13:48 +053058
Manikkaraj kb1d51442019-07-23 10:41:02 -040059 //DhcpFlow flow category
60 DhcpFlow = "DHCP_FLOW"
61
Esin Karamanccb714b2019-11-29 15:02:06 +000062 //MulticastFlow flow category
63 MulticastFlow = "MULTICAST_FLOW"
64
Esin Karamanae41e2b2019-12-17 18:13:13 +000065 //IgmpFlow flow category
66 IgmpFlow = "IGMP_FLOW"
67
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070068 //IPProtoDhcp flow category
69 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053070
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070071 //IPProtoIgmp flow category
72 IPProtoIgmp = 2
73
74 //EapEthType eapethtype value
75 EapEthType = 0x888e
76 //LldpEthType lldp ethtype value
77 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000078 //IPv4EthType IPv4 ethernet type value
79 IPv4EthType = 0x800
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070080
81 //IgmpProto proto value
82 IgmpProto = 2
manikkaraj kbf256be2019-03-25 00:13:48 +053083
Andrea Campanella7acc0b92020-02-14 09:20:49 +010084 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
85 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040086
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070087 //DefaultMgmtVlan default vlan value
88 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053089
manikkaraj kbf256be2019-03-25 00:13:48 +053090 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070091
David K. Bainbridge82efc492019-09-04 09:57:11 -070092 //Upstream constant
93 Upstream = "upstream"
94 //Downstream constant
95 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000096 //Multicast constant
97 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070098 //PacketTagType constant
99 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700100 //Untagged constant
101 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700102 //SingleTag constant
103 SingleTag = "single_tag"
104 //DoubleTag constant
105 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +0530106
107 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108
109 //EthType constant
110 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +0000111 //EthDst constant
112 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 //TPID constant
114 TPID = "tpid"
115 //IPProto constant
116 IPProto = "ip_proto"
117 //InPort constant
118 InPort = "in_port"
119 //VlanVid constant
120 VlanVid = "vlan_vid"
121 //VlanPcp constant
122 VlanPcp = "vlan_pcp"
123
124 //UDPDst constant
125 UDPDst = "udp_dst"
126 //UDPSrc constant
127 UDPSrc = "udp_src"
128 //Ipv4Dst constant
129 Ipv4Dst = "ipv4_dst"
130 //Ipv4Src constant
131 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700132 //Metadata constant
133 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700134 //TunnelID constant
135 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700136 //Output constant
137 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000138 //GroupID constant
139 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700140 // Actions
141
142 //PopVlan constant
143 PopVlan = "pop_vlan"
144 //PushVlan constant
145 PushVlan = "push_vlan"
146 //TrapToHost constant
147 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400148 //MaxMeterBand constant
149 MaxMeterBand = 2
150 //VlanPCPMask contant
151 VlanPCPMask = 0xFF
152 //VlanvIDMask constant
153 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000154 //IntfID constant
155 IntfID = "intfId"
156 //OnuID constant
157 OnuID = "onuId"
158 //UniID constant
159 UniID = "uniId"
160 //PortNo constant
161 PortNo = "portNo"
162 //AllocID constant
163 AllocID = "allocId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000164
165 //NoneOnuID constant
166 NoneOnuID = -1
167 //NoneUniID constant
168 NoneUniID = -1
169 //NoneGemPortID constant
170 NoneGemPortID = -1
Girish Gowdrafae935c2020-02-17 19:21:44 +0530171
172 // BinaryStringPrefix is binary string prefix
173 BinaryStringPrefix = "0b"
174 // BinaryBit1 is binary bit 1 expressed as a character
175 BinaryBit1 = '1'
manikkaraj kbf256be2019-03-25 00:13:48 +0530176)
177
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400178type gemPortKey struct {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700179 intfID uint32
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400180 gemPort uint32
181}
182
Girish Gowdra3d633032019-12-10 16:37:05 +0530183type pendingFlowDeleteKey struct {
184 intfID uint32
185 onuID uint32
186 uniID uint32
187}
188
189type tpLockKey struct {
190 intfID uint32
191 onuID uint32
192 uniID uint32
193}
194
Gamze Abakafee36392019-10-03 11:17:24 +0000195type schedQueue struct {
196 direction tp_pb.Direction
197 intfID uint32
198 onuID uint32
199 uniID uint32
200 tpID uint32
201 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700202 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000203 meterID uint32
204 flowMetadata *voltha.FlowMetadata
205}
206
Esin Karamanccb714b2019-11-29 15:02:06 +0000207type queueInfoBrief struct {
208 gemPortID uint32
209 servicePriority uint32
210}
211
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700212//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530213type OpenOltFlowMgr struct {
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000214 techprofile map[uint32]tp.TechProfileIf
Gamze Abakafee36392019-10-03 11:17:24 +0000215 deviceHandler *DeviceHandler
216 resourceMgr *rsrcMgr.OpenOltResourceMgr
Gamze Abakafee36392019-10-03 11:17:24 +0000217 onuIdsLock sync.RWMutex
Matteo Scandoloac032b12020-08-03 11:14:22 -0700218 perGemPortLock *mapmutex.Mutex // lock to be used to access the flowsUsedByGemPort map
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530219 flowsUsedByGemPort map[gemPortKey][]uint32 //gem port id to flow ids
220 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700221 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700222 onuGemInfo map[uint32][]rsrcMgr.OnuGemInfo //onu, gem and uni info local cache, indexed by IntfId
223 // We need to have a global lock on the onuGemInfo map
224 onuGemInfoLock sync.RWMutex
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700225 pendingFlowDelete sync.Map
Girish Gowdra3d633032019-12-10 16:37:05 +0530226 // The mapmutex.Mutex can be fine tuned to use mapmutex.NewCustomizedMapMutex
Esin Karamanccb714b2019-11-29 15:02:06 +0000227 perUserFlowHandleLock *mapmutex.Mutex
228 interfaceToMcastQueueMap map[uint32]*queueInfoBrief /*pon interface -> multicast queue map. Required to assign GEM to a bucket during group population*/
manikkaraj kbf256be2019-03-25 00:13:48 +0530229}
230
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700231//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
npujarec5762e2020-01-01 14:08:48 +0530232func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr) *OpenOltFlowMgr {
Shrey Baid26912972020-04-16 21:02:31 +0530233 logger.Infow("initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530234 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530235 var err error
236 var idx uint32
237
manikkaraj kbf256be2019-03-25 00:13:48 +0530238 flowMgr.deviceHandler = dh
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530239 flowMgr.resourceMgr = rMgr
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000240 flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530241 if err = flowMgr.populateTechProfilePerPonPort(); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530242 logger.Errorw("error-while-populating-tech-profile-mgr", log.Fields{"error": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530243 return nil
244 }
William Kurkian740a09c2019-10-23 17:07:38 -0400245 flowMgr.onuIdsLock = sync.RWMutex{}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530246 flowMgr.flowsUsedByGemPort = make(map[gemPortKey][]uint32)
247 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530248 ponPorts := rMgr.DevInfo.GetPonPorts()
Matteo Scandolo60913ed2020-06-23 19:31:14 -0700249 flowMgr.onuGemInfo = make(map[uint32][]rsrcMgr.OnuGemInfo, ponPorts)
Girish Gowdra8e43ebb2020-08-17 15:41:16 -0700250 flowMgr.onuGemInfoLock = sync.RWMutex{}
251 flowMgr.pendingFlowDelete = sync.Map{}
252 flowMgr.perUserFlowHandleLock = mapmutex.NewCustomizedMapMutex(300, 100000000, 10000000, 1.1, 0.2)
253 flowMgr.perGemPortLock = mapmutex.NewCustomizedMapMutex(300, 100000000, 10000000, 1.1, 0.2)
254 flowMgr.interfaceToMcastQueueMap = make(map[uint32]*queueInfoBrief)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530255 //Load the onugem info cache from kv store on flowmanager start
256 for idx = 0; idx < ponPorts; idx++ {
npujarec5762e2020-01-01 14:08:48 +0530257 if flowMgr.onuGemInfo[idx], err = rMgr.GetOnuGemInfo(ctx, idx); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530258 logger.Error("failed-to-load-onu-gem-info-cache")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530259 }
Abhilash Laxmeshwar275c0742019-11-25 16:47:02 +0530260 //Load flowID list per gem map per interface from the kvstore.
npujarec5762e2020-01-01 14:08:48 +0530261 flowMgr.loadFlowIDlistForGem(ctx, idx)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530262 }
Esin Karamanccb714b2019-11-29 15:02:06 +0000263 //load interface to multicast queue map from kv store
npujarec5762e2020-01-01 14:08:48 +0530264 flowMgr.loadInterfaceToMulticastQueueMap(ctx)
Shrey Baid26912972020-04-16 21:02:31 +0530265 logger.Info("initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530266 return &flowMgr
267}
268
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700269func (f *OpenOltFlowMgr) generateStoredFlowID(flowID uint32, direction string) (uint64, error) {
David K. Bainbridge82efc492019-09-04 09:57:11 -0700270 if direction == Upstream {
Shrey Baid26912972020-04-16 21:02:31 +0530271 logger.Debugw("upstream-flow-shifting-id", log.Fields{"device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700272 return 0x1<<15 | uint64(flowID), nil
David K. Bainbridge82efc492019-09-04 09:57:11 -0700273 } else if direction == Downstream {
Shrey Baid26912972020-04-16 21:02:31 +0530274 logger.Debugw("downstream-flow-not-shifting-id", log.Fields{"device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700275 return uint64(flowID), nil
Esin Karamanccb714b2019-11-29 15:02:06 +0000276 } else if direction == Multicast {
Shrey Baid26912972020-04-16 21:02:31 +0530277 logger.Debugw("multicast-flow-shifting-id", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000278 return 0x2<<15 | uint64(flowID), nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400279 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530280 return 0, olterrors.NewErrInvalidValue(log.Fields{"direction": direction}, nil).Log()
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400281 }
282}
283
npujarec5762e2020-01-01 14:08:48 +0530284func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) {
Matteo Scandoloac032b12020-08-03 11:14:22 -0700285
Gamze Abakafee36392019-10-03 11:17:24 +0000286 gemPK := gemPortKey{uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId)}
Matteo Scandoloac032b12020-08-03 11:14:22 -0700287 if f.perGemPortLock.TryLock(gemPK) {
288 logger.Debugw("registering-flow-for-device",
289 log.Fields{
290 "flow": flowFromCore,
291 "device-id": f.deviceHandler.device.Id})
292 flowIDList, ok := f.flowsUsedByGemPort[gemPK]
293 if !ok {
294 flowIDList = []uint32{deviceFlow.FlowId}
295 }
296 flowIDList = appendUnique(flowIDList, deviceFlow.FlowId)
297 f.flowsUsedByGemPort[gemPK] = flowIDList
298 // update the flowids for a gem to the KVstore
299 f.resourceMgr.UpdateFlowIDsForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowIDList)
300 f.perGemPortLock.Unlock(gemPK)
301 } else {
302 logger.Error("failed-to-acquire-per-gem-port-lock",
303 log.Fields{
304 "flow": flowFromCore,
305 "device-id": f.deviceHandler.device.Id,
306 "key": gemPK,
307 })
Gamze Abakafee36392019-10-03 11:17:24 +0000308 }
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400309}
310
npujarec5762e2020-01-01 14:08:48 +0530311func (f *OpenOltFlowMgr) divideAndAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000312 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
313 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) {
Gamze Abakafee36392019-10-03 11:17:24 +0000314 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530315 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700316 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530317
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700318 logger.Infow("dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530319 "device-id": f.deviceHandler.device.Id,
320 "intf-id": intfID,
321 "onu-id": onuID,
322 "uni-id": uniID,
323 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700324 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530325 "action": actionInfo,
326 "usmeter-iD": UsMeterID,
327 "dsmeter-iD": DsMeterID,
328 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400329 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
330 // is because the flow is an NNI flow and there would be no onu resources associated with it
331 // TODO: properly deal with NNI flows
Manikkaraj kb1d51442019-07-23 10:41:02 -0400332 if onuID <= 0 {
Shrey Baid26912972020-04-16 21:02:31 +0530333 logger.Errorw("no-onu-id-for-flow",
334 log.Fields{
335 "port-no": portNo,
336 "classifer": classifierInfo,
337 "action": actionInfo,
338 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530339 return
340 }
341
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700342 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Shrey Baid26912972020-04-16 21:02:31 +0530343 logger.Debugw("uni-port-path", log.Fields{
344 "uni": uni,
345 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530346
347 tpLockMapKey := tpLockKey{intfID, onuID, uniID}
348 if f.perUserFlowHandleLock.TryLock(tpLockMapKey) {
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700349 logger.Debugw("dividing-flow-create-tcont-gem-ports", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530350 "device-id": f.deviceHandler.device.Id,
351 "intf-id": intfID,
352 "onu-id": onuID,
353 "uni-id": uniID,
354 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700355 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530356 "action": actionInfo,
357 "usmeter-id": UsMeterID,
358 "dsmeter-id": DsMeterID,
359 "tp-id": TpID})
npujarec5762e2020-01-01 14:08:48 +0530360 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
Girish Gowdra3d633032019-12-10 16:37:05 +0530361 if allocID == 0 || gemPorts == nil || TpInst == nil {
Girish Kumar2ad402b2020-03-20 19:45:12 +0000362 logger.Error("alloc-id-gem-ports-tp-unavailable")
Girish Gowdra3d633032019-12-10 16:37:05 +0530363 f.perUserFlowHandleLock.Unlock(tpLockMapKey)
364 return
365 }
366 args := make(map[string]uint32)
367 args[IntfID] = intfID
368 args[OnuID] = onuID
369 args[UniID] = uniID
370 args[PortNo] = portNo
371 args[AllocID] = allocID
372
373 /* Flows can be added specific to gemport if p-bits are received.
374 * If no pbit mentioned then adding flows for all gemports
375 */
npujarec5762e2020-01-01 14:08:48 +0530376 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
Girish Gowdra3d633032019-12-10 16:37:05 +0530377 f.perUserFlowHandleLock.Unlock(tpLockMapKey)
378 } else {
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700379 logger.Errorw("failed-to-acquire-per-user-flow-handle-lock",
Shrey Baid26912972020-04-16 21:02:31 +0530380 log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -0700381 "intf-id": intfID,
382 "onu-id": onuID,
383 "uni-id": uniID,
384 "flow-id": flow.Id,
385 "flow-cookie": flow.Cookie,
386 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400387 return
388 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530389}
390
salmansiddiqui7ac62132019-08-22 03:58:50 +0000391// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530392func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400393
Shrey Baid26912972020-04-16 21:02:31 +0530394 logger.Debugw("CreateSchedulerQueues",
395 log.Fields{"dir": sq.direction,
396 "intf-id": sq.intfID,
397 "onu-id": sq.onuID,
398 "uni-id": sq.uniID,
399 "tp-id": sq.tpID,
400 "meter-id": sq.meterID,
401 "tp-inst": sq.tpInst,
402 "flowmetadata": sq.flowMetadata,
403 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400404
Gamze Abakafee36392019-10-03 11:17:24 +0000405 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000406 if err != nil {
407 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400408 }
409
410 /* Lets make a simple assumption that if the meter-id is present on the KV store,
411 * then the scheduler and queues configuration is applied on the OLT device
412 * in the given direction.
413 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000414
Manikkaraj kb1d51442019-07-23 10:41:02 -0400415 var SchedCfg *tp_pb.SchedulerConfig
npujarec5762e2020-01-01 14:08:48 +0530416 KvStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400417 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530418 return olterrors.NewErrNotFound("meter",
419 log.Fields{"intf-id": sq.intfID,
420 "onu-id": sq.onuID,
421 "uni-id": sq.uniID,
422 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400423 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000424
Manikkaraj kb1d51442019-07-23 10:41:02 -0400425 if KvStoreMeter != nil {
Gamze Abakafee36392019-10-03 11:17:24 +0000426 if KvStoreMeter.MeterId == sq.meterID {
Shrey Baid26912972020-04-16 21:02:31 +0530427 logger.Debugw("scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400428 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400429 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530430 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800431 "unsupported": "meter-id",
432 "kv-store-meter-id": KvStoreMeter.MeterId,
Shrey Baid26912972020-04-16 21:02:31 +0530433 "meter-id-in-flow": sq.meterID,
434 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400435 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000436
Shrey Baid26912972020-04-16 21:02:31 +0530437 logger.Debugw("meter-does-not-exist-creating-new",
438 log.Fields{
439 "meter-id": sq.meterID,
440 "direction": Direction,
441 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000442
Gamze Abakafee36392019-10-03 11:17:24 +0000443 if sq.direction == tp_pb.Direction_UPSTREAM {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700444 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst.(*tp.TechProfile))
Gamze Abakafee36392019-10-03 11:17:24 +0000445 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700446 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400447 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000448
449 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530450 return olterrors.NewErrNotFound("scheduler-config",
451 log.Fields{
452 "intf-id": sq.intfID,
453 "direction": sq.direction,
454 "tp-inst": sq.tpInst,
455 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000456 }
457
Manikkaraj kb1d51442019-07-23 10:41:02 -0400458 var meterConfig *ofp.OfpMeterConfig
Gamze Abakafee36392019-10-03 11:17:24 +0000459 if sq.flowMetadata != nil {
460 for _, meter := range sq.flowMetadata.Meters {
461 if sq.meterID == meter.MeterId {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400462 meterConfig = meter
Shrey Baid26912972020-04-16 21:02:31 +0530463 logger.Debugw("found-meter-config-from-flowmetadata",
464 log.Fields{"meterConfig": meterConfig,
465 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400466 break
467 }
468 }
469 } else {
Shrey Baid26912972020-04-16 21:02:31 +0530470 logger.Errorw("flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400471 }
472 if meterConfig == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530473 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800474 "reason": "Could-not-get-meterbands-from-flowMetadata",
475 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530476 "meter-id": sq.meterID,
477 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400478 } else if len(meterConfig.Bands) < MaxMeterBand {
Shrey Baid26912972020-04-16 21:02:31 +0530479 logger.Errorw("invalid-number-of-bands-in-meter",
480 log.Fields{"Bands": meterConfig.Bands,
481 "meter-id": sq.meterID,
482 "device-id": f.deviceHandler.device.Id})
Thomas Lee S94109f12020-03-03 16:39:29 +0530483 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800484 "reason": "Invalid-number-of-bands-in-meter",
485 "meterband-count": len(meterConfig.Bands),
486 "metabands": meterConfig.Bands,
Shrey Baid26912972020-04-16 21:02:31 +0530487 "meter-id": sq.meterID,
488 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400489 }
490 cir := meterConfig.Bands[0].Rate
491 cbs := meterConfig.Bands[0].BurstSize
492 eir := meterConfig.Bands[1].Rate
493 ebs := meterConfig.Bands[1].BurstSize
494 pir := cir + eir
495 pbs := cbs + ebs
496 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
497
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700498 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000499 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400500
npujarec5762e2020-01-01 14:08:48 +0530501 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficShaping, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530502 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
503 log.Fields{"intf-id": sq.intfID,
504 "direction": sq.direction,
505 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400506 }
507
salmansiddiqui7ac62132019-08-22 03:58:50 +0000508 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400509 * store the meter id on the KV store, for further reference.
510 */
npujarec5762e2020-01-01 14:08:48 +0530511 if err := f.resourceMgr.UpdateMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, meterConfig); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530512 return olterrors.NewErrAdapter("failed-updating-meter-id",
513 log.Fields{"onu-id": sq.onuID,
514 "meter-id": sq.meterID,
515 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400516 }
Shrey Baid26912972020-04-16 21:02:31 +0530517 logger.Infow("updated-meter-info-into-kv-store-successfully",
518 log.Fields{"direction": Direction,
519 "Meter": meterConfig,
520 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400521 return nil
522}
523
npujarec5762e2020-01-01 14:08:48 +0530524func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficShaping *tp_pb.TrafficShapingInfo, TrafficSched []*tp_pb.TrafficScheduler) error {
Girish Kumar8f73fe02019-12-09 13:19:37 +0000525
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700526 trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000527
528 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530529 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
530 log.Fields{"intf-id": sq.intfID,
531 "direction": sq.direction,
532 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000533 }
534
Shrey Baid26912972020-04-16 21:02:31 +0530535 logger.Debugw("sending-traffic-scheduler-create-to-device",
536 log.Fields{
537 "direction": sq.direction,
538 "TrafficScheds": TrafficSched,
539 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530540 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Girish Kumar8f73fe02019-12-09 13:19:37 +0000541 IntfId: sq.intfID, OnuId: sq.onuID,
542 UniId: sq.uniID, PortNo: sq.uniPort,
543 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000544 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000545 }
Shrey Baid26912972020-04-16 21:02:31 +0530546 logger.Infow("successfully-created-traffic-schedulers", log.Fields{
547 "direction": sq.direction,
548 "traffic-queues": trafficQueues,
549 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000550
551 // On receiving the CreateTrafficQueues request, the driver should create corresponding
552 // downstream queues.
Shrey Baid26912972020-04-16 21:02:31 +0530553 logger.Debugw("sending-traffic-queues-create-to-device",
554 log.Fields{"direction": sq.direction,
555 "traffic-queues": trafficQueues,
556 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530557 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000558 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
559 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000560 TrafficQueues: trafficQueues,
561 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530562 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000563 }
Shrey Baid26912972020-04-16 21:02:31 +0530564 logger.Infow("successfully-created-traffic-schedulers", log.Fields{
565 "direction": sq.direction,
566 "traffic-queues": trafficQueues,
567 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000568
Esin Karamanccb714b2019-11-29 15:02:06 +0000569 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700570 multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(sq.tpInst.(*tp.TechProfile))
Esin Karamanccb714b2019-11-29 15:02:06 +0000571 if len(multicastTrafficQueues) > 0 {
572 if _, present := f.interfaceToMcastQueueMap[sq.intfID]; !present {
573 //assumed that there is only one queue per PON for the multicast service
574 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
575 //just put it in interfaceToMcastQueueMap to use for building group members
Shrey Baid26912972020-04-16 21:02:31 +0530576 logger.Debugw("multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000577 multicastQueuePerPonPort := multicastTrafficQueues[0]
578 f.interfaceToMcastQueueMap[sq.intfID] = &queueInfoBrief{
579 gemPortID: multicastQueuePerPonPort.GemportId,
580 servicePriority: multicastQueuePerPonPort.Priority,
581 }
582 //also store the queue info in kv store
npujarec5762e2020-01-01 14:08:48 +0530583 f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID,
Esin Karamanccb714b2019-11-29 15:02:06 +0000584 multicastQueuePerPonPort.GemportId,
585 multicastQueuePerPonPort.Priority)
Shrey Baid26912972020-04-16 21:02:31 +0530586
587 logger.Infow("multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000588 }
589 }
590 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000591 return nil
592}
593
salmansiddiqui7ac62132019-08-22 03:58:50 +0000594// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530595func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400596
597 var Direction string
598 var SchedCfg *tp_pb.SchedulerConfig
599 var err error
Shrey Baid26912972020-04-16 21:02:31 +0530600 logger.Infow("removing-schedulers-and-queues-in-olt",
601 log.Fields{
602 "direction": sq.direction,
603 "intf-id": sq.intfID,
604 "onu-id": sq.onuID,
605 "uni-id": sq.uniID,
606 "uni-port": sq.uniPort,
607 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000608 if sq.direction == tp_pb.Direction_UPSTREAM {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700609 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400610 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000611 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700612 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400613 Direction = "downstream"
614 }
615
Girish Kumar8f73fe02019-12-09 13:19:37 +0000616 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530617 return olterrors.NewErrNotFound("scheduler-config",
618 log.Fields{
619 "int-id": sq.intfID,
620 "direction": sq.direction,
621 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000622 }
623
npujarec5762e2020-01-01 14:08:48 +0530624 KVStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400625 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530626 return olterrors.NewErrNotFound("meter",
627 log.Fields{
628 "onu-id": sq.onuID,
629 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400630 }
631 if KVStoreMeter == nil {
Shrey Baid26912972020-04-16 21:02:31 +0530632 logger.Warnw("no-meter-installed-yet",
633 log.Fields{
634 "direction": Direction,
635 "intf-id": sq.intfID,
636 "onu-id": sq.onuID,
637 "uni-id": sq.uniID,
638 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400639 return nil
640 }
641 cir := KVStoreMeter.Bands[0].Rate
642 cbs := KVStoreMeter.Bands[0].BurstSize
643 eir := KVStoreMeter.Bands[1].Rate
644 ebs := KVStoreMeter.Bands[1].BurstSize
645 pir := cir + eir
646 pbs := cbs + ebs
647
648 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
649
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700650 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000651 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000652
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700653 TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000654 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530655 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
656 log.Fields{
657 "intf-id": sq.intfID,
658 "direction": sq.direction,
659 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000660 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400661
npujarec5762e2020-01-01 14:08:48 +0530662 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000663 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
664 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000665 TrafficQueues: TrafficQueues,
666 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000667 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530668 log.Fields{
669 "intf-id": sq.intfID,
670 "traffic-queues": TrafficQueues,
671 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400672 }
Shrey Baid26912972020-04-16 21:02:31 +0530673 logger.Infow("removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530674 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Gamze Abakafee36392019-10-03 11:17:24 +0000675 IntfId: sq.intfID, OnuId: sq.onuID,
676 UniId: sq.uniID, PortNo: sq.uniPort,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400677 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000678 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530679 log.Fields{
680 "intf-id": sq.intfID,
681 "traffic-schedulers": TrafficSched}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400682 }
683
Shrey Baid26912972020-04-16 21:02:31 +0530684 logger.Infow("removed-traffic-schedulers-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000685
686 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400687 * delete the meter id on the KV store.
688 */
npujarec5762e2020-01-01 14:08:48 +0530689 err = f.resourceMgr.RemoveMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400690 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530691 return olterrors.NewErrAdapter("unable-to-remove-meter",
692 log.Fields{
693 "onu": sq.onuID,
694 "meter": KVStoreMeter.MeterId,
695 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400696 }
Shrey Baid26912972020-04-16 21:02:31 +0530697 logger.Infow("removed-meter-from-KV-store-successfully",
698 log.Fields{
699 "meter-id": KVStoreMeter.MeterId,
700 "dir": Direction,
701 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400702 return err
703}
704
Gamze Abakafee36392019-10-03 11:17:24 +0000705// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700706func (f *OpenOltFlowMgr) createTcontGemports(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uni string, uniPort uint32, TpID uint32, UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) (uint32, []uint32, interface{}) {
Gamze Abakafee36392019-10-03 11:17:24 +0000707 var allocIDs []uint32
708 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530709 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530710 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000711 var err error
Gamze Abakafee36392019-10-03 11:17:24 +0000712
npujarec5762e2020-01-01 14:08:48 +0530713 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
714 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400715
716 tpPath := f.getTPpath(intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530717
Shrey Baid26912972020-04-16 21:02:31 +0530718 logger.Debugw("creating-new-tcont-and-gem", log.Fields{
719 "intf-id": intfID,
720 "onu-id": onuID,
721 "uni-id": uniID,
722 "device-id": f.deviceHandler.device.Id,
723 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530724
Manikkaraj kb1d51442019-07-23 10:41:02 -0400725 // Check tech profile instance already exists for derived port name
npujarec5762e2020-01-01 14:08:48 +0530726 techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000727 if techProfileInstance == nil {
Shrey Baid26912972020-04-16 21:02:31 +0530728 logger.Infow("tp-instance-not-found--creating-new",
729 log.Fields{
730 "path": tpPath,
731 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530732 techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000733 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530734 // This should not happen, something wrong in KV backend transaction
Shrey Baid26912972020-04-16 21:02:31 +0530735 logger.Errorw("tp-instance-create-failed",
736 log.Fields{
737 "error": err,
738 "tp-id": TpID,
739 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000740 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530741 }
npujarec5762e2020-01-01 14:08:48 +0530742 f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID)
manikkaraj kbf256be2019-03-25 00:13:48 +0530743 } else {
Shrey Baid26912972020-04-16 21:02:31 +0530744 logger.Debugw("tech-profile-instance-already-exist-for-given port-name",
745 log.Fields{
746 "uni": uni,
747 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530748 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530749 }
Gamze Abakafee36392019-10-03 11:17:24 +0000750
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700751 switch tpInst := techProfileInstance.(type) {
752 case *tp.TechProfile:
753 if UsMeterID != 0 {
754 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
755 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
756 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
757 logger.Errorw("CreateSchedulerQueues-failed-upstream",
758 log.Fields{
759 "error": err,
760 "meter-id": UsMeterID,
761 "device-id": f.deviceHandler.device.Id})
762 return 0, nil, nil
763 }
764 }
765 if DsMeterID != 0 {
766 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
767 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
768 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
769 logger.Errorw("CreateSchedulerQueues-failed-downstream",
770 log.Fields{
771 "error": err,
772 "meter-id": DsMeterID,
773 "device-id": f.deviceHandler.device.Id})
774 return 0, nil, nil
775 }
776 }
777 allocID := tpInst.UsScheduler.AllocID
778 for _, gem := range tpInst.UpstreamGemPortAttributeList {
779 gemPortIDs = append(gemPortIDs, gem.GemportID)
780 }
781 allocIDs = appendUnique(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000782
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700783 if tpInstanceExists {
784 return allocID, gemPortIDs, techProfileInstance
785 }
786
787 for _, gemPortID := range gemPortIDs {
788 allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
789 }
790 logger.Infow("allocated-tcont-and-gem-ports",
791 log.Fields{
792 "alloc-ids": allocIDs,
793 "gemports": allgemPortIDs,
794 "device-id": f.deviceHandler.device.Id})
795 // Send Tconts and GEM ports to KV store
796 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530797 return allocID, gemPortIDs, techProfileInstance
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700798 case *tp.EponProfile:
799 // CreateSchedulerQueues for EPON needs to be implemented here
800 // when voltha-protos for EPON is completed.
801 allocID := tpInst.AllocID
802 for _, gem := range tpInst.UpstreamQueueAttributeList {
803 gemPortIDs = append(gemPortIDs, gem.GemportID)
804 }
805 allocIDs = appendUnique(allocIDs, allocID)
806
807 if tpInstanceExists {
808 return allocID, gemPortIDs, techProfileInstance
809 }
810
811 for _, gemPortID := range gemPortIDs {
812 allgemPortIDs = appendUnique(allgemPortIDs, gemPortID)
813 }
814 logger.Infow("allocated-tcont-and-gem-ports",
815 log.Fields{
816 "alloc-ids": allocIDs,
817 "gemports": allgemPortIDs,
818 "device-id": f.deviceHandler.device.Id})
819 // Send Tconts and GEM ports to KV store
820 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
821 return allocID, gemPortIDs, techProfileInstance
822 default:
823 logger.Errorw("unknown-tech",
824 log.Fields{
825 "tpInst": tpInst})
826 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530827 }
828
manikkaraj kbf256be2019-03-25 00:13:48 +0530829}
830
npujarec5762e2020-01-01 14:08:48 +0530831func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530832
Shrey Baid26912972020-04-16 21:02:31 +0530833 logger.Debugw("storing-allocated-tconts-and-gem-ports-into-KV-store",
834 log.Fields{
835 "intf-id": intfID,
836 "onu-id": onuID,
837 "uni-id": uniID,
838 "alloc-id": allocID,
839 "gemport-ids": gemPortIDs,
840 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530841 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530842 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530843 logger.Errorw("error-while-uploading-allocid-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530844 }
npujarec5762e2020-01-01 14:08:48 +0530845 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530846 logger.Errorw("error-while-uploading-gemports-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530847 }
npujarec5762e2020-01-01 14:08:48 +0530848 if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530849 logger.Error("error-while-uploading-gemtopon-map-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530850 }
Shrey Baid26912972020-04-16 21:02:31 +0530851 logger.Infow("stored-tconts-and-gem-into-kv-store-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400852 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530853 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400854 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530855}
856
857func (f *OpenOltFlowMgr) populateTechProfilePerPonPort() error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000858 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530859 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000860 for _, intfID := range techRange.IntfIds {
861 f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[uint32(intfID)].TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400862 tpCount++
Shrey Baid26912972020-04-16 21:02:31 +0530863 logger.Debugw("init-tech-profile-done",
864 log.Fields{
865 "intf-id": intfID,
866 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530867 }
868 }
869 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400870 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530871 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530872 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800873 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530874 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
875 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530876 }
Shrey Baid26912972020-04-16 21:02:31 +0530877 logger.Infow("populated-techprofile-for-ponports-successfully",
878 log.Fields{
879 "numofTech": tpCount,
880 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
881 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530882 return nil
883}
884
npujarec5762e2020-01-01 14:08:48 +0530885func (f *OpenOltFlowMgr) addUpstreamDataFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530886 portNo uint32, uplinkClassifier map[string]interface{},
887 uplinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000888 allocID uint32, gemportID uint32, tpID uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700889 uplinkClassifier[PacketTagType] = SingleTag
Shrey Baid26912972020-04-16 21:02:31 +0530890 logger.Debugw("adding-upstream-data-flow",
891 log.Fields{
892 "uplinkClassifier": uplinkClassifier,
893 "uplinkAction": uplinkAction})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800894 return f.addHSIAFlow(ctx, intfID, onuID, uniID, portNo, uplinkClassifier, uplinkAction,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000895 Upstream, logicalFlow, allocID, gemportID, tpID)
Manikkaraj k884c1242019-04-11 16:26:42 +0530896 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530897}
898
npujarec5762e2020-01-01 14:08:48 +0530899func (f *OpenOltFlowMgr) addDownstreamDataFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530900 portNo uint32, downlinkClassifier map[string]interface{},
901 downlinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000902 allocID uint32, gemportID uint32, tpID uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700903 downlinkClassifier[PacketTagType] = DoubleTag
Shrey Baid26912972020-04-16 21:02:31 +0530904 logger.Debugw("adding-downstream-data-flow",
905 log.Fields{
906 "downlinkClassifier": downlinkClassifier,
907 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400908 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
909 if vlan, exists := downlinkClassifier[VlanVid]; exists {
910 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700911 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Manikkaraj kb1d51442019-07-23 10:41:02 -0400912 if uint32(metadata.(uint64)) == MkUniPortNum(intfID, onuID, uniID) {
Shrey Baid26912972020-04-16 21:02:31 +0530913 logger.Infow("ignoring-dl-trap-device-flow-from-core",
914 log.Fields{
915 "flow": logicalFlow,
916 "device-id": f.deviceHandler.device.Id,
917 "onu-id": onuID,
918 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800919 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400920 }
921 }
922 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530923 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400924
Manikkaraj k884c1242019-04-11 16:26:42 +0530925 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700926 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400927 // vlan_vid is a uint32. must be type asserted as such or conversion fails
928 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530929 if ok {
930 downlinkAction[VlanVid] = dlClVid & 0xfff
931 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530932 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530933 "reason": "failed-to-convert-vlanid-classifier",
934 "vlan-id": VlanVid,
935 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530936 }
937
David K. Bainbridge794735f2020-02-11 21:01:37 -0800938 return f.addHSIAFlow(ctx, intfID, onuID, uniID, portNo, downlinkClassifier, downlinkAction,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000939 Downstream, logicalFlow, allocID, gemportID, tpID)
manikkaraj kbf256be2019-03-25 00:13:48 +0530940}
941
npujarec5762e2020-01-01 14:08:48 +0530942func (f *OpenOltFlowMgr) addHSIAFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Manikkaraj k884c1242019-04-11 16:26:42 +0530943 action map[string]interface{}, direction string, logicalFlow *ofp.OfpFlowStats,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000944 allocID uint32, gemPortID uint32, tpID uint32) error {
Manikkaraj k884c1242019-04-11 16:26:42 +0530945 /* One of the OLT platform (Broadcom BAL) requires that symmetric
946 flows require the same flow_id to be used across UL and DL.
947 Since HSIA flow is the only symmetric flow currently, we need to
948 re-use the flow_id across both direction. The 'flow_category'
949 takes priority over flow_cookie to find any available HSIA_FLOW
950 id for the ONU.
951 */
Shrey Baid26912972020-04-16 21:02:31 +0530952 logger.Infow("adding-hsia-flow",
953 log.Fields{
954 "intf-id": intfID,
955 "onu-id": onuID,
956 "uni-id": uniID,
957 "device-id": f.deviceHandler.device.Id,
958 "classifier": classifier,
959 "action": action,
960 "direction": direction,
961 "alloc-id": allocID,
962 "gemport-id": gemPortID,
963 "logicalflow": *logicalFlow})
Girish Gowdrafae935c2020-02-17 19:21:44 +0530964 var vlanPbit uint32 = 0xff // means no pbit
Gamze Abaka724d0852020-03-18 12:10:24 +0000965 var vlanVid uint32
Manikkaraj kb1d51442019-07-23 10:41:02 -0400966 if _, ok := classifier[VlanPcp]; ok {
Gamze Abakafee36392019-10-03 11:17:24 +0000967 vlanPbit = classifier[VlanPcp].(uint32)
Shrey Baid26912972020-04-16 21:02:31 +0530968 logger.Debugw("found-pbit-in-flow",
969 log.Fields{
970 "vlan-pbit": vlanPbit,
971 "intf-id": intfID,
972 "onu-id": onuID,
973 "device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800974 } else {
Shrey Baid26912972020-04-16 21:02:31 +0530975 logger.Debugw("pbit-not-found-in-flow",
976 log.Fields{
977 "vlan-pcp": VlanPcp,
978 "intf-id": intfID,
979 "onu-id": onuID,
980 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400981 }
Gamze Abaka724d0852020-03-18 12:10:24 +0000982 if _, ok := classifier[VlanVid]; ok {
983 vlanVid = classifier[VlanVid].(uint32)
Shrey Baid26912972020-04-16 21:02:31 +0530984 log.Debugw("found-vlan-in-the-flow",
985 log.Fields{
986 "vlan-vid": vlanVid,
987 "intf-id": intfID,
988 "onu-id": onuID,
989 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +0000990 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700991 flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
npujarec5762e2020-01-01 14:08:48 +0530992 if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
Shrey Baid26912972020-04-16 21:02:31 +0530993 logger.Infow("flow-already-exists",
994 log.Fields{
995 "device-id": f.deviceHandler.device.Id,
996 "intf-id": intfID,
997 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530999 }
Gamze Abaka724d0852020-03-18 12:10:24 +00001000 flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, HsiaFlow, vlanVid, vlanPbit)
Manikkaraj k884c1242019-04-11 16:26:42 +05301001 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301002 return olterrors.NewErrNotFound("hsia-flow-id",
1003 log.Fields{
1004 "direction": direction,
1005 "device-id": f.deviceHandler.device.Id,
1006 "intf-id": intfID,
1007 "onu-id": onuID,
1008 }, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301009 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001010 classifierProto, err := makeOpenOltClassifierField(classifier)
1011 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301012 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301013 }
Shrey Baid26912972020-04-16 21:02:31 +05301014 logger.Debugw("created-classifier-proto",
1015 log.Fields{
1016 "classifier": *classifierProto,
1017 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001018 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001019 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301020 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301021 }
Shrey Baid26912972020-04-16 21:02:31 +05301022 logger.Debugw("created-action-proto",
1023 log.Fields{
1024 "action": *actionProto,
1025 "device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001026 networkIntfID, err := getNniIntfID(classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301027 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301028 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -08001029 log.Fields{
1030 "classifier": classifier,
1031 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301032 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001033 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301034 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001035 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
1036 OnuId: int32(onuID),
1037 UniId: int32(uniID),
salmansiddiqui7ac62132019-08-22 03:58:50 +00001038 FlowId: flowID,
Manikkaraj k884c1242019-04-11 16:26:42 +05301039 FlowType: direction,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001040 AllocId: int32(allocID),
1041 NetworkIntfId: int32(networkIntfID),
1042 GemportId: int32(gemPortID),
Manikkaraj k884c1242019-04-11 16:26:42 +05301043 Classifier: classifierProto,
1044 Action: actionProto,
1045 Priority: int32(logicalFlow.Priority),
1046 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001047 PortNo: portNo,
1048 TechProfileId: tpID,
1049 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301051 return olterrors.NewErrFlowOp("add", flowID, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301052 }
Shrey Baid26912972020-04-16 21:02:31 +05301053 logger.Infow("hsia-flow-added-to-device-successfully",
1054 log.Fields{"direction": direction,
1055 "device-id": f.deviceHandler.device.Id,
1056 "flow": flow,
1057 "intf-id": intfID,
1058 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001059 flowsToKVStore := f.getUpdatedFlowInfo(ctx, &flow, flowStoreCookie, HsiaFlow, flowID, logicalFlow.Id)
1060 if err := f.updateFlowInfoToKVStore(ctx, flow.AccessIntfId,
1061 flow.OnuId,
1062 flow.UniId,
1063 flow.FlowId /*flowCategory,*/, flowsToKVStore); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301064 return olterrors.NewErrPersistence("update", "flow", flowID,
1065 log.Fields{
1066 "flow": flow,
1067 "device-id": f.deviceHandler.device.Id,
1068 "intf-id": intfID,
1069 "onu-id": onuID}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001070 }
1071 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301072}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001073
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001074func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1075 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
1076 gemPortID uint32, tpID uint32) error {
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301077
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301078 networkIntfID, err := getNniIntfID(classifier, action)
1079 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301080 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001081 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301082 "action": action,
1083 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001084 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301085 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301086
1087 // Clear the action map
1088 for k := range action {
1089 delete(action, k)
1090 }
1091
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001092 action[TrapToHost] = true
1093 classifier[UDPSrc] = uint32(68)
1094 classifier[UDPDst] = uint32(67)
1095 classifier[PacketTagType] = SingleTag
1096 delete(classifier, VlanVid)
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301097
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001098 flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
npujarec5762e2020-01-01 14:08:48 +05301099 if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
Shrey Baid26912972020-04-16 21:02:31 +05301100 logger.Infow("flow-exists--not-re-adding",
1101 log.Fields{
1102 "device-id": f.deviceHandler.device.Id,
1103 "intf-id": intfID,
1104 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001105 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301106 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301107
David K. Bainbridge794735f2020-02-11 21:01:37 -08001108 flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, DhcpFlow, 0 /*classifier[VLAN_PCP].(uint32)*/)
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301109
1110 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301111 return olterrors.NewErrNotFound("flow",
1112 log.Fields{
1113 "interface-id": intfID,
1114 "gem-port": gemPortID,
1115 "cookie": flowStoreCookie,
1116 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001117 err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301118 }
1119
Shrey Baid26912972020-04-16 21:02:31 +05301120 logger.Debugw("creating-ul-dhcp-flow",
1121 log.Fields{
1122 "ul_classifier": classifier,
1123 "ul_action": action,
1124 "uplinkFlowId": flowID,
1125 "intf-id": intfID,
1126 "onu-id": onuID,
1127 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301128
David K. Bainbridge794735f2020-02-11 21:01:37 -08001129 classifierProto, err := makeOpenOltClassifierField(classifier)
1130 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301131 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301132 }
Shrey Baid26912972020-04-16 21:02:31 +05301133 logger.Debugw("created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001134 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001135 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301136 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301137 }
1138
David K. Bainbridge794735f2020-02-11 21:01:37 -08001139 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001140 OnuId: int32(onuID),
1141 UniId: int32(uniID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301142 FlowId: flowID,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001143 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001144 AllocId: int32(allocID),
1145 NetworkIntfId: int32(networkIntfID),
1146 GemportId: int32(gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301147 Classifier: classifierProto,
1148 Action: actionProto,
1149 Priority: int32(logicalFlow.Priority),
1150 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001151 PortNo: portNo,
1152 TechProfileId: tpID,
1153 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001154 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301155 return olterrors.NewErrFlowOp("add", flowID, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001156 }
Shrey Baid26912972020-04-16 21:02:31 +05301157 logger.Infow("dhcp-ul-flow-added-to-device-successfully",
1158 log.Fields{
1159 "device-id": f.deviceHandler.device.Id,
1160 "flow-id": flowID,
1161 "intf-id": intfID,
1162 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001163 flowsToKVStore := f.getUpdatedFlowInfo(ctx, &dhcpFlow, flowStoreCookie, "DHCP", flowID, logicalFlow.Id)
1164 if err := f.updateFlowInfoToKVStore(ctx, dhcpFlow.AccessIntfId,
1165 dhcpFlow.OnuId,
1166 dhcpFlow.UniId,
1167 dhcpFlow.FlowId, flowsToKVStore); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301168 return olterrors.NewErrPersistence("update", "flow", dhcpFlow.FlowId,
1169 log.Fields{
1170 "flow": dhcpFlow,
1171 "device-id": f.deviceHandler.device.Id}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301172 }
1173
David K. Bainbridge794735f2020-02-11 21:01:37 -08001174 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301175}
1176
Esin Karamanae41e2b2019-12-17 18:13:13 +00001177//addIGMPTrapFlow creates IGMP trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301178func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001179 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32) error {
1180 return f.addUpstreamTrapFlow(ctx, intfID, onuID, uniID, portNo, classifier, action, logicalFlow, allocID, gemPortID, IgmpFlow, tpID)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001181}
1182
1183//addUpstreamTrapFlow creates a trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301184func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001185 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, flowType string, tpID uint32) error {
Esin Karamanae41e2b2019-12-17 18:13:13 +00001186
1187 networkIntfID, err := getNniIntfID(classifier, action)
1188 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301189 return olterrors.NewErrNotFound("nni-interface-id",
1190 log.Fields{
1191 "classifier": classifier,
1192 "action": action,
1193 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001194 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001195 }
1196
1197 // Clear the action map
1198 for k := range action {
1199 delete(action, k)
1200 }
1201
1202 action[TrapToHost] = true
1203 classifier[PacketTagType] = SingleTag
1204 delete(classifier, VlanVid)
1205
1206 flowStoreCookie := getFlowStoreCookie(classifier, gemPortID)
npujarec5762e2020-01-01 14:08:48 +05301207 if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkIntfID), int32(onuID), int32(uniID), flowStoreCookie); present {
Shrey Baid26912972020-04-16 21:02:31 +05301208 logger.Infow("flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001209 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001210 }
1211
npujarec5762e2020-01-01 14:08:48 +05301212 flowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, flowType, 0, 0 /*classifier[VLAN_PCP].(uint32)*/)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001213
1214 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301215 return olterrors.NewErrNotFound("flow-id",
1216 log.Fields{
1217 "intf-id": intfID,
1218 "oni-id": onuID,
1219 "cookie": flowStoreCookie,
1220 "flow-type": flowType,
1221 "device-id": f.deviceHandler.device.Id,
1222 "onu-id": onuID},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001223 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001224 }
1225
Shrey Baid26912972020-04-16 21:02:31 +05301226 logger.Debugw("creating-upstream-trap-flow",
1227 log.Fields{
1228 "ul_classifier": classifier,
1229 "ul_action": action,
1230 "uplinkFlowId": flowID,
1231 "flowType": flowType,
1232 "device-id": f.deviceHandler.device.Id,
1233 "intf-id": intfID,
1234 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001235
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 classifierProto, err := makeOpenOltClassifierField(classifier)
1237 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301238 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001239 }
Shrey Baid26912972020-04-16 21:02:31 +05301240 logger.Debugw("created-classifier-proto",
1241 log.Fields{
1242 "classifier": *classifierProto,
1243 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001244 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001245 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301246 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001247 }
1248
David K. Bainbridge794735f2020-02-11 21:01:37 -08001249 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001250 OnuId: int32(onuID),
1251 UniId: int32(uniID),
1252 FlowId: flowID,
1253 FlowType: Upstream,
1254 AllocId: int32(allocID),
1255 NetworkIntfId: int32(networkIntfID),
1256 GemportId: int32(gemPortID),
1257 Classifier: classifierProto,
1258 Action: actionProto,
1259 Priority: int32(logicalFlow.Priority),
1260 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001261 PortNo: portNo,
1262 TechProfileId: tpID,
1263 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001264
David K. Bainbridge794735f2020-02-11 21:01:37 -08001265 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301266 return olterrors.NewErrFlowOp("add", flowID, log.Fields{"flow": flow, "device-id": f.deviceHandler.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001267 }
Shrey Baid26912972020-04-16 21:02:31 +05301268 logger.Infof("%s ul-flow-added-to-device-successfully", flowType)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001269
David K. Bainbridge794735f2020-02-11 21:01:37 -08001270 flowsToKVStore := f.getUpdatedFlowInfo(ctx, &flow, flowStoreCookie, flowType, flowID, logicalFlow.Id)
1271 if err := f.updateFlowInfoToKVStore(ctx, flow.AccessIntfId,
1272 flow.OnuId,
1273 flow.UniId,
1274 flow.FlowId, flowsToKVStore); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301275 return olterrors.NewErrPersistence("update", "flow", flow.FlowId, log.Fields{"flow": flow, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001276 }
1277
David K. Bainbridge794735f2020-02-11 21:01:37 -08001278 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001279}
1280
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001281// Add EAPOL flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001282func (f *OpenOltFlowMgr) addEAPOLFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1283 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
1284 gemPortID uint32, vlanID uint32, tpID uint32) error {
Shrey Baid26912972020-04-16 21:02:31 +05301285 logger.Infow("adding-eapol-to-device",
1286 log.Fields{
1287 "intf-id": intfID,
1288 "onu-id": onuID,
1289 "port-no": portNo,
1290 "alloc-id": allocID,
1291 "gemport-id": gemPortID,
1292 "vlan-id": vlanID,
1293 "flow": logicalFlow})
manikkaraj kbf256be2019-03-25 00:13:48 +05301294
1295 uplinkClassifier := make(map[string]interface{})
1296 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301297
manikkaraj kbf256be2019-03-25 00:13:48 +05301298 // Fill Classfier
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001299 uplinkClassifier[EthType] = uint32(EapEthType)
1300 uplinkClassifier[PacketTagType] = SingleTag
1301 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001302 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301303 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304 uplinkAction[TrapToHost] = true
1305 flowStoreCookie := getFlowStoreCookie(uplinkClassifier, gemPortID)
npujarec5762e2020-01-01 14:08:48 +05301306 if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(intfID), int32(onuID), int32(uniID), flowStoreCookie); present {
Shrey Baid26912972020-04-16 21:02:31 +05301307 logger.Infow("flow-exists-not-re-adding", log.Fields{
1308 "device-id": f.deviceHandler.device.Id,
1309 "onu-id": onuID,
1310 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001311 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301312 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301313 //Add Uplink EAPOL Flow
Gamze Abaka724d0852020-03-18 12:10:24 +00001314 uplinkFlowID, err := f.resourceMgr.GetFlowID(ctx, intfID, int32(onuID), int32(uniID), gemPortID, flowStoreCookie, "", 0, 0)
manikkaraj kbf256be2019-03-25 00:13:48 +05301315 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301316 return olterrors.NewErrNotFound("flow-id",
1317 log.Fields{
1318 "intf-id": intfID,
1319 "onu-id": onuID,
1320 "coookie": flowStoreCookie,
1321 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301323 }
Shrey Baid26912972020-04-16 21:02:31 +05301324 logger.Debugw("creating-ul-eapol-flow",
1325 log.Fields{
1326 "ul_classifier": uplinkClassifier,
1327 "ul_action": uplinkAction,
1328 "uplinkFlowId": uplinkFlowID,
1329 "device-id": f.deviceHandler.device.Id,
1330 "intf-id": intfID,
1331 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301332
David K. Bainbridge794735f2020-02-11 21:01:37 -08001333 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1334 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301335 return olterrors.NewErrInvalidValue(log.Fields{
1336 "classifier": uplinkClassifier,
1337 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301338 }
Shrey Baid26912972020-04-16 21:02:31 +05301339 logger.Debugw("created-classifier-proto",
1340 log.Fields{
1341 "classifier": *classifierProto,
1342 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001343 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001344 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301345 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301346 }
Shrey Baid26912972020-04-16 21:02:31 +05301347 logger.Debugw("created-action-proto",
1348 log.Fields{
1349 "action": *actionProto,
1350 "device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 networkIntfID, err := getNniIntfID(classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301352 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301353 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001354 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301355 "action": action,
1356 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001357 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301358 }
1359
David K. Bainbridge794735f2020-02-11 21:01:37 -08001360 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001361 OnuId: int32(onuID),
1362 UniId: int32(uniID),
1363 FlowId: uplinkFlowID,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001364 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001365 AllocId: int32(allocID),
1366 NetworkIntfId: int32(networkIntfID),
1367 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301368 Classifier: classifierProto,
1369 Action: actionProto,
1370 Priority: int32(logicalFlow.Priority),
1371 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001372 PortNo: portNo,
1373 TechProfileId: tpID,
1374 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001375 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301376 return olterrors.NewErrFlowOp("add", uplinkFlowID, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001377 }
Shrey Baid26912972020-04-16 21:02:31 +05301378 logger.Infow("eapol-ul-flow-added-to-device-successfully",
1379 log.Fields{
1380 "device-id": f.deviceHandler.device.Id,
1381 "onu-id": onuID,
1382 "intf-id": intfID,
1383 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001384 flowCategory := "EAPOL"
1385 flowsToKVStore := f.getUpdatedFlowInfo(ctx, &upstreamFlow, flowStoreCookie, flowCategory, uplinkFlowID, logicalFlow.Id)
1386 if err := f.updateFlowInfoToKVStore(ctx, upstreamFlow.AccessIntfId,
1387 upstreamFlow.OnuId,
1388 upstreamFlow.UniId,
1389 upstreamFlow.FlowId,
1390 /* lowCategory, */
1391 flowsToKVStore); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301392 return olterrors.NewErrPersistence("update", "flow", upstreamFlow.FlowId,
1393 log.Fields{
1394 "flow": upstreamFlow,
1395 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301396 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001397 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301398}
1399
David K. Bainbridge794735f2020-02-11 21:01:37 -08001400func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001401 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001402
1403 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1404 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1405 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001406 if vlanID != ReservedVlan {
1407 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001408 classifier.OVid = vid
1409 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301410 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001411 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1412 vid := uint32(metadata)
1413 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001414 classifier.IVid = vid
1415 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301416 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301417 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001418 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301419 classifier.OPbits = vlanPcp
1420 } else {
1421 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301422 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001423 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1424 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1425 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1426 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001427 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001428 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1429 classifier.PktTagType = pktTagType
1430
1431 switch pktTagType {
1432 case SingleTag:
1433 case DoubleTag:
1434 case Untagged:
1435 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001436 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301437 }
1438 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001439 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301440}
1441
Gamze Abaka724d0852020-03-18 12:10:24 +00001442func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001443 var actionCmd openoltpb2.ActionCmd
1444 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301445 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001446 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301447 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001448 if _, ok := actionInfo[VlanPcp]; ok {
1449 action.Cmd.RemarkInnerPbits = true
1450 action.IPbits = actionInfo[VlanPcp].(uint32)
1451 if _, ok := actionInfo[VlanVid]; ok {
1452 action.Cmd.TranslateInnerTag = true
1453 action.IVid = actionInfo[VlanVid].(uint32)
1454 }
1455 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001456 } else if _, ok := actionInfo[PushVlan]; ok {
1457 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301458 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001459 if _, ok := actionInfo[VlanPcp]; ok {
1460 action.OPbits = actionInfo[VlanPcp].(uint32)
1461 action.Cmd.RemarkOuterPbits = true
1462 if _, ok := classifierInfo[VlanVid]; ok {
1463 action.IVid = classifierInfo[VlanVid].(uint32)
1464 action.Cmd.TranslateInnerTag = true
1465 }
1466 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001467 } else if _, ok := actionInfo[TrapToHost]; ok {
1468 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301469 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001470 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301471 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001472 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301473}
1474
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001475// getTPpath return the ETCD path for a given UNI port
1476func (f *OpenOltFlowMgr) getTPpath(intfID uint32, uniPath string, TpID uint32) string {
1477 return f.techprofile[intfID].GetTechProfileInstanceKVPath(TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301478}
1479
Gamze Abakafee36392019-10-03 11:17:24 +00001480// DeleteTechProfileInstances removes the tech profile instances from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301481func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, sn string) error {
1482 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001483 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1484
Gamze Abakafee36392019-10-03 11:17:24 +00001485 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301486 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301487 olterrors.NewErrAdapter("delete-tech-profile-failed", log.Fields{"device-id": f.deviceHandler.device.Id}, err).Log()
Girish Gowdra54934262019-11-13 14:19:55 +05301488 // return err
1489 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001490 }
Shrey Baid26912972020-04-16 21:02:31 +05301491 log.Debugw("tech-profile-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001492 }
1493 return nil
1494}
1495
1496// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301497func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001498 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001499 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001500 }
npujarec5762e2020-01-01 14:08:48 +05301501 if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301502 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1503 log.Fields{
1504 "tp-id": tpID,
1505 "uni-port-name": uniPortName,
1506 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001507 }
1508 return nil
1509}
1510
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001511func getFlowStoreCookie(classifier map[string]interface{}, gemPortID uint32) uint64 {
manikkaraj kbf256be2019-03-25 00:13:48 +05301512 if len(classifier) == 0 { // should never happen
Shrey Baid26912972020-04-16 21:02:31 +05301513 logger.Error("invalid-classfier-object")
manikkaraj kbf256be2019-03-25 00:13:48 +05301514 return 0
1515 }
Shrey Baid26912972020-04-16 21:02:31 +05301516 logger.Debugw("generating-flow-store-cookie",
1517 log.Fields{
1518 "classifier": classifier,
1519 "gemport-id": gemPortID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301520 var jsonData []byte
1521 var flowString string
1522 var err error
1523 // TODO: Do we need to marshall ??
1524 if jsonData, err = json.Marshal(classifier); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301525 logger.Error("failed-to-encode-classifier")
manikkaraj kbf256be2019-03-25 00:13:48 +05301526 return 0
1527 }
1528 flowString = string(jsonData)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001529 if gemPortID != 0 {
1530 flowString = fmt.Sprintf("%s%s", string(jsonData), string(gemPortID))
manikkaraj kbf256be2019-03-25 00:13:48 +05301531 }
1532 h := md5.New()
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001533 _, _ = h.Write([]byte(flowString))
manikkaraj kbf256be2019-03-25 00:13:48 +05301534 hash := big.NewInt(0)
1535 hash.SetBytes(h.Sum(nil))
Girish Gowdra3d633032019-12-10 16:37:05 +05301536 generatedHash := hash.Uint64()
Shrey Baid26912972020-04-16 21:02:31 +05301537 logger.Debugw("hash-generated", log.Fields{"hash": generatedHash})
Girish Gowdra3d633032019-12-10 16:37:05 +05301538 return generatedHash
manikkaraj kbf256be2019-03-25 00:13:48 +05301539}
1540
npujarec5762e2020-01-01 14:08:48 +05301541func (f *OpenOltFlowMgr) getUpdatedFlowInfo(ctx context.Context, flow *openoltpb2.Flow, flowStoreCookie uint64, flowCategory string, deviceFlowID uint32, logicalFlowID uint64) *[]rsrcMgr.FlowInfo {
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301542 var flows = []rsrcMgr.FlowInfo{{Flow: flow, FlowCategory: flowCategory, FlowStoreCookie: flowStoreCookie, LogicalFlowID: logicalFlowID}}
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001543 var intfID uint32
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001544 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1545 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1546 */
1547 if flow.AccessIntfId != -1 {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001548 intfID = uint32(flow.AccessIntfId)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001549 } else {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001550 intfID = uint32(flow.NetworkIntfId)
manikkaraj k9eb6cac2019-05-09 12:32:03 -04001551 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001552 // Get existing flows matching flowid for given subscriber from KV store
npujarec5762e2020-01-01 14:08:48 +05301553 existingFlows := f.resourceMgr.GetFlowIDInfo(ctx, intfID, flow.OnuId, flow.UniId, flow.FlowId)
manikkaraj k17652a72019-05-06 09:06:36 -04001554 if existingFlows != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301555 logger.Debugw("flow-exists-for-given-flowID--appending-it-to-current-flow",
1556 log.Fields{
1557 "flow-id": flow.FlowId,
1558 "device-id": f.deviceHandler.device.Id,
1559 "intf-id": intfID,
1560 "onu-id": flow.OnuId})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001561 //for _, f := range *existingFlows {
1562 // flows = append(flows, f)
1563 //}
1564 flows = append(flows, *existingFlows...)
manikkaraj k17652a72019-05-06 09:06:36 -04001565 }
Shrey Baid26912972020-04-16 21:02:31 +05301566 logger.Debugw("updated-flows-for-given-flowID-and-onuid",
1567 log.Fields{
1568 "updatedflow": flows,
1569 "flow-id": flow.FlowId,
1570 "onu-id": flow.OnuId,
1571 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +05301572 return &flows
1573}
1574
npujarec5762e2020-01-01 14:08:48 +05301575func (f *OpenOltFlowMgr) updateFlowInfoToKVStore(ctx context.Context, intfID int32, onuID int32, uniID int32, flowID uint32, flows *[]rsrcMgr.FlowInfo) error {
Shrey Baid26912972020-04-16 21:02:31 +05301576 logger.Debugw("storing-flow(s)-into-kv-store", log.Fields{
1577 "flow-id": flowID,
1578 "device-id": f.deviceHandler.device.Id,
1579 "intf-id": intfID,
1580 "onu-id": onuID})
npujarec5762e2020-01-01 14:08:48 +05301581 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, intfID, onuID, uniID, flowID, flows); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301582 logger.Warnw("error-while-storing-flow-into-kv-store", log.Fields{
1583 "device-id": f.deviceHandler.device.Id,
1584 "onu-id": onuID,
1585 "intf-id": intfID,
1586 "flow-id": flowID})
manikkaraj k17652a72019-05-06 09:06:36 -04001587 return err
1588 }
Shrey Baid26912972020-04-16 21:02:31 +05301589 logger.Infow("stored-flow(s)-into-kv-store-successfully!", log.Fields{
1590 "device-id": f.deviceHandler.device.Id,
1591 "onu-id": onuID,
1592 "intf-id": intfID,
1593 "flow-id": flowID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301594 return nil
1595}
1596
David K. Bainbridge794735f2020-02-11 21:01:37 -08001597func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001598
1599 var intfID uint32
1600 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1601 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1602 */
1603 if deviceFlow.AccessIntfId != -1 {
1604 intfID = uint32(deviceFlow.AccessIntfId)
1605 } else {
Manikkaraj kb1d51442019-07-23 10:41:02 -04001606 // REVIST : Why ponport is given as network port?
Daniele Rossi22db98e2019-07-11 11:50:00 +00001607 intfID = uint32(deviceFlow.NetworkIntfId)
1608 }
1609
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001610 logger.Debugw("sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301611 "flow": *deviceFlow,
1612 "device-id": f.deviceHandler.device.Id,
1613 "intf-id": intfID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301614 _, err := f.deviceHandler.Client.FlowAdd(context.Background(), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001615
1616 st, _ := status.FromError(err)
1617 if st.Code() == codes.AlreadyExists {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001618 logger.Debug("flow-already-exists", log.Fields{
1619 "err": err,
1620 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301621 "device-id": f.deviceHandler.device.Id,
1622 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001623 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301624 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001625
1626 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301627 logger.Errorw("failed-to-add-flow-to-device",
1628 log.Fields{"err": err,
1629 "device-flow": deviceFlow,
1630 "device-id": f.deviceHandler.device.Id,
1631 "intf-id": intfID})
npujarec5762e2020-01-01 14:08:48 +05301632 f.resourceMgr.FreeFlowID(ctx, intfID, deviceFlow.OnuId, deviceFlow.UniId, deviceFlow.FlowId)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001633 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001634 }
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301635 if deviceFlow.GemportId != -1 {
1636 // No need to register the flow if it is a trap on nni flow.
npujarec5762e2020-01-01 14:08:48 +05301637 f.registerFlow(ctx, logicalFlow, deviceFlow)
Abhilash Laxmeshwar6d1acb92020-01-17 15:43:03 +05301638 }
Shrey Baid26912972020-04-16 21:02:31 +05301639 logger.Infow("flow-added-to-device-successfully ",
1640 log.Fields{
1641 "flow": *deviceFlow,
1642 "device-id": f.deviceHandler.device.Id,
1643 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001644 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001645}
1646
Matteo Scandolo92186242020-06-12 10:54:18 -07001647func (f *OpenOltFlowMgr) removeFlowFromDevice(deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
Shrey Baid26912972020-04-16 21:02:31 +05301648 logger.Debugw("sending-flow-to-device-via-grpc",
1649 log.Fields{
1650 "flow": *deviceFlow,
1651 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001652 _, err := f.deviceHandler.Client.FlowRemove(context.Background(), deviceFlow)
1653 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001654 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Shrey Baid26912972020-04-16 21:02:31 +05301655 logger.Warnw("can-not-remove-flow-from-device--unreachable",
1656 log.Fields{
1657 "err": err,
1658 "deviceFlow": deviceFlow,
1659 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001660 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001661 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001662 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001663 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001664
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001665 }
Matteo Scandolo92186242020-06-12 10:54:18 -07001666 logger.Infow("flow-removed-from-device-successfully", log.Fields{
1667 "of-flow-id": ofFlowID,
1668 "flow": *deviceFlow,
1669 "device-id": f.deviceHandler.device.Id,
1670 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001671 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301672}
1673
David K. Bainbridge794735f2020-02-11 21:01:37 -08001674func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001675
1676 classifierInfo := make(map[string]interface{})
1677 actionInfo := make(map[string]interface{})
1678
1679 classifierInfo[EthType] = uint32(LldpEthType)
1680 classifierInfo[PacketTagType] = Untagged
1681 actionInfo[TrapToHost] = true
1682
1683 // LLDP flow is installed to trap LLDP packets on the NNI port.
1684 // We manage flow_id resource pool on per PON port basis.
1685 // Since this situation is tricky, as a hack, we pass the NNI port
1686 // index (network_intf_id) as PON port Index for the flow_id resource
1687 // pool. Also, there is no ONU Id available for trapping LLDP packets
1688 // on NNI port, use onu_id as -1 (invalid)
1689 // ****************** CAVEAT *******************
1690 // This logic works if the NNI Port Id falls within the same valid
1691 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1692 // we need to have a re-look at this.
1693 // *********************************************
1694
1695 var onuID = -1
1696 var uniID = -1
1697 var gemPortID = -1
1698
David K. Bainbridge794735f2020-02-11 21:01:37 -08001699 networkInterfaceID, err := IntfIDFromNniPortNum(portNo)
1700 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301701 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001702 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001703 var flowStoreCookie = getFlowStoreCookie(classifierInfo, uint32(0))
npujarec5762e2020-01-01 14:08:48 +05301704 if present := f.resourceMgr.IsFlowCookieOnKVStore(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), flowStoreCookie); present {
Shrey Baid26912972020-04-16 21:02:31 +05301705 logger.Infow("flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001706 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001707 }
npujarec5762e2020-01-01 14:08:48 +05301708 flowID, err := f.resourceMgr.GetFlowID(ctx, uint32(networkInterfaceID), int32(onuID), int32(uniID), uint32(gemPortID), flowStoreCookie, "", 0)
Humera Kouser94d7a842019-08-25 19:04:32 -04001709
1710 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301711 return olterrors.NewErrNotFound("flow-id",
1712 log.Fields{
1713 "interface-id": networkInterfaceID,
1714 "onu-id": onuID,
1715 "uni-id": uniID,
1716 "gem-port-id": gemPortID,
1717 "cookie": flowStoreCookie,
1718 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001719 err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001720 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001721 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1722 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301723 return olterrors.NewErrInvalidValue(
1724 log.Fields{
1725 "classifier": classifierInfo,
1726 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001727 }
Shrey Baid26912972020-04-16 21:02:31 +05301728 logger.Debugw("created-classifier-proto",
1729 log.Fields{
1730 "classifier": *classifierProto,
1731 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001732 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001733 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301734 return olterrors.NewErrInvalidValue(
1735 log.Fields{
1736 "action": actionInfo,
1737 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001738 }
Shrey Baid26912972020-04-16 21:02:31 +05301739 logger.Debugw("created-action-proto",
1740 log.Fields{
1741 "action": *actionProto,
1742 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001743
1744 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1745 OnuId: int32(onuID), // OnuId not required
1746 UniId: int32(uniID), // UniId not used
1747 FlowId: flowID,
1748 FlowType: Downstream,
1749 NetworkIntfId: int32(networkInterfaceID),
1750 GemportId: int32(gemPortID),
1751 Classifier: classifierProto,
1752 Action: actionProto,
1753 Priority: int32(flow.Priority),
1754 Cookie: flow.Cookie,
1755 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001756 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301757 return olterrors.NewErrFlowOp("add", flowID,
1758 log.Fields{
1759 "flow": downstreamflow,
1760 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001761 }
Shrey Baid26912972020-04-16 21:02:31 +05301762 logger.Infow("lldp-trap-on-nni-flow-added-to-device-successfully",
1763 log.Fields{
1764 "device-id": f.deviceHandler.device.Id,
1765 "onu-id": onuID,
1766 "flow-id": flowID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001767 flowsToKVStore := f.getUpdatedFlowInfo(ctx, &downstreamflow, flowStoreCookie, "", flowID, flow.Id)
1768 if err := f.updateFlowInfoToKVStore(ctx, int32(networkInterfaceID),
1769 int32(onuID),
1770 int32(uniID),
1771 flowID, flowsToKVStore); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301772 return olterrors.NewErrPersistence("update", "flow", flowID,
1773 log.Fields{
1774 "flow": downstreamflow,
1775 "device-id": f.deviceHandler.device.Id}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001776 }
1777 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301778}
1779
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001780func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1781 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001782}
1783
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001784//getOnuDevice to fetch onu from cache or core.
1785func (f *OpenOltFlowMgr) getOnuDevice(intfID uint32, onuID uint32) (*OnuDevice, error) {
1786 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1787 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1788 if !ok {
Shrey Baid26912972020-04-16 21:02:31 +05301789 logger.Debugw("couldnt-find-onu-in-cache",
1790 log.Fields{
1791 "intf-id": intfID,
1792 "onu-id": onuID,
1793 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001794 onuDevice, err := f.getChildDevice(intfID, onuID)
1795 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301796 return nil, olterrors.NewErrNotFound("onu-child-device",
1797 log.Fields{
1798 "onu-id": onuID,
1799 "intf-id": intfID,
1800 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001801 }
1802 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1803 //better to ad the device to cache here.
1804 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1805 } else {
Shrey Baid26912972020-04-16 21:02:31 +05301806 logger.Debugw("found-onu-in-cache",
1807 log.Fields{
1808 "intf-id": intfID,
1809 "onu-id": onuID,
1810 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001811 }
1812
1813 return onuDev.(*OnuDevice), nil
1814}
1815
1816//getChildDevice to fetch onu
1817func (f *OpenOltFlowMgr) getChildDevice(intfID uint32, onuID uint32) (*voltha.Device, error) {
Shrey Baid26912972020-04-16 21:02:31 +05301818 logger.Infow("GetChildDevice",
1819 log.Fields{
1820 "pon-port": intfID,
1821 "onu-id": onuID,
1822 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001823 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001824 onuDevice, err := f.deviceHandler.GetChildDevice(parentPortNo, onuID)
1825 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301826 return nil, olterrors.NewErrNotFound("onu",
1827 log.Fields{
1828 "interface-id": parentPortNo,
1829 "onu-id": onuID,
1830 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001831 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301832 }
Shrey Baid26912972020-04-16 21:02:31 +05301833 logger.Infow("successfully-received-child-device-from-core",
1834 log.Fields{
1835 "device-id": f.deviceHandler.device.Id,
1836 "child_device_id": onuDevice.Id,
1837 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301838 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301839}
1840
1841func findNextFlow(flow *ofp.OfpFlowStats) *ofp.OfpFlowStats {
Shrey Baid26912972020-04-16 21:02:31 +05301842 logger.Info("unimplemented-flow %v", flow)
manikkaraj kbf256be2019-03-25 00:13:48 +05301843 return nil
1844}
1845
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001846func (f *OpenOltFlowMgr) clearFlowsAndSchedulerForLogicalPort(childDevice *voltha.Device, logicalPort *voltha.LogicalPort) {
Shrey Baid26912972020-04-16 21:02:31 +05301847 logger.Info("unimplemented-device %v, logicalport %v", childDevice, logicalPort)
manikkaraj kbf256be2019-03-25 00:13:48 +05301848}
1849
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001850func (f *OpenOltFlowMgr) decodeStoredID(id uint64) (uint64, string) {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001851 if id>>15 == 0x1 {
David K. Bainbridge82efc492019-09-04 09:57:11 -07001852 return id & 0x7fff, Upstream
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001853 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001854 return id, Downstream
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001855}
1856
Girish Gowdra6b130582019-11-20 16:45:20 +05301857func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001858 onuDev, err := f.getOnuDevice(intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301859 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301860 logger.Debugw("couldnt-find-onu-child-device",
1861 log.Fields{
1862 "intf-id": intfID,
1863 "onu-id": onuID,
1864 "uni-id": uniID,
1865 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001866 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301867 }
1868
1869 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
Shrey Baid26912972020-04-16 21:02:31 +05301870 logger.Debugw("sending-gem-port-delete-to-openonu-adapter",
1871 log.Fields{
1872 "msg": *delGemPortMsg,
1873 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301874 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(context.Background(),
1875 delGemPortMsg,
1876 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301877 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001878 onuDev.deviceType,
1879 onuDev.deviceID,
1880 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301881 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1882 log.Fields{
1883 "from-adapter": f.deviceHandler.device.Type,
1884 "to-adapter": onuDev.deviceType,
1885 "onu-id": onuDev.deviceID,
1886 "proxyDeviceID": onuDev.proxyDeviceID,
1887 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301888 }
Shrey Baid26912972020-04-16 21:02:31 +05301889 logger.Infow("success-sending-del-gem-port-to-onu-adapter",
1890 log.Fields{
1891 "msg": delGemPortMsg,
1892 "from-adapter": f.deviceHandler.device.Type,
1893 "to-adapter": onuDev.deviceType,
1894 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301895 return nil
1896}
1897
1898func (f *OpenOltFlowMgr) sendDeleteTcontToChild(intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001899 onuDev, err := f.getOnuDevice(intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301900 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301901 logger.Warnw("couldnt-find-onu-child-device",
1902 log.Fields{
1903 "intf-id": intfID,
1904 "onu-id": onuID,
1905 "uni-id": uniID,
1906 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001907 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301908 }
1909
1910 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
Shrey Baid26912972020-04-16 21:02:31 +05301911 logger.Debugw("sending-tcont-delete-to-openonu-adapter",
1912 log.Fields{
1913 "msg": *delTcontMsg,
1914 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301915 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(context.Background(),
1916 delTcontMsg,
1917 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301918 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001919 onuDev.deviceType,
1920 onuDev.deviceID,
1921 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301922 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1923 log.Fields{
1924 "from-adapter": f.deviceHandler.device.Type,
1925 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1926 "proxyDeviceID": onuDev.proxyDeviceID,
1927 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301928 }
Shrey Baid26912972020-04-16 21:02:31 +05301929 logger.Infow("success-sending-del-tcont-to-onu-adapter",
1930 log.Fields{
1931 "msg": delTcontMsg,
1932 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301933 return nil
1934}
1935
Girish Gowdra3d633032019-12-10 16:37:05 +05301936func (f *OpenOltFlowMgr) deletePendingFlows(Intf uint32, onuID int32, uniID int32) {
1937 pnFlDelKey := pendingFlowDeleteKey{Intf, uint32(onuID), uint32(uniID)}
1938 if val, ok := f.pendingFlowDelete.Load(pnFlDelKey); ok {
1939 if val.(int) > 0 {
1940 pnFlDels := val.(int) - 1
1941 if pnFlDels > 0 {
Shrey Baid26912972020-04-16 21:02:31 +05301942 logger.Debugw("flow-delete-succeeded--more-pending",
1943 log.Fields{
1944 "intf": Intf,
1945 "onu-id": onuID,
1946 "uni-id": uniID,
1947 "currpendingflowcnt": pnFlDels,
1948 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +05301949 f.pendingFlowDelete.Store(pnFlDelKey, pnFlDels)
1950 } else {
Shrey Baid26912972020-04-16 21:02:31 +05301951 logger.Debugw("all-pending-flow-deletes-handled--removing-entry-from-map",
1952 log.Fields{
1953 "intf": Intf,
1954 "onu-id": onuID,
1955 "uni-id": uniID,
1956 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +05301957 f.pendingFlowDelete.Delete(pnFlDelKey)
1958 }
1959 }
1960 } else {
Shrey Baid26912972020-04-16 21:02:31 +05301961 logger.Debugw("no-pending-delete-flows-found",
1962 log.Fields{
1963 "intf": Intf,
1964 "onu-id": onuID,
1965 "uni-id": uniID,
1966 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +05301967
1968 }
1969
1970}
1971
Girish Gowdrac3037402020-01-22 20:29:53 +05301972// Once the gemport is released for a given onu, it also has to be cleared from local cache
1973// which was used for deriving the gemport->logicalPortNo during packet-in.
1974// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1975// is conveyed to ONOS during packet-in OF message.
1976func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(intfID uint32, onuID uint32, gemPortID uint32) {
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001977
Matteo Scandolo60913ed2020-06-23 19:31:14 -07001978 f.onuGemInfoLock.Lock()
1979 defer f.onuGemInfoLock.Unlock()
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001980
Shrey Baid26912972020-04-16 21:02:31 +05301981 logger.Infow("deleting-gem-from-local-cache",
1982 log.Fields{
Matteo Scandolo60913ed2020-06-23 19:31:14 -07001983 "gem-port-id": gemPortID,
1984 "intf-id": intfID,
1985 "onu-id": onuID,
1986 "device-id": f.deviceHandler.device.Id,
1987 "onu-gem": f.onuGemInfo[intfID]})
Girish Gowdrac3037402020-01-22 20:29:53 +05301988 onugem := f.onuGemInfo[intfID]
Matteo Scandolo60913ed2020-06-23 19:31:14 -07001989deleteLoop:
serkant.uluderya96af4932020-02-20 16:58:48 -08001990 for i, onu := range onugem {
Girish Gowdrac3037402020-01-22 20:29:53 +05301991 if onu.OnuID == onuID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001992 for j, gem := range onu.GemPorts {
Girish Gowdrac3037402020-01-22 20:29:53 +05301993 // If the gemport is found, delete it from local cache.
1994 if gem == gemPortID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001995 onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
1996 onugem[i] = onu
Shrey Baid26912972020-04-16 21:02:31 +05301997 logger.Infow("removed-gemport-from-local-cache",
1998 log.Fields{
1999 "intf-id": intfID,
2000 "onu-id": onuID,
2001 "deletedgemport-id": gemPortID,
2002 "gemports": onu.GemPorts,
2003 "device-id": f.deviceHandler.device.Id})
Matteo Scandolo60913ed2020-06-23 19:31:14 -07002004 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05302005 }
2006 }
Matteo Scandolo60913ed2020-06-23 19:31:14 -07002007 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05302008 }
2009 }
2010}
2011
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05302012//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07002013// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +05302014func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05302015 gemPortID int32, flowID uint32, flowDirection string,
2016 portNum uint32, updatedFlows []rsrcMgr.FlowInfo) error {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04002017
Chaitrashree G S90a17952019-11-14 21:51:21 -05002018