blob: b936a90bdde633962742dc0db97e972f8c4df597 [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"
Matteo Scandolo6056e822019-11-13 14:05:29 -080022 "encoding/hex"
Girish Gowdracefae192020-03-19 18:14:10 -070023 "errors"
manikkaraj kbf256be2019-03-25 00:13:48 +053024 "fmt"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070025 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
26 "github.com/opencord/voltha-lib-go/v4/pkg/log"
27 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080028 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070029 "github.com/opencord/voltha-protos/v4/go/common"
30 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
31 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
32 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
33 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
34 "github.com/opencord/voltha-protos/v4/go/voltha"
Girish Gowdra9602eb42020-09-09 15:50:39 -070035 "strings"
36 "sync"
Chaitrashree G S579fe732019-08-20 20:50:47 -040037
Girish Gowdra3d633032019-12-10 16:37:05 +053038 "github.com/EagleChen/mapmutex"
Thomas Lee S94109f12020-03-03 16:39:29 +053039 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000040 "google.golang.org/grpc/codes"
41 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053042)
43
44const (
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070045 //IPProtoDhcp flow category
46 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053047
Girish Gowdraa09aeab2020-09-14 16:30:52 -070048 //IgmpProto proto value
49 IgmpProto = 2
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070050
51 //EapEthType eapethtype value
52 EapEthType = 0x888e
53 //LldpEthType lldp ethtype value
54 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000055 //IPv4EthType IPv4 ethernet type value
56 IPv4EthType = 0x800
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070057
Andrea Campanella7acc0b92020-02-14 09:20:49 +010058 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
59 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040060
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070061 //DefaultMgmtVlan default vlan value
62 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053063
manikkaraj kbf256be2019-03-25 00:13:48 +053064 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070065
David K. Bainbridge82efc492019-09-04 09:57:11 -070066 //Upstream constant
67 Upstream = "upstream"
68 //Downstream constant
69 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000070 //Multicast constant
71 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070072 //PacketTagType constant
73 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070074 //Untagged constant
75 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070076 //SingleTag constant
77 SingleTag = "single_tag"
78 //DoubleTag constant
79 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053080
81 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070082
83 //EthType constant
84 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000085 //EthDst constant
86 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070087 //TPID constant
88 TPID = "tpid"
89 //IPProto constant
90 IPProto = "ip_proto"
91 //InPort constant
92 InPort = "in_port"
93 //VlanVid constant
94 VlanVid = "vlan_vid"
95 //VlanPcp constant
96 VlanPcp = "vlan_pcp"
97
98 //UDPDst constant
99 UDPDst = "udp_dst"
100 //UDPSrc constant
101 UDPSrc = "udp_src"
102 //Ipv4Dst constant
103 Ipv4Dst = "ipv4_dst"
104 //Ipv4Src constant
105 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700106 //Metadata constant
107 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700108 //TunnelID constant
109 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700110 //Output constant
111 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000112 //GroupID constant
113 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114 // Actions
115
116 //PopVlan constant
117 PopVlan = "pop_vlan"
118 //PushVlan constant
119 PushVlan = "push_vlan"
120 //TrapToHost constant
121 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400122 //MaxMeterBand constant
123 MaxMeterBand = 2
124 //VlanPCPMask contant
125 VlanPCPMask = 0xFF
126 //VlanvIDMask constant
127 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000128 //IntfID constant
129 IntfID = "intfId"
130 //OnuID constant
131 OnuID = "onuId"
132 //UniID constant
133 UniID = "uniId"
134 //PortNo constant
135 PortNo = "portNo"
136 //AllocID constant
137 AllocID = "allocId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000138
139 //NoneOnuID constant
140 NoneOnuID = -1
141 //NoneUniID constant
142 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700143
144 // MapMutex
145 maxRetry = 300
146 maxDelay = 100000000
147 baseDelay = 10000000
148 factor = 1.1
149 jitter = 0.2
manikkaraj kbf256be2019-03-25 00:13:48 +0530150
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700151 bitMapPrefix = "0b"
152 pbit1 = '1'
153)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400154
Girish Gowdra3d633032019-12-10 16:37:05 +0530155type tpLockKey struct {
156 intfID uint32
157 onuID uint32
158 uniID uint32
159}
160
Gamze Abakafee36392019-10-03 11:17:24 +0000161type schedQueue struct {
162 direction tp_pb.Direction
163 intfID uint32
164 onuID uint32
165 uniID uint32
166 tpID uint32
167 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700168 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000169 meterID uint32
170 flowMetadata *voltha.FlowMetadata
171}
172
Girish Gowdra9602eb42020-09-09 15:50:39 -0700173// pendingFlowRemoveDataKey is key to pendingFlowRemoveDataPerSubscriber map
174type pendingFlowRemoveDataKey struct {
175 intfID uint32
176 onuID uint32
177 uniID uint32
178}
179
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700180// subscriberDataPathFlowIDKey is key to subscriberDataPathFlowIDMap map
181type subscriberDataPathFlowIDKey struct {
182 intfID uint32
183 onuID uint32
184 uniID uint32
185 direction string
186 tpID uint32
187}
188
Girish Gowdra9602eb42020-09-09 15:50:39 -0700189// pendingFlowRemoveData is value stored in pendingFlowRemoveDataPerSubscriber map
190// This holds the number of pending flow removes and also a signal channel to
191// to indicate the receiver when all flow removes are handled
192type pendingFlowRemoveData struct {
193 pendingFlowRemoveCount uint32
194 allFlowsRemoved chan struct{}
Esin Karamanccb714b2019-11-29 15:02:06 +0000195}
196
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700197//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530198type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700199 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
200 techprofile map[uint32]tp.TechProfileIf
201 deviceHandler *DeviceHandler
202 grpMgr *OpenOltGroupMgr
203 resourceMgr *rsrcMgr.OpenOltResourceMgr
204
205 onuIdsLock sync.RWMutex // TODO: Do we need this?
206
207 flowsUsedByGemPort map[uint32][]uint64 // gem port id to flow ids
208 flowsUsedByGemPortKey sync.RWMutex // lock to be used to access the flowsUsedByGemPort map
209
210 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
211 packetInGemPortLock sync.RWMutex
212
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700213 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700214 onuGemInfo []rsrcMgr.OnuGemInfo //onu, gem and uni info local cache
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700215 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700216 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700217
Girish Gowdra3d633032019-12-10 16:37:05 +0530218 // The mapmutex.Mutex can be fine tuned to use mapmutex.NewCustomizedMapMutex
Girish Gowdra9602eb42020-09-09 15:50:39 -0700219 perUserFlowHandleLock *mapmutex.Mutex
220
221 // pendingFlowRemoveDataPerSubscriber map is used to maintain the context on a per
222 // subscriber basis for the number of pending flow removes. This data is used
223 // to process all the flow removes for a subscriber before handling flow adds.
224 // Interleaving flow delete and flow add processing has known to cause PON resource
225 // management contentions on a per subscriber bases, so we need ensure ordering.
226 pendingFlowRemoveDataPerSubscriber map[pendingFlowRemoveDataKey]pendingFlowRemoveData
227 pendingFlowRemoveDataPerSubscriberLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700228
229 // Map of voltha flowID associated with subscriberDataPathFlowIDKey
230 // This information is not persisted on Kv store and hence should be reconciled on adapter restart
231 subscriberDataPathFlowIDMap map[subscriberDataPathFlowIDKey]uint64
232 subscriberDataPathFlowIDMapLock sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +0530233}
234
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700235//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700236func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000237 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530238 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530239 var err error
240 var idx uint32
241
manikkaraj kbf256be2019-03-25 00:13:48 +0530242 flowMgr.deviceHandler = dh
Girish Gowdra9602eb42020-09-09 15:50:39 -0700243 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530244 flowMgr.resourceMgr = rMgr
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000245 flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000246 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
247 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"error": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530248 return nil
249 }
William Kurkian740a09c2019-10-23 17:07:38 -0400250 flowMgr.onuIdsLock = sync.RWMutex{}
Girish Gowdra9602eb42020-09-09 15:50:39 -0700251 flowMgr.pendingFlowRemoveDataPerSubscriberLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700252 flowMgr.flowsUsedByGemPort = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530253 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700254 flowMgr.packetInGemPortLock = sync.RWMutex{}
Girish Gowdra1183b4d2020-08-25 16:12:01 -0700255 flowMgr.onuGemInfoLock = sync.RWMutex{}
Girish Gowdra1183b4d2020-08-25 16:12:01 -0700256 flowMgr.perUserFlowHandleLock = mapmutex.NewCustomizedMapMutex(maxRetry, maxDelay, baseDelay, factor, jitter)
Girish Gowdra9602eb42020-09-09 15:50:39 -0700257 flowMgr.pendingFlowRemoveDataPerSubscriber = make(map[pendingFlowRemoveDataKey]pendingFlowRemoveData)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700258 flowMgr.subscriberDataPathFlowIDMap = make(map[subscriberDataPathFlowIDKey]uint64)
259 flowMgr.subscriberDataPathFlowIDMapLock = sync.RWMutex{}
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530260 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700261 if flowMgr.onuGemInfo, err = rMgr.GetOnuGemInfo(ctx, ponPortIdx); err != nil {
262 logger.Error(ctx, "failed-to-load-onu-gem-info-cache")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530263 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700264 //Load flowID list per gem map per interface from the kvstore.
265 flowMgr.loadFlowIDlistForGem(ctx, idx)
Esin Karamanccb714b2019-11-29 15:02:06 +0000266 //load interface to multicast queue map from kv store
Girish Gowdra9602eb42020-09-09 15:50:39 -0700267 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700268 flowMgr.reconcileSubscriberDataPathFlowIDMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530270 return &flowMgr
271}
272
Kent Hagermane6ff1012020-07-14 15:07:53 -0400273func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700274 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
275 // Flow is not replicated in this case, we need to register the flow for a single gem-port
276 return f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
277 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
278 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
279 for _, gemPort := range deviceFlow.PbitToGemport {
280 if err := f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
281 return err
282 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700283 }
Gamze Abakafee36392019-10-03 11:17:24 +0000284 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700285 return nil
286}
287
288func (f *OpenOltFlowMgr) registerFlowIDForGem(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
289 f.flowsUsedByGemPortKey.Lock()
290 flowIDList, ok := f.flowsUsedByGemPort[gemPortID]
291 if !ok {
292 flowIDList = []uint64{flowFromCore.Id}
293 }
294 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
295 f.flowsUsedByGemPort[gemPortID] = flowIDList
296 f.flowsUsedByGemPortKey.Unlock()
297
298 // update the flowids for a gem to the KVstore
299 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400300}
301
Girish Gowdra9602eb42020-09-09 15:50:39 -0700302func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000303 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200304 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000305 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530306 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700307 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530308
Neha Sharma96b7bf22020-06-15 10:37:32 +0000309 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530310 "device-id": f.deviceHandler.device.Id,
311 "intf-id": intfID,
312 "onu-id": onuID,
313 "uni-id": uniID,
314 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700315 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530316 "action": actionInfo,
317 "usmeter-iD": UsMeterID,
318 "dsmeter-iD": DsMeterID,
319 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400320 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
321 // is because the flow is an NNI flow and there would be no onu resources associated with it
322 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400323 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200324 cause := "no-onu-id-for-flow"
325 fields := log.Fields{
326 "onu": onuID,
327 "port-no": portNo,
328 "classifer": classifierInfo,
329 "action": actionInfo,
330 "device-id": f.deviceHandler.device.Id}
331 logger.Errorw(ctx, cause, fields)
332 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530333 }
334
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700335 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000336 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530337 "uni": uni,
338 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530339
340 tpLockMapKey := tpLockKey{intfID, onuID, uniID}
341 if f.perUserFlowHandleLock.TryLock(tpLockMapKey) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000342 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530343 "device-id": f.deviceHandler.device.Id,
344 "intf-id": intfID,
345 "onu-id": onuID,
346 "uni-id": uniID,
347 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700348 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530349 "action": actionInfo,
350 "usmeter-id": UsMeterID,
351 "dsmeter-id": DsMeterID,
352 "tp-id": TpID})
npujarec5762e2020-01-01 14:08:48 +0530353 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
Girish Gowdra3d633032019-12-10 16:37:05 +0530354 if allocID == 0 || gemPorts == nil || TpInst == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000355 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
Girish Gowdra3d633032019-12-10 16:37:05 +0530356 f.perUserFlowHandleLock.Unlock(tpLockMapKey)
Andrea Campanellabfe08432020-09-11 17:07:03 +0200357 return olterrors.NewErrNotFound(
358 "alloc-id-gem-ports-tp-unavailable",
359 nil, nil)
Girish Gowdra3d633032019-12-10 16:37:05 +0530360 }
361 args := make(map[string]uint32)
362 args[IntfID] = intfID
363 args[OnuID] = onuID
364 args[UniID] = uniID
365 args[PortNo] = portNo
366 args[AllocID] = allocID
367
368 /* Flows can be added specific to gemport if p-bits are received.
369 * If no pbit mentioned then adding flows for all gemports
370 */
npujarec5762e2020-01-01 14:08:48 +0530371 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
Girish Gowdra3d633032019-12-10 16:37:05 +0530372 f.perUserFlowHandleLock.Unlock(tpLockMapKey)
373 } else {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200374 cause := "failed-to-acquire-per-user-flow-handle-lock"
375 fields := log.Fields{
376 "intf-id": intfID,
377 "onu-id": onuID,
378 "uni-id": uniID,
379 "flow-id": flow.Id,
380 "flow-cookie": flow.Cookie,
381 "device-id": f.deviceHandler.device.Id}
382 logger.Errorw(ctx, cause, fields)
383 return olterrors.NewErrAdapter(cause, fields, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400384 }
Andrea Campanellabfe08432020-09-11 17:07:03 +0200385 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530386}
387
salmansiddiqui7ac62132019-08-22 03:58:50 +0000388// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530389func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400390
Neha Sharma96b7bf22020-06-15 10:37:32 +0000391 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530392 log.Fields{"dir": sq.direction,
393 "intf-id": sq.intfID,
394 "onu-id": sq.onuID,
395 "uni-id": sq.uniID,
396 "tp-id": sq.tpID,
397 "meter-id": sq.meterID,
398 "tp-inst": sq.tpInst,
399 "flowmetadata": sq.flowMetadata,
400 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400401
Gamze Abakafee36392019-10-03 11:17:24 +0000402 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000403 if err != nil {
404 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400405 }
406
407 /* Lets make a simple assumption that if the meter-id is present on the KV store,
408 * then the scheduler and queues configuration is applied on the OLT device
409 * in the given direction.
410 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000411
Manikkaraj kb1d51442019-07-23 10:41:02 -0400412 var SchedCfg *tp_pb.SchedulerConfig
npujarec5762e2020-01-01 14:08:48 +0530413 KvStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400414 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530415 return olterrors.NewErrNotFound("meter",
416 log.Fields{"intf-id": sq.intfID,
417 "onu-id": sq.onuID,
418 "uni-id": sq.uniID,
419 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400420 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000421
Manikkaraj kb1d51442019-07-23 10:41:02 -0400422 if KvStoreMeter != nil {
Gamze Abakafee36392019-10-03 11:17:24 +0000423 if KvStoreMeter.MeterId == sq.meterID {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000424 logger.Debugw(ctx, "scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400425 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400426 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530427 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800428 "unsupported": "meter-id",
429 "kv-store-meter-id": KvStoreMeter.MeterId,
Shrey Baid26912972020-04-16 21:02:31 +0530430 "meter-id-in-flow": sq.meterID,
431 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400432 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000433
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530435 log.Fields{
436 "meter-id": sq.meterID,
437 "direction": Direction,
438 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000439
Gamze Abakafee36392019-10-03 11:17:24 +0000440 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000441 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Gamze Abakafee36392019-10-03 11:17:24 +0000442 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000443 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400444 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000445
446 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530447 return olterrors.NewErrNotFound("scheduler-config",
448 log.Fields{
449 "intf-id": sq.intfID,
450 "direction": sq.direction,
451 "tp-inst": sq.tpInst,
452 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000453 }
454
Manikkaraj kb1d51442019-07-23 10:41:02 -0400455 var meterConfig *ofp.OfpMeterConfig
Gamze Abakafee36392019-10-03 11:17:24 +0000456 if sq.flowMetadata != nil {
457 for _, meter := range sq.flowMetadata.Meters {
458 if sq.meterID == meter.MeterId {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400459 meterConfig = meter
Neha Sharma96b7bf22020-06-15 10:37:32 +0000460 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Shrey Baid26912972020-04-16 21:02:31 +0530461 log.Fields{"meterConfig": meterConfig,
462 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400463 break
464 }
465 }
466 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000467 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400468 }
469 if meterConfig == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530470 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800471 "reason": "Could-not-get-meterbands-from-flowMetadata",
472 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530473 "meter-id": sq.meterID,
474 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400475 } else if len(meterConfig.Bands) < MaxMeterBand {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000476 logger.Errorw(ctx, "invalid-number-of-bands-in-meter",
Shrey Baid26912972020-04-16 21:02:31 +0530477 log.Fields{"Bands": meterConfig.Bands,
478 "meter-id": sq.meterID,
479 "device-id": f.deviceHandler.device.Id})
Thomas Lee S94109f12020-03-03 16:39:29 +0530480 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800481 "reason": "Invalid-number-of-bands-in-meter",
482 "meterband-count": len(meterConfig.Bands),
483 "metabands": meterConfig.Bands,
Shrey Baid26912972020-04-16 21:02:31 +0530484 "meter-id": sq.meterID,
485 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400486 }
487 cir := meterConfig.Bands[0].Rate
488 cbs := meterConfig.Bands[0].BurstSize
489 eir := meterConfig.Bands[1].Rate
490 ebs := meterConfig.Bands[1].BurstSize
491 pir := cir + eir
492 pbs := cbs + ebs
493 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
494
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700495 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000496 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400497
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700498 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530499 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
500 log.Fields{"intf-id": sq.intfID,
501 "direction": sq.direction,
502 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400503 }
504
salmansiddiqui7ac62132019-08-22 03:58:50 +0000505 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400506 * store the meter id on the KV store, for further reference.
507 */
npujarec5762e2020-01-01 14:08:48 +0530508 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 +0530509 return olterrors.NewErrAdapter("failed-updating-meter-id",
510 log.Fields{"onu-id": sq.onuID,
511 "meter-id": sq.meterID,
512 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400513 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000514 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530515 log.Fields{"direction": Direction,
516 "Meter": meterConfig,
517 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400518 return nil
519}
520
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700521func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000523
524 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530525 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
526 log.Fields{"intf-id": sq.intfID,
527 "direction": sq.direction,
528 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000529 }
530
Neha Sharma96b7bf22020-06-15 10:37:32 +0000531 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530532 log.Fields{
533 "direction": sq.direction,
534 "TrafficScheds": TrafficSched,
535 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530536 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Girish Kumar8f73fe02019-12-09 13:19:37 +0000537 IntfId: sq.intfID, OnuId: sq.onuID,
538 UniId: sq.uniID, PortNo: sq.uniPort,
539 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000540 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000541 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000542 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530543 "direction": sq.direction,
544 "traffic-queues": trafficQueues,
545 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000546
547 // On receiving the CreateTrafficQueues request, the driver should create corresponding
548 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000549 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530550 log.Fields{"direction": sq.direction,
551 "traffic-queues": trafficQueues,
552 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530553 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000554 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
555 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000556 TrafficQueues: trafficQueues,
557 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530558 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000559 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530561 "direction": sq.direction,
562 "traffic-queues": trafficQueues,
563 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000564
Esin Karamanccb714b2019-11-29 15:02:06 +0000565 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000566 multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile))
Esin Karamanccb714b2019-11-29 15:02:06 +0000567 if len(multicastTrafficQueues) > 0 {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700568 if _, present := f.grpMgr.GetInterfaceToMcastQueueMap(sq.intfID); !present {
Esin Karamanccb714b2019-11-29 15:02:06 +0000569 //assumed that there is only one queue per PON for the multicast service
570 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
571 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000573 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700574 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000575 gemPortID: multicastQueuePerPonPort.GemportId,
576 servicePriority: multicastQueuePerPonPort.Priority,
577 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700578 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000579 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400580 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
581 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"error": err})
582 return err
583 }
Shrey Baid26912972020-04-16 21:02:31 +0530584
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000586 }
587 }
588 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000589 return nil
590}
591
salmansiddiqui7ac62132019-08-22 03:58:50 +0000592// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530593func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400594
595 var Direction string
596 var SchedCfg *tp_pb.SchedulerConfig
597 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000598 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530599 log.Fields{
600 "direction": sq.direction,
601 "intf-id": sq.intfID,
602 "onu-id": sq.onuID,
603 "uni-id": sq.uniID,
604 "uni-port": sq.uniPort,
605 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000606 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000607 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400608 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000609 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000610 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400611 Direction = "downstream"
612 }
613
Girish Kumar8f73fe02019-12-09 13:19:37 +0000614 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530615 return olterrors.NewErrNotFound("scheduler-config",
616 log.Fields{
617 "int-id": sq.intfID,
618 "direction": sq.direction,
619 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000620 }
621
npujarec5762e2020-01-01 14:08:48 +0530622 KVStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400623 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530624 return olterrors.NewErrNotFound("meter",
625 log.Fields{
626 "onu-id": sq.onuID,
627 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400628 }
629 if KVStoreMeter == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000630 logger.Warnw(ctx, "no-meter-installed-yet",
Shrey Baid26912972020-04-16 21:02:31 +0530631 log.Fields{
632 "direction": Direction,
633 "intf-id": sq.intfID,
634 "onu-id": sq.onuID,
635 "uni-id": sq.uniID,
636 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400637 return nil
638 }
639 cir := KVStoreMeter.Bands[0].Rate
640 cbs := KVStoreMeter.Bands[0].BurstSize
641 eir := KVStoreMeter.Bands[1].Rate
642 ebs := KVStoreMeter.Bands[1].BurstSize
643 pir := cir + eir
644 pbs := cbs + ebs
645
646 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
647
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700648 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000649 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000650
Neha Sharma96b7bf22020-06-15 10:37:32 +0000651 TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000652 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530653 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
654 log.Fields{
655 "intf-id": sq.intfID,
656 "direction": sq.direction,
657 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000658 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400659
npujarec5762e2020-01-01 14:08:48 +0530660 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000661 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
662 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000663 TrafficQueues: TrafficQueues,
664 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000665 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530666 log.Fields{
667 "intf-id": sq.intfID,
668 "traffic-queues": TrafficQueues,
669 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000671 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530672 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Gamze Abakafee36392019-10-03 11:17:24 +0000673 IntfId: sq.intfID, OnuId: sq.onuID,
674 UniId: sq.uniID, PortNo: sq.uniPort,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400675 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000676 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530677 log.Fields{
678 "intf-id": sq.intfID,
679 "traffic-schedulers": TrafficSched}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400680 }
681
Neha Sharma96b7bf22020-06-15 10:37:32 +0000682 logger.Infow(ctx, "removed-traffic-schedulers-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000683
684 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400685 * delete the meter id on the KV store.
686 */
npujarec5762e2020-01-01 14:08:48 +0530687 err = f.resourceMgr.RemoveMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400688 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530689 return olterrors.NewErrAdapter("unable-to-remove-meter",
690 log.Fields{
691 "onu": sq.onuID,
692 "meter": KVStoreMeter.MeterId,
693 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400694 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000695 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530696 log.Fields{
697 "meter-id": KVStoreMeter.MeterId,
698 "dir": Direction,
699 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400700 return err
701}
702
Gamze Abakafee36392019-10-03 11:17:24 +0000703// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700704func (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 +0000705 var allocIDs []uint32
706 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530707 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530708 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000709 var err error
Gamze Abakafee36392019-10-03 11:17:24 +0000710
npujarec5762e2020-01-01 14:08:48 +0530711 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
712 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400713
Neha Sharma96b7bf22020-06-15 10:37:32 +0000714 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530715
Neha Sharma96b7bf22020-06-15 10:37:32 +0000716 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530717 "intf-id": intfID,
718 "onu-id": onuID,
719 "uni-id": uniID,
720 "device-id": f.deviceHandler.device.Id,
721 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530722
Manikkaraj kb1d51442019-07-23 10:41:02 -0400723 // Check tech profile instance already exists for derived port name
npujarec5762e2020-01-01 14:08:48 +0530724 techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000725 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000726 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530727 log.Fields{
728 "path": tpPath,
729 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530730 techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000731 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530732 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000733 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530734 log.Fields{
735 "error": err,
736 "tp-id": TpID,
737 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000738 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530739 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400740 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
741 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"error": err})
742 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530743 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000744 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530745 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 {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000757 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700758 log.Fields{
759 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700760 "onu-id": onuID,
761 "uni-id": uniID,
762 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700763 "meter-id": UsMeterID,
764 "device-id": f.deviceHandler.device.Id})
765 return 0, nil, nil
766 }
767 }
768 if DsMeterID != 0 {
769 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
770 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
771 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000772 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700773 log.Fields{
774 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700775 "onu-id": onuID,
776 "uni-id": uniID,
777 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700778 "meter-id": DsMeterID,
779 "device-id": f.deviceHandler.device.Id})
780 return 0, nil, nil
781 }
782 }
783 allocID := tpInst.UsScheduler.AllocID
784 for _, gem := range tpInst.UpstreamGemPortAttributeList {
785 gemPortIDs = append(gemPortIDs, gem.GemportID)
786 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700787 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000788
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700789 if tpInstanceExists {
790 return allocID, gemPortIDs, techProfileInstance
791 }
792
793 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700794 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700795 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000796 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700797 log.Fields{
798 "alloc-ids": allocIDs,
799 "gemports": allgemPortIDs,
800 "device-id": f.deviceHandler.device.Id})
801 // Send Tconts and GEM ports to KV store
802 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530803 return allocID, gemPortIDs, techProfileInstance
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700804 case *tp.EponProfile:
805 // CreateSchedulerQueues for EPON needs to be implemented here
806 // when voltha-protos for EPON is completed.
807 allocID := tpInst.AllocID
808 for _, gem := range tpInst.UpstreamQueueAttributeList {
809 gemPortIDs = append(gemPortIDs, gem.GemportID)
810 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700811 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700812
813 if tpInstanceExists {
814 return allocID, gemPortIDs, techProfileInstance
815 }
816
817 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700818 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700819 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000820 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700821 log.Fields{
822 "alloc-ids": allocIDs,
823 "gemports": allgemPortIDs,
824 "device-id": f.deviceHandler.device.Id})
825 // Send Tconts and GEM ports to KV store
826 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
827 return allocID, gemPortIDs, techProfileInstance
828 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000829 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700830 log.Fields{
831 "tpInst": tpInst})
832 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530833 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530834}
835
npujarec5762e2020-01-01 14:08:48 +0530836func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530837
Neha Sharma96b7bf22020-06-15 10:37:32 +0000838 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530839 log.Fields{
840 "intf-id": intfID,
841 "onu-id": onuID,
842 "uni-id": uniID,
843 "alloc-id": allocID,
844 "gemport-ids": gemPortIDs,
845 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530846 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530847 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000848 logger.Errorw(ctx, "error-while-uploading-allocid-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530849 }
npujarec5762e2020-01-01 14:08:48 +0530850 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000851 logger.Errorw(ctx, "error-while-uploading-gemports-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530852 }
npujarec5762e2020-01-01 14:08:48 +0530853 if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000854 logger.Error(ctx, "error-while-uploading-gemtopon-map-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530855 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000856 logger.Infow(ctx, "stored-tconts-and-gem-into-kv-store-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400857 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530858 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400859 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530860}
861
Neha Sharma96b7bf22020-06-15 10:37:32 +0000862func (f *OpenOltFlowMgr) populateTechProfilePerPonPort(ctx context.Context) error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000863 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530864 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000865 for _, intfID := range techRange.IntfIds {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700866 f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[intfID].TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400867 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000868 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530869 log.Fields{
870 "intf-id": intfID,
871 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530872 }
873 }
874 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400875 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530876 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530877 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800878 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530879 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
880 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530881 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000882 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530883 log.Fields{
884 "numofTech": tpCount,
885 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
886 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530887 return nil
888}
889
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700890func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530891 portNo uint32, uplinkClassifier map[string]interface{},
892 uplinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700893 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700894 uplinkClassifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000895 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530896 log.Fields{
897 "uplinkClassifier": uplinkClassifier,
898 "uplinkAction": uplinkAction})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700899 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, uplinkClassifier, uplinkAction,
900 Upstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
Manikkaraj k884c1242019-04-11 16:26:42 +0530901 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530902}
903
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700904func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530905 portNo uint32, downlinkClassifier map[string]interface{},
906 downlinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700907 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700908 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000909 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530910 log.Fields{
911 "downlinkClassifier": downlinkClassifier,
912 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400913 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
914 if vlan, exists := downlinkClassifier[VlanVid]; exists {
915 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700916 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Neha Sharma96b7bf22020-06-15 10:37:32 +0000917 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, intfID, onuID, uniID) {
918 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530919 log.Fields{
920 "flow": logicalFlow,
921 "device-id": f.deviceHandler.device.Id,
922 "onu-id": onuID,
923 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800924 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400925 }
926 }
927 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530928 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400929
Manikkaraj k884c1242019-04-11 16:26:42 +0530930 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700931 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400932 // vlan_vid is a uint32. must be type asserted as such or conversion fails
933 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530934 if ok {
935 downlinkAction[VlanVid] = dlClVid & 0xfff
936 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530937 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530938 "reason": "failed-to-convert-vlanid-classifier",
939 "vlan-id": VlanVid,
940 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530941 }
942
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700943 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, downlinkClassifier, downlinkAction,
944 Downstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
manikkaraj kbf256be2019-03-25 00:13:48 +0530945}
946
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700947func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Manikkaraj k884c1242019-04-11 16:26:42 +0530948 action map[string]interface{}, direction string, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700949 allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
950
951 var inverseDirection string
952 if direction == Upstream {
953 inverseDirection = Downstream
954 } else {
955 inverseDirection = Upstream
956 }
957
Neha Sharma96b7bf22020-06-15 10:37:32 +0000958 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530959 log.Fields{
960 "intf-id": intfID,
961 "onu-id": onuID,
962 "uni-id": uniID,
963 "device-id": f.deviceHandler.device.Id,
964 "classifier": classifier,
965 "action": action,
966 "direction": direction,
967 "alloc-id": allocID,
968 "gemport-id": gemPortID,
969 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700970
971 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000972 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +0530973 log.Fields{
974 "device-id": f.deviceHandler.device.Id,
975 "intf-id": intfID,
976 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800977 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530978 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800979 classifierProto, err := makeOpenOltClassifierField(classifier)
980 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530981 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530982 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000983 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530984 log.Fields{
985 "classifier": *classifierProto,
986 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +0000987 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800988 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530989 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530990 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000991 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530992 log.Fields{
993 "action": *actionProto,
994 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +0000995 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530996 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530997 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 log.Fields{
999 "classifier": classifier,
1000 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301001 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001002 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301003 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001004
1005 // Get symmetric flowID if it exists
1006 // This symmetric flowID will be needed by agent software to use the same device flow-id that was used for the
1007 // symmetric flow earlier
1008 // symmetric flowID 0 is considered by agent as non-existent symmetric flow
1009 keySymm := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: inverseDirection, tpID: tpID}
1010 f.subscriberDataPathFlowIDMapLock.RLock()
1011 symmFlowID := f.subscriberDataPathFlowIDMap[keySymm]
1012 f.subscriberDataPathFlowIDMapLock.RUnlock()
1013
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001014 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001015 OnuId: int32(onuID),
1016 UniId: int32(uniID),
1017 FlowId: logicalFlow.Id,
1018 FlowType: direction,
1019 AllocId: int32(allocID),
1020 NetworkIntfId: int32(networkIntfID),
1021 GemportId: int32(gemPortID),
1022 Classifier: classifierProto,
1023 Action: actionProto,
1024 Priority: int32(logicalFlow.Priority),
1025 Cookie: logicalFlow.Cookie,
1026 PortNo: portNo,
1027 TechProfileId: tpID,
1028 ReplicateFlow: len(pbitToGem) > 0,
1029 PbitToGemport: pbitToGem,
1030 SymmetricFlowId: symmFlowID,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001031 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001032 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001033 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301034 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301036 log.Fields{"direction": direction,
1037 "device-id": f.deviceHandler.device.Id,
1038 "flow": flow,
1039 "intf-id": intfID,
1040 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001041 flowInfo := rsrcMgr.FlowInfo{Flow: &flow, IsSymmtricFlow: true}
1042 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(flow.AccessIntfId), flow.OnuId, flow.UniId, flow.FlowId, flowInfo); err != nil {
1043 return olterrors.NewErrPersistence("update", "flow", logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301044 log.Fields{
1045 "flow": flow,
1046 "device-id": f.deviceHandler.device.Id,
1047 "intf-id": intfID,
1048 "onu-id": onuID}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001049 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001050
1051 // Update the current flowID to the map
1052 keyCurr := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: direction, tpID: tpID}
1053 f.subscriberDataPathFlowIDMapLock.Lock()
1054 f.subscriberDataPathFlowIDMap[keyCurr] = logicalFlow.Id
1055 f.subscriberDataPathFlowIDMapLock.Unlock()
1056
David K. Bainbridge794735f2020-02-11 21:01:37 -08001057 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301058}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001059
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001060func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1061 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001062 gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301063
Neha Sharma96b7bf22020-06-15 10:37:32 +00001064 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301065 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301066 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001067 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301068 "action": action,
1069 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001070 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301071 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301072
1073 // Clear the action map
1074 for k := range action {
1075 delete(action, k)
1076 }
1077
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001078 action[TrapToHost] = true
1079 classifier[UDPSrc] = uint32(68)
1080 classifier[UDPDst] = uint32(67)
1081 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301082
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001083 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001084 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301085 log.Fields{
1086 "device-id": f.deviceHandler.device.Id,
1087 "intf-id": intfID,
1088 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001089 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301090 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301091
Neha Sharma96b7bf22020-06-15 10:37:32 +00001092 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301093 log.Fields{
1094 "ul_classifier": classifier,
1095 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001096 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301097 "intf-id": intfID,
1098 "onu-id": onuID,
1099 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301100
David K. Bainbridge794735f2020-02-11 21:01:37 -08001101 classifierProto, err := makeOpenOltClassifierField(classifier)
1102 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301103 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301104 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001105 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001106 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001107 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301108 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301109 }
1110
David K. Bainbridge794735f2020-02-11 21:01:37 -08001111 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001112 OnuId: int32(onuID),
1113 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001114 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001115 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001116 AllocId: int32(allocID),
1117 NetworkIntfId: int32(networkIntfID),
1118 GemportId: int32(gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301119 Classifier: classifierProto,
1120 Action: actionProto,
1121 Priority: int32(logicalFlow.Priority),
1122 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001123 PortNo: portNo,
1124 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001125 ReplicateFlow: len(pbitToGem) > 0,
1126 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001127 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001128 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001129 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001130 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001131 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301132 log.Fields{
1133 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001134 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301135 "intf-id": intfID,
1136 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001137 flowInfo := rsrcMgr.FlowInfo{Flow: &dhcpFlow}
1138 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(dhcpFlow.AccessIntfId), dhcpFlow.OnuId, dhcpFlow.UniId, dhcpFlow.FlowId, flowInfo); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301139 return olterrors.NewErrPersistence("update", "flow", dhcpFlow.FlowId,
1140 log.Fields{
1141 "flow": dhcpFlow,
1142 "device-id": f.deviceHandler.device.Id}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301143 }
1144
David K. Bainbridge794735f2020-02-11 21:01:37 -08001145 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301146}
1147
Esin Karamanae41e2b2019-12-17 18:13:13 +00001148//addIGMPTrapFlow creates IGMP trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301149func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001150 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
1151 return f.addUpstreamTrapFlow(ctx, intfID, onuID, uniID, portNo, classifier, action, logicalFlow, allocID, gemPortID, tpID, pbitToGem)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001152}
1153
1154//addUpstreamTrapFlow creates a trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301155func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001156 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Esin Karamanae41e2b2019-12-17 18:13:13 +00001157
Neha Sharma96b7bf22020-06-15 10:37:32 +00001158 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001159 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301160 return olterrors.NewErrNotFound("nni-interface-id",
1161 log.Fields{
1162 "classifier": classifier,
1163 "action": action,
1164 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001165 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001166 }
1167
1168 // Clear the action map
1169 for k := range action {
1170 delete(action, k)
1171 }
1172
1173 action[TrapToHost] = true
1174 classifier[PacketTagType] = SingleTag
1175 delete(classifier, VlanVid)
1176
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001177 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001178 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001179 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001180 }
1181
Neha Sharma96b7bf22020-06-15 10:37:32 +00001182 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301183 log.Fields{
1184 "ul_classifier": classifier,
1185 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001186 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301187 "device-id": f.deviceHandler.device.Id,
1188 "intf-id": intfID,
1189 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001190
David K. Bainbridge794735f2020-02-11 21:01:37 -08001191 classifierProto, err := makeOpenOltClassifierField(classifier)
1192 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301193 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001194 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001195 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301196 log.Fields{
1197 "classifier": *classifierProto,
1198 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001199 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001200 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301201 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001202 }
1203
David K. Bainbridge794735f2020-02-11 21:01:37 -08001204 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001205 OnuId: int32(onuID),
1206 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001207 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001208 FlowType: Upstream,
1209 AllocId: int32(allocID),
1210 NetworkIntfId: int32(networkIntfID),
1211 GemportId: int32(gemPortID),
1212 Classifier: classifierProto,
1213 Action: actionProto,
1214 Priority: int32(logicalFlow.Priority),
1215 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001216 PortNo: portNo,
1217 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001218 ReplicateFlow: len(pbitToGem) > 0,
1219 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001220 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001221
David K. Bainbridge794735f2020-02-11 21:01:37 -08001222 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001223 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": flow, "device-id": f.deviceHandler.device.Id}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001225
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001226 flowInfo := rsrcMgr.FlowInfo{Flow: &flow}
1227 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(flow.AccessIntfId), flow.OnuId, flow.UniId, flow.FlowId, flowInfo); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301228 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 +00001229 }
1230
David K. Bainbridge794735f2020-02-11 21:01:37 -08001231 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001232}
1233
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001234// Add EAPOL flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001235func (f *OpenOltFlowMgr) addEAPOLFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1236 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001237 gemPortID uint32, vlanID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001238 logger.Infow(ctx, "adding-eapol-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301239 log.Fields{
1240 "intf-id": intfID,
1241 "onu-id": onuID,
1242 "port-no": portNo,
1243 "alloc-id": allocID,
1244 "gemport-id": gemPortID,
1245 "vlan-id": vlanID,
1246 "flow": logicalFlow})
manikkaraj kbf256be2019-03-25 00:13:48 +05301247
1248 uplinkClassifier := make(map[string]interface{})
1249 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301250
manikkaraj kbf256be2019-03-25 00:13:48 +05301251 // Fill Classfier
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001252 uplinkClassifier[EthType] = uint32(EapEthType)
1253 uplinkClassifier[PacketTagType] = SingleTag
1254 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001255 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301256 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001257 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001258 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001259 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301260 "device-id": f.deviceHandler.device.Id,
1261 "onu-id": onuID,
1262 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001263 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301264 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301265 //Add Uplink EAPOL Flow
Neha Sharma96b7bf22020-06-15 10:37:32 +00001266 logger.Debugw(ctx, "creating-ul-eapol-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301267 log.Fields{
1268 "ul_classifier": uplinkClassifier,
1269 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001270 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301271 "device-id": f.deviceHandler.device.Id,
1272 "intf-id": intfID,
1273 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301274
David K. Bainbridge794735f2020-02-11 21:01:37 -08001275 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1276 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301277 return olterrors.NewErrInvalidValue(log.Fields{
1278 "classifier": uplinkClassifier,
1279 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301280 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301282 log.Fields{
1283 "classifier": *classifierProto,
1284 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001285 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001286 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301287 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301288 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001289 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301290 log.Fields{
1291 "action": *actionProto,
1292 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001293 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301294 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301295 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001296 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301297 "action": action,
1298 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001299 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301300 }
1301
David K. Bainbridge794735f2020-02-11 21:01:37 -08001302 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001303 OnuId: int32(onuID),
1304 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001305 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001306 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001307 AllocId: int32(allocID),
1308 NetworkIntfId: int32(networkIntfID),
1309 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301310 Classifier: classifierProto,
1311 Action: actionProto,
1312 Priority: int32(logicalFlow.Priority),
1313 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001314 PortNo: portNo,
1315 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001316 ReplicateFlow: len(pbitToGem) > 0,
1317 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001318 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001319 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001320 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001321 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001322 logger.Infow(ctx, "eapol-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301323 log.Fields{
1324 "device-id": f.deviceHandler.device.Id,
1325 "onu-id": onuID,
1326 "intf-id": intfID,
1327 })
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001328 flowInfo := rsrcMgr.FlowInfo{Flow: &upstreamFlow}
1329 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(upstreamFlow.AccessIntfId), upstreamFlow.OnuId, upstreamFlow.UniId, upstreamFlow.FlowId, flowInfo); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301330 return olterrors.NewErrPersistence("update", "flow", upstreamFlow.FlowId,
1331 log.Fields{
1332 "flow": upstreamFlow,
1333 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301334 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001335 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301336}
1337
David K. Bainbridge794735f2020-02-11 21:01:37 -08001338func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001339 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001340
1341 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1342 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1343 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001344 if vlanID != ReservedVlan {
1345 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001346 classifier.OVid = vid
1347 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301348 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001349 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1350 vid := uint32(metadata)
1351 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001352 classifier.IVid = vid
1353 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301354 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301355 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001356 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301357 classifier.OPbits = vlanPcp
1358 } else {
1359 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301360 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001361 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1362 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1363 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1364 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001365 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001366 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1367 classifier.PktTagType = pktTagType
1368
1369 switch pktTagType {
1370 case SingleTag:
1371 case DoubleTag:
1372 case Untagged:
1373 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001374 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301375 }
1376 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001377 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301378}
1379
Gamze Abaka724d0852020-03-18 12:10:24 +00001380func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001381 var actionCmd openoltpb2.ActionCmd
1382 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301383 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001384 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301385 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001386 if _, ok := actionInfo[VlanPcp]; ok {
1387 action.Cmd.RemarkInnerPbits = true
1388 action.IPbits = actionInfo[VlanPcp].(uint32)
1389 if _, ok := actionInfo[VlanVid]; ok {
1390 action.Cmd.TranslateInnerTag = true
1391 action.IVid = actionInfo[VlanVid].(uint32)
1392 }
1393 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001394 } else if _, ok := actionInfo[PushVlan]; ok {
1395 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301396 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001397 if _, ok := actionInfo[VlanPcp]; ok {
1398 action.OPbits = actionInfo[VlanPcp].(uint32)
1399 action.Cmd.RemarkOuterPbits = true
1400 if _, ok := classifierInfo[VlanVid]; ok {
1401 action.IVid = classifierInfo[VlanVid].(uint32)
1402 action.Cmd.TranslateInnerTag = true
1403 }
1404 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001405 } else if _, ok := actionInfo[TrapToHost]; ok {
1406 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301407 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001408 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301409 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001410 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301411}
1412
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001413// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001414func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
1415 return f.techprofile[intfID].GetTechProfileInstanceKVPath(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301416}
1417
Gamze Abakafee36392019-10-03 11:17:24 +00001418// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001419func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301420 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001421 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1422
Gamze Abakafee36392019-10-03 11:17:24 +00001423 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301424 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001425 _ = olterrors.NewErrAdapter("delete-tech-profile-failed", log.Fields{"device-id": f.deviceHandler.device.Id}, err).Log()
Girish Gowdra54934262019-11-13 14:19:55 +05301426 // return err
1427 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001428 }
Girish Kumara1ea2aa2020-08-19 18:14:22 +00001429 logger.Debugw(ctx, "tech-profile-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001430 }
1431 return nil
1432}
1433
1434// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301435func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001436 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001437 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001438 }
npujarec5762e2020-01-01 14:08:48 +05301439 if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301440 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1441 log.Fields{
1442 "tp-id": tpID,
1443 "uni-port-name": uniPortName,
1444 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001445 }
1446 return nil
1447}
1448
David K. Bainbridge794735f2020-02-11 21:01:37 -08001449func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001450
1451 var intfID uint32
1452 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1453 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1454 */
1455 if deviceFlow.AccessIntfId != -1 {
1456 intfID = uint32(deviceFlow.AccessIntfId)
1457 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001458 // We need to log the valid interface ID.
1459 // For trap-on-nni flows, the access_intf_id is invalid (-1), so choose the network_intf_id.
Daniele Rossi22db98e2019-07-11 11:50:00 +00001460 intfID = uint32(deviceFlow.NetworkIntfId)
1461 }
1462
Neha Sharma96b7bf22020-06-15 10:37:32 +00001463 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301464 "flow": *deviceFlow,
1465 "device-id": f.deviceHandler.device.Id,
1466 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001467 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001468
1469 st, _ := status.FromError(err)
1470 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001471 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001472 "err": err,
1473 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301474 "device-id": f.deviceHandler.device.Id,
1475 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001476 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301477 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001478
1479 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001480 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301481 log.Fields{"err": err,
1482 "device-flow": deviceFlow,
1483 "device-id": f.deviceHandler.device.Id,
1484 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001485 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001486 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001487 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301488 log.Fields{
1489 "flow": *deviceFlow,
1490 "device-id": f.deviceHandler.device.Id,
1491 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001492
1493 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1494 if deviceFlow.AccessIntfId != -1 {
1495 // No need to register the flow if it is a trap on nni flow.
1496 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1497 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1498 return err
1499 }
1500 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001501 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001502}
1503
Neha Sharma96b7bf22020-06-15 10:37:32 +00001504func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1505 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301506 log.Fields{
1507 "flow": *deviceFlow,
1508 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001509 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001510 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001511 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001512 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301513 log.Fields{
1514 "err": err,
1515 "deviceFlow": deviceFlow,
1516 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001517 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001518 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001519 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001520 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001521
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001522 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001523 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001524 "of-flow-id": ofFlowID,
1525 "flow": *deviceFlow,
1526 "device-id": f.deviceHandler.device.Id,
1527 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001528 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301529}
1530
David K. Bainbridge794735f2020-02-11 21:01:37 -08001531func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001532
1533 classifierInfo := make(map[string]interface{})
1534 actionInfo := make(map[string]interface{})
1535
1536 classifierInfo[EthType] = uint32(LldpEthType)
1537 classifierInfo[PacketTagType] = Untagged
1538 actionInfo[TrapToHost] = true
1539
1540 // LLDP flow is installed to trap LLDP packets on the NNI port.
1541 // We manage flow_id resource pool on per PON port basis.
1542 // Since this situation is tricky, as a hack, we pass the NNI port
1543 // index (network_intf_id) as PON port Index for the flow_id resource
1544 // pool. Also, there is no ONU Id available for trapping LLDP packets
1545 // on NNI port, use onu_id as -1 (invalid)
1546 // ****************** CAVEAT *******************
1547 // This logic works if the NNI Port Id falls within the same valid
1548 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1549 // we need to have a re-look at this.
1550 // *********************************************
1551
1552 var onuID = -1
1553 var uniID = -1
1554 var gemPortID = -1
1555
Neha Sharma96b7bf22020-06-15 10:37:32 +00001556 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001557 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301558 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001559 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001560 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001561 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001562 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001563 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001564
David K. Bainbridge794735f2020-02-11 21:01:37 -08001565 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1566 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301567 return olterrors.NewErrInvalidValue(
1568 log.Fields{
1569 "classifier": classifierInfo,
1570 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001571 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001572 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301573 log.Fields{
1574 "classifier": *classifierProto,
1575 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001576 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001577 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301578 return olterrors.NewErrInvalidValue(
1579 log.Fields{
1580 "action": actionInfo,
1581 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001582 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001583 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301584 log.Fields{
1585 "action": *actionProto,
1586 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001587
1588 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1589 OnuId: int32(onuID), // OnuId not required
1590 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001591 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001592 FlowType: Downstream,
1593 NetworkIntfId: int32(networkInterfaceID),
1594 GemportId: int32(gemPortID),
1595 Classifier: classifierProto,
1596 Action: actionProto,
1597 Priority: int32(flow.Priority),
1598 Cookie: flow.Cookie,
1599 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001600 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001601 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301602 log.Fields{
1603 "flow": downstreamflow,
1604 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001605 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001606 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301607 log.Fields{
1608 "device-id": f.deviceHandler.device.Id,
1609 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001610 "flow-id": flow.Id})
1611 flowInfo := rsrcMgr.FlowInfo{Flow: &downstreamflow}
1612 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id, flowInfo); err != nil {
1613 return olterrors.NewErrPersistence("update", "flow", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301614 log.Fields{
1615 "flow": downstreamflow,
1616 "device-id": f.deviceHandler.device.Id}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001617 }
1618 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301619}
1620
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001621func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1622 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001623}
1624
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001625//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001626func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001627 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1628 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1629 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001630 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301631 log.Fields{
1632 "intf-id": intfID,
1633 "onu-id": onuID,
1634 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001635 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001636 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301637 return nil, olterrors.NewErrNotFound("onu-child-device",
1638 log.Fields{
1639 "onu-id": onuID,
1640 "intf-id": intfID,
1641 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001642 }
1643 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1644 //better to ad the device to cache here.
1645 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1646 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001647 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301648 log.Fields{
1649 "intf-id": intfID,
1650 "onu-id": onuID,
1651 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001652 }
1653
1654 return onuDev.(*OnuDevice), nil
1655}
1656
1657//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001658func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1659 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301660 log.Fields{
1661 "pon-port": intfID,
1662 "onu-id": onuID,
1663 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001664 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001665 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001666 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301667 return nil, olterrors.NewErrNotFound("onu",
1668 log.Fields{
1669 "interface-id": parentPortNo,
1670 "onu-id": onuID,
1671 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001672 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301673 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001674 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301675 log.Fields{
1676 "device-id": f.deviceHandler.device.Id,
1677 "child_device_id": onuDevice.Id,
1678 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301679 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301680}
1681
Neha Sharma96b7bf22020-06-15 10:37:32 +00001682func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1683 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301684 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301686 log.Fields{
1687 "intf-id": intfID,
1688 "onu-id": onuID,
1689 "uni-id": uniID,
1690 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001691 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301692 }
1693
1694 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301696 log.Fields{
1697 "msg": *delGemPortMsg,
1698 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001699 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301700 delGemPortMsg,
1701 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301702 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001703 onuDev.deviceType,
1704 onuDev.deviceID,
1705 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301706 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1707 log.Fields{
1708 "from-adapter": f.deviceHandler.device.Type,
1709 "to-adapter": onuDev.deviceType,
1710 "onu-id": onuDev.deviceID,
1711 "proxyDeviceID": onuDev.proxyDeviceID,
1712 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301713 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301715 log.Fields{
1716 "msg": delGemPortMsg,
1717 "from-adapter": f.deviceHandler.device.Type,
1718 "to-adapter": onuDev.deviceType,
1719 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301720 return nil
1721}
1722
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1724 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301725 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001726 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301727 log.Fields{
1728 "intf-id": intfID,
1729 "onu-id": onuID,
1730 "uni-id": uniID,
1731 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001732 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301733 }
1734
1735 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001736 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301737 log.Fields{
1738 "msg": *delTcontMsg,
1739 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001740 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301741 delTcontMsg,
1742 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301743 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001744 onuDev.deviceType,
1745 onuDev.deviceID,
1746 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301747 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1748 log.Fields{
1749 "from-adapter": f.deviceHandler.device.Type,
1750 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1751 "proxyDeviceID": onuDev.proxyDeviceID,
1752 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301753 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001754 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301755 log.Fields{
1756 "msg": delTcontMsg,
1757 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301758 return nil
1759}
1760
Girish Gowdrac3037402020-01-22 20:29:53 +05301761// Once the gemport is released for a given onu, it also has to be cleared from local cache
1762// which was used for deriving the gemport->logicalPortNo during packet-in.
1763// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1764// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001765func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001766
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001767 f.onuGemInfoLock.Lock()
1768 defer f.onuGemInfoLock.Unlock()
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001769
Neha Sharma96b7bf22020-06-15 10:37:32 +00001770 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301771 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001772 "gem-port-id": gemPortID,
1773 "intf-id": intfID,
1774 "onu-id": onuID,
1775 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001776 "onu-gem": f.onuGemInfo})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001777
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001778 onugem := f.onuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001779deleteLoop:
serkant.uluderya96af4932020-02-20 16:58:48 -08001780 for i, onu := range onugem {
Girish Gowdrac3037402020-01-22 20:29:53 +05301781 if onu.OnuID == onuID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001782 for j, gem := range onu.GemPorts {
Girish Gowdrac3037402020-01-22 20:29:53 +05301783 // If the gemport is found, delete it from local cache.
1784 if gem == gemPortID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001785 onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
1786 onugem[i] = onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001787 logger.Infow(ctx, "removed-gemport-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301788 log.Fields{
1789 "intf-id": intfID,
1790 "onu-id": onuID,
1791 "deletedgemport-id": gemPortID,
1792 "gemports": onu.GemPorts,
1793 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001794 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301795 }
1796 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001797 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301798 }
1799 }
1800}
1801
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301802//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001803// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +05301804func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001805 gemPortID int32, flowID uint64, portNum uint32) error {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001806
Neha Sharma96b7bf22020-06-15 10:37:32 +00001807 tpID, err := getTpIDFromFlow(ctx, flow)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001808 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301809 return olterrors.NewErrNotFound("tp-id",
1810 log.Fields{
1811 "flow": flow,
1812 "intf": Intf,
1813 "onu-id": onuID,
1814 "uni-id": uniID,
1815 "device-id": f.deviceHandler.device.Id}, err)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001816 }
Gamze Abakafee36392019-10-03 11:17:24 +00001817
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001818 uni := getUniPortPath(f.deviceHandler.device.Id, Intf, onuID, uniID)
1819 tpPath := f.getTPpath(ctx, Intf, uni, tpID)
1820 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1821 log.Fields{
1822 "tpPath": tpPath,
1823 "device-id": f.deviceHandler.device.Id})
1824 techprofileInst, err := f.techprofile[Intf].GetTPInstanceFromKVStore(ctx, tpID, tpPath)
1825 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1826 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1827 log.Fields{
1828 "tp-id": tpID,
1829 "path": tpPath}, err)
1830 }
1831
1832 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1833
1834 if used {
1835 f.flowsUsedByGemPortKey.Lock()
1836 defer f.flowsUsedByGemPortKey.Unlock()
1837
1838 flowIDs := f.flowsUsedByGemPort[uint32(gemPortID)]
1839 for i, flowIDinMap := range flowIDs {
1840 if flowIDinMap == flowID {
1841 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
1842 // everytime flowsUsedByGemPort cache is updated the same should be updated
1843 // in kv store by calling UpdateFlowIDsForGem
1844 f.flowsUsedByGemPort[uint32(gemPortID)] = flowIDs
1845 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, Intf, uint32(gemPortID), flowIDs); err != nil {
1846 return err
1847 }
1848 break
1849 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001850 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001851 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1852 log.Fields{
1853 "gemport-id": gemPortID,
1854 "usedByFlows": flowIDs,
1855 "device-id": f.deviceHandler.device.Id})
1856 return nil
1857 }
1858 logger.Debugf(ctx, "gem-port-id %d is-not-used-by-another-flow--releasing-the-gem-port", gemPortID)
1859 f.resourceMgr.RemoveGemPortIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1860 // TODO: The TrafficQueue corresponding to this gem-port also should be removed immediately.
1861 // But it is anyway eventually removed later when the TechProfile is freed, so not a big issue for now.
1862 f.resourceMgr.RemoveGEMportPonportToOnuMapOnKVStore(ctx, uint32(gemPortID), Intf)
1863 f.deleteGemPortFromLocalCache(ctx, Intf, uint32(onuID), uint32(gemPortID))
1864 f.onuIdsLock.Lock() // TODO: What is this lock?
1865
1866 //everytime an entry is deleted from flowsUsedByGemPort cache, the same should be updated in kv as well
1867 // by calling DeleteFlowIDsForGem
1868 f.flowsUsedByGemPortKey.Lock()
1869 delete(f.flowsUsedByGemPort, uint32(gemPortID))
1870 f.flowsUsedByGemPortKey.Unlock()
1871 f.resourceMgr.DeleteFlowIDsForGem(ctx, Intf, uint32(gemPortID))
1872 f.resourceMgr.FreeGemPortID(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1873
1874 f.onuIdsLock.Unlock()
1875
1876 // Delete the gem port on the ONU.
1877 if err := f.sendDeleteGemPortToChild(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
1878 logger.Errorw(ctx, "error-processing-delete-gem-port-towards-onu",
1879 log.Fields{
1880 "err": err,
1881 "intf": Intf,
1882 "onu-id": onuID,
1883 "uni-id": uniID,
1884 "device-id": f.deviceHandler.device.Id,
1885 "gemport-id": gemPortID})
1886 }
1887 switch techprofileInst := techprofileInst.(type) {
1888 case *tp.TechProfile:
1889 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
1890 if !ok {
1891 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID); err != nil {
1892 logger.Warn(ctx, err)
1893 }
1894 if err := f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID); err != nil {
1895 logger.Warn(ctx, err)
1896 }
1897 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
1898 logger.Warn(ctx, err)
1899 }
1900 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
1901 logger.Warn(ctx, err)
1902 }
1903 f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
1904 // Delete the TCONT on the ONU.
1905 if err := f.sendDeleteTcontToChild(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID, tpPath); err != nil {
1906 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
1907 log.Fields{
1908 "intf": Intf,
1909 "onu-id": onuID,
1910 "uni-id": uniID,
1911 "device-id": f.deviceHandler.device.Id,
1912 "alloc-id": techprofileInst.UsScheduler.AllocID})
1913 }
1914 }
1915 case *tp.EponProfile:
1916 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID); err != nil {
1917 logger.Warn(ctx, err)
1918 }
1919 if err := f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID); err != nil {
1920 logger.Warn(ctx, err)
1921 }
1922 f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.AllocID)
1923 // Delete the TCONT on the ONU.
1924 if err := f.sendDeleteTcontToChild(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.AllocID, tpPath); err != nil {
1925 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
Shrey Baid26912972020-04-16 21:02:31 +05301926 log.Fields{
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001927 "intf": Intf,
Shrey Baid26912972020-04-16 21:02:31 +05301928 "onu-id": onuID,
1929 "uni-id": uniID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001930 "device-id": f.deviceHandler.device.Id,
1931 "alloc-id": techprofileInst.AllocID})
Gamze Abakafee36392019-10-03 11:17:24 +00001932 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001933 default:
1934 logger.Errorw(ctx, "error-unknown-tech",
1935 log.Fields{
1936 "techprofileInst": techprofileInst})
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001937 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001938
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301939 return nil
1940}
1941
David K. Bainbridge794735f2020-02-11 21:01:37 -08001942// nolint: gocyclo
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001943func (f *OpenOltFlowMgr) clearFlowFromResourceManager(ctx context.Context, flow *ofp.OfpFlowStats, flowDirection string) error {
1944 var flowInfo *rsrcMgr.FlowInfo
Neha Sharma96b7bf22020-06-15 10:37:32 +00001945 logger.Infow(ctx, "clear-flow-from-resource-manager",
Shrey Baid26912972020-04-16 21:02:31 +05301946 log.Fields{
1947 "flowDirection": flowDirection,
1948 "flow": *flow,
1949 "device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +00001950
1951 if flowDirection == Multicast {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001952 return f.clearMulticastFlowFromResourceManager(ctx, flow)
Esin Karamanccb714b