blob: 979aa7d57688d98ebb0e1086c9838330d84fbb71 [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"
serkant.uluderya4aff1862020-09-17 23:35:26 +030025 "strings"
26 "sync"
27
Girish Gowdraa09aeab2020-09-14 16:30:52 -070028 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
29 "github.com/opencord/voltha-lib-go/v4/pkg/log"
30 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080031 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070032 "github.com/opencord/voltha-protos/v4/go/common"
33 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
34 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
35 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
36 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
37 "github.com/opencord/voltha-protos/v4/go/voltha"
Chaitrashree G S579fe732019-08-20 20:50:47 -040038
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
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -030057 //PPPoEDEthType PPPoE discovery ethernet type value
58 PPPoEDEthType = 0x8863
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070059
Andrea Campanella7acc0b92020-02-14 09:20:49 +010060 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
61 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040062
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070063 //DefaultMgmtVlan default vlan value
64 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053065
manikkaraj kbf256be2019-03-25 00:13:48 +053066 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070067
David K. Bainbridge82efc492019-09-04 09:57:11 -070068 //Upstream constant
69 Upstream = "upstream"
70 //Downstream constant
71 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000072 //Multicast constant
73 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070074 //PacketTagType constant
75 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070076 //Untagged constant
77 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070078 //SingleTag constant
79 SingleTag = "single_tag"
80 //DoubleTag constant
81 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053082
83 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070084
85 //EthType constant
86 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000087 //EthDst constant
88 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070089 //TPID constant
90 TPID = "tpid"
91 //IPProto constant
92 IPProto = "ip_proto"
93 //InPort constant
94 InPort = "in_port"
95 //VlanVid constant
96 VlanVid = "vlan_vid"
97 //VlanPcp constant
98 VlanPcp = "vlan_pcp"
99
100 //UDPDst constant
101 UDPDst = "udp_dst"
102 //UDPSrc constant
103 UDPSrc = "udp_src"
104 //Ipv4Dst constant
105 Ipv4Dst = "ipv4_dst"
106 //Ipv4Src constant
107 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700108 //Metadata constant
109 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700110 //TunnelID constant
111 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700112 //Output constant
113 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000114 //GroupID constant
115 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700116 // Actions
117
118 //PopVlan constant
119 PopVlan = "pop_vlan"
120 //PushVlan constant
121 PushVlan = "push_vlan"
122 //TrapToHost constant
123 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400124 //MaxMeterBand constant
125 MaxMeterBand = 2
126 //VlanPCPMask contant
127 VlanPCPMask = 0xFF
128 //VlanvIDMask constant
129 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000130 //IntfID constant
131 IntfID = "intfId"
132 //OnuID constant
133 OnuID = "onuId"
134 //UniID constant
135 UniID = "uniId"
136 //PortNo constant
137 PortNo = "portNo"
138 //AllocID constant
139 AllocID = "allocId"
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000140 //GemID constant
141 GemID = "gemId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000142
143 //NoneOnuID constant
144 NoneOnuID = -1
145 //NoneUniID constant
146 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700147
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700148 // Max number of flows that can be queued per ONU
149 maxConcurrentFlowsPerOnu = 20
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
Esin Karamandf392e12020-12-16 13:33:09 +0000155type gemPortKey struct {
156 intfID uint32
157 gemPort uint32
158}
159
Gamze Abakafee36392019-10-03 11:17:24 +0000160type schedQueue struct {
161 direction tp_pb.Direction
162 intfID uint32
163 onuID uint32
164 uniID uint32
165 tpID uint32
166 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700167 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000168 meterID uint32
169 flowMetadata *voltha.FlowMetadata
170}
171
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700172// subscriberDataPathFlowIDKey is key to subscriberDataPathFlowIDMap map
173type subscriberDataPathFlowIDKey struct {
174 intfID uint32
175 onuID uint32
176 uniID uint32
177 direction string
178 tpID uint32
179}
180
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700181// This control block is created per flow add/remove and pushed on the incomingFlows channel slice
182// The flowControlBlock is then picked by the perOnuFlowHandlerRoutine for further processing.
183// There is on perOnuFlowHandlerRoutine routine per ONU that constantly monitors for any incoming
184// flow and processes it serially
185type flowControlBlock struct {
186 ctx context.Context // Flow handler context
187 addFlow bool // if true flow to be added, else removed
188 flow *voltha.OfpFlowStats // Flow message
189 flowMetadata *voltha.FlowMetadata // FlowMetadata that contains flow meter information. This can be nil for Flow remove
190 errChan *chan error // channel to report the Flow handling error
Esin Karamanccb714b2019-11-29 15:02:06 +0000191}
192
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700193//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530194type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700195 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
196 techprofile map[uint32]tp.TechProfileIf
197 deviceHandler *DeviceHandler
198 grpMgr *OpenOltGroupMgr
199 resourceMgr *rsrcMgr.OpenOltResourceMgr
200
201 onuIdsLock sync.RWMutex // TODO: Do we need this?
202
203 flowsUsedByGemPort map[uint32][]uint64 // gem port id to flow ids
204 flowsUsedByGemPortKey sync.RWMutex // lock to be used to access the flowsUsedByGemPort map
205
206 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
207 packetInGemPortLock sync.RWMutex
208
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700209 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700210 onuGemInfo []rsrcMgr.OnuGemInfo //onu, gem and uni info local cache
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700211 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700212 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700213
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700214 // Map of voltha flowID associated with subscriberDataPathFlowIDKey
215 // This information is not persisted on Kv store and hence should be reconciled on adapter restart
216 subscriberDataPathFlowIDMap map[subscriberDataPathFlowIDKey]uint64
217 subscriberDataPathFlowIDMapLock sync.RWMutex
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700218
219 // Slice of channels. Each channel in slice, index by ONU ID, queues flows per ONU.
220 // A go routine per ONU, waits on the unique channel (indexed by ONU ID) for incoming flows (add/remove)
221 incomingFlows []chan flowControlBlock
Esin Karamandf392e12020-12-16 13:33:09 +0000222
223 //this map keeps uni port info by gem and pon port. This relation shall be used for packet-out operations
224 gemToUniMap map[gemPortKey][]uint32
225 //We need to have a global lock on the gemToUniLock map
226 gemToUniLock sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +0530227}
228
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700229//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700230func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000231 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530232 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530233 var err error
234 var idx uint32
235
manikkaraj kbf256be2019-03-25 00:13:48 +0530236 flowMgr.deviceHandler = dh
Girish Gowdra9602eb42020-09-09 15:50:39 -0700237 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530238 flowMgr.resourceMgr = rMgr
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000239 flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000240 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
241 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"error": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530242 return nil
243 }
William Kurkian740a09c2019-10-23 17:07:38 -0400244 flowMgr.onuIdsLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700245 flowMgr.flowsUsedByGemPort = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530246 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700247 flowMgr.packetInGemPortLock = sync.RWMutex{}
Girish Gowdra1183b4d2020-08-25 16:12:01 -0700248 flowMgr.onuGemInfoLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700249 flowMgr.subscriberDataPathFlowIDMap = make(map[subscriberDataPathFlowIDKey]uint64)
250 flowMgr.subscriberDataPathFlowIDMapLock = sync.RWMutex{}
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700251
252 // Create a slice of buffered channels for handling concurrent flows per ONU.
253 // The additional entry (+1) is to handle the NNI trap flows on a separate channel from individual ONUs channel
254 flowMgr.incomingFlows = make([]chan flowControlBlock, MaxOnusPerPon+1)
255 for i := range flowMgr.incomingFlows {
256 flowMgr.incomingFlows[i] = make(chan flowControlBlock, maxConcurrentFlowsPerOnu)
257 // Spin up a go routine to handling incoming flows (add/remove).
258 // There will be on go routine per ONU.
259 // This routine will be blocked on the flowMgr.incomingFlows[onu-id] channel for incoming flows.
260 go flowMgr.perOnuFlowHandlerRoutine(flowMgr.incomingFlows[i])
261 }
262
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530263 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700264 if flowMgr.onuGemInfo, err = rMgr.GetOnuGemInfo(ctx, ponPortIdx); err != nil {
265 logger.Error(ctx, "failed-to-load-onu-gem-info-cache")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530266 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700267 //Load flowID list per gem map per interface from the kvstore.
268 flowMgr.loadFlowIDlistForGem(ctx, idx)
Esin Karamanccb714b2019-11-29 15:02:06 +0000269 //load interface to multicast queue map from kv store
Esin Karamandf392e12020-12-16 13:33:09 +0000270
271 flowMgr.gemToUniMap = make(map[gemPortKey][]uint32)
272 flowMgr.gemToUniLock = sync.RWMutex{}
273
Girish Gowdra9602eb42020-09-09 15:50:39 -0700274 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700275 flowMgr.reconcileSubscriberDataPathFlowIDMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000276 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530277 return &flowMgr
278}
279
Esin Karamandf392e12020-12-16 13:33:09 +0000280// toGemToUniMap adds uni info consisting of onu and uni ID to the map and associates it with a gem port
281func (f *OpenOltFlowMgr) toGemToUniMap(ctx context.Context, gemPK gemPortKey, onuID uint32, uniID uint32) {
282 f.gemToUniLock.Lock()
283 f.gemToUniMap[gemPK] = []uint32{onuID, uniID}
284 f.gemToUniLock.Unlock()
285}
286
287// fromGemToUniMap returns onu and uni ID associated with the given key
288func (f *OpenOltFlowMgr) fromGemToUniMap(key gemPortKey) ([]uint32, bool) {
289 f.gemToUniLock.RLock()
290 defer f.gemToUniLock.RUnlock()
291 val, ok := f.gemToUniMap[key]
292 return val, ok
293}
294
295// removeFromGemToUniMap removes an entry associated with the given key from gemToUniMap
296func (f *OpenOltFlowMgr) removeFromGemToUniMap(key gemPortKey) {
297 f.gemToUniLock.Lock()
298 defer f.gemToUniLock.Unlock()
299 delete(f.gemToUniMap, key)
300}
301
Kent Hagermane6ff1012020-07-14 15:07:53 -0400302func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700303 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
304 // Flow is not replicated in this case, we need to register the flow for a single gem-port
305 return f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
306 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
307 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
308 for _, gemPort := range deviceFlow.PbitToGemport {
309 if err := f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
310 return err
311 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700312 }
Gamze Abakafee36392019-10-03 11:17:24 +0000313 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700314 return nil
315}
316
317func (f *OpenOltFlowMgr) registerFlowIDForGem(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
318 f.flowsUsedByGemPortKey.Lock()
319 flowIDList, ok := f.flowsUsedByGemPort[gemPortID]
320 if !ok {
321 flowIDList = []uint64{flowFromCore.Id}
322 }
323 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
324 f.flowsUsedByGemPort[gemPortID] = flowIDList
325 f.flowsUsedByGemPortKey.Unlock()
326
327 // update the flowids for a gem to the KVstore
328 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400329}
330
Girish Gowdra9602eb42020-09-09 15:50:39 -0700331func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000332 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200333 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000334 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530335 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700336 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530337
Neha Sharma96b7bf22020-06-15 10:37:32 +0000338 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530339 "device-id": f.deviceHandler.device.Id,
340 "intf-id": intfID,
341 "onu-id": onuID,
342 "uni-id": uniID,
343 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700344 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530345 "action": actionInfo,
346 "usmeter-iD": UsMeterID,
347 "dsmeter-iD": DsMeterID,
348 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400349 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
350 // is because the flow is an NNI flow and there would be no onu resources associated with it
351 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400352 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200353 cause := "no-onu-id-for-flow"
354 fields := log.Fields{
355 "onu": onuID,
356 "port-no": portNo,
357 "classifer": classifierInfo,
358 "action": actionInfo,
359 "device-id": f.deviceHandler.device.Id}
360 logger.Errorw(ctx, cause, fields)
361 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530362 }
363
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700364 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000365 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530366 "uni": uni,
367 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530368
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700369 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
370 "device-id": f.deviceHandler.device.Id,
371 "intf-id": intfID,
372 "onu-id": onuID,
373 "uni-id": uniID,
374 "port-no": portNo,
375 "classifier": classifierInfo,
376 "action": actionInfo,
377 "usmeter-id": UsMeterID,
378 "dsmeter-id": DsMeterID,
379 "tp-id": TpID})
380 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
381 if allocID == 0 || gemPorts == nil || TpInst == nil {
382 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
383 return olterrors.NewErrNotFound(
384 "alloc-id-gem-ports-tp-unavailable",
385 nil, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400386 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700387 args := make(map[string]uint32)
388 args[IntfID] = intfID
389 args[OnuID] = onuID
390 args[UniID] = uniID
391 args[PortNo] = portNo
392 args[AllocID] = allocID
393
394 /* Flows can be added specific to gemport if p-bits are received.
395 * If no pbit mentioned then adding flows for all gemports
396 */
397 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
398
Andrea Campanellabfe08432020-09-11 17:07:03 +0200399 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530400}
401
salmansiddiqui7ac62132019-08-22 03:58:50 +0000402// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530403func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400404
Neha Sharma96b7bf22020-06-15 10:37:32 +0000405 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530406 log.Fields{"dir": sq.direction,
407 "intf-id": sq.intfID,
408 "onu-id": sq.onuID,
409 "uni-id": sq.uniID,
410 "tp-id": sq.tpID,
411 "meter-id": sq.meterID,
412 "tp-inst": sq.tpInst,
413 "flowmetadata": sq.flowMetadata,
414 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400415
Gamze Abakafee36392019-10-03 11:17:24 +0000416 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000417 if err != nil {
418 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400419 }
420
421 /* Lets make a simple assumption that if the meter-id is present on the KV store,
422 * then the scheduler and queues configuration is applied on the OLT device
423 * in the given direction.
424 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000425
Manikkaraj kb1d51442019-07-23 10:41:02 -0400426 var SchedCfg *tp_pb.SchedulerConfig
npujarec5762e2020-01-01 14:08:48 +0530427 KvStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400428 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530429 return olterrors.NewErrNotFound("meter",
430 log.Fields{"intf-id": sq.intfID,
431 "onu-id": sq.onuID,
432 "uni-id": sq.uniID,
433 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400434 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000435
Manikkaraj kb1d51442019-07-23 10:41:02 -0400436 if KvStoreMeter != nil {
Gamze Abakafee36392019-10-03 11:17:24 +0000437 if KvStoreMeter.MeterId == sq.meterID {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000438 logger.Debugw(ctx, "scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400439 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400440 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530441 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800442 "unsupported": "meter-id",
443 "kv-store-meter-id": KvStoreMeter.MeterId,
Shrey Baid26912972020-04-16 21:02:31 +0530444 "meter-id-in-flow": sq.meterID,
445 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400446 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000447
Neha Sharma96b7bf22020-06-15 10:37:32 +0000448 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530449 log.Fields{
450 "meter-id": sq.meterID,
451 "direction": Direction,
452 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000453
Gamze Abakafee36392019-10-03 11:17:24 +0000454 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000455 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Gamze Abakafee36392019-10-03 11:17:24 +0000456 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000457 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400458 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000459
460 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530461 return olterrors.NewErrNotFound("scheduler-config",
462 log.Fields{
463 "intf-id": sq.intfID,
464 "direction": sq.direction,
465 "tp-inst": sq.tpInst,
466 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000467 }
468
Manikkaraj kb1d51442019-07-23 10:41:02 -0400469 var meterConfig *ofp.OfpMeterConfig
Gamze Abakafee36392019-10-03 11:17:24 +0000470 if sq.flowMetadata != nil {
471 for _, meter := range sq.flowMetadata.Meters {
472 if sq.meterID == meter.MeterId {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400473 meterConfig = meter
Neha Sharma96b7bf22020-06-15 10:37:32 +0000474 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Shrey Baid26912972020-04-16 21:02:31 +0530475 log.Fields{"meterConfig": meterConfig,
476 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400477 break
478 }
479 }
480 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000481 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400482 }
483 if meterConfig == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530484 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800485 "reason": "Could-not-get-meterbands-from-flowMetadata",
486 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530487 "meter-id": sq.meterID,
488 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400489 } else if len(meterConfig.Bands) < MaxMeterBand {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000490 logger.Errorw(ctx, "invalid-number-of-bands-in-meter",
Shrey Baid26912972020-04-16 21:02:31 +0530491 log.Fields{"Bands": meterConfig.Bands,
492 "meter-id": sq.meterID,
493 "device-id": f.deviceHandler.device.Id})
Thomas Lee S94109f12020-03-03 16:39:29 +0530494 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800495 "reason": "Invalid-number-of-bands-in-meter",
496 "meterband-count": len(meterConfig.Bands),
497 "metabands": meterConfig.Bands,
Shrey Baid26912972020-04-16 21:02:31 +0530498 "meter-id": sq.meterID,
499 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400500 }
501 cir := meterConfig.Bands[0].Rate
502 cbs := meterConfig.Bands[0].BurstSize
503 eir := meterConfig.Bands[1].Rate
504 ebs := meterConfig.Bands[1].BurstSize
505 pir := cir + eir
506 pbs := cbs + ebs
507 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
508
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700509 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000510 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400511
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700512 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530513 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
514 log.Fields{"intf-id": sq.intfID,
515 "direction": sq.direction,
516 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400517 }
518
salmansiddiqui7ac62132019-08-22 03:58:50 +0000519 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400520 * store the meter id on the KV store, for further reference.
521 */
npujarec5762e2020-01-01 14:08:48 +0530522 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 +0530523 return olterrors.NewErrAdapter("failed-updating-meter-id",
524 log.Fields{"onu-id": sq.onuID,
525 "meter-id": sq.meterID,
526 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400527 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000528 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530529 log.Fields{"direction": Direction,
530 "Meter": meterConfig,
531 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400532 return nil
533}
534
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700535func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000536 trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000537
538 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530539 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
540 log.Fields{"intf-id": sq.intfID,
541 "direction": sq.direction,
542 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000543 }
544
Neha Sharma96b7bf22020-06-15 10:37:32 +0000545 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530546 log.Fields{
547 "direction": sq.direction,
548 "TrafficScheds": TrafficSched,
549 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530550 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Girish Kumar8f73fe02019-12-09 13:19:37 +0000551 IntfId: sq.intfID, OnuId: sq.onuID,
552 UniId: sq.uniID, PortNo: sq.uniPort,
553 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000554 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000555 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000556 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530557 "direction": sq.direction,
558 "traffic-queues": trafficQueues,
559 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000560
561 // On receiving the CreateTrafficQueues request, the driver should create corresponding
562 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000563 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530564 log.Fields{"direction": sq.direction,
565 "traffic-queues": trafficQueues,
566 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530567 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000568 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
569 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000570 TrafficQueues: trafficQueues,
571 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530572 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000573 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000574 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530575 "direction": sq.direction,
576 "traffic-queues": trafficQueues,
577 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000578
Esin Karamanccb714b2019-11-29 15:02:06 +0000579 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile))
Esin Karamanccb714b2019-11-29 15:02:06 +0000581 if len(multicastTrafficQueues) > 0 {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700582 if _, present := f.grpMgr.GetInterfaceToMcastQueueMap(sq.intfID); !present {
Esin Karamanccb714b2019-11-29 15:02:06 +0000583 //assumed that there is only one queue per PON for the multicast service
584 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
585 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000587 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700588 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000589 gemPortID: multicastQueuePerPonPort.GemportId,
590 servicePriority: multicastQueuePerPonPort.Priority,
591 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700592 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000593 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400594 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
595 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"error": err})
596 return err
597 }
Shrey Baid26912972020-04-16 21:02:31 +0530598
Neha Sharma96b7bf22020-06-15 10:37:32 +0000599 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000600 }
601 }
602 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000603 return nil
604}
605
salmansiddiqui7ac62132019-08-22 03:58:50 +0000606// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530607func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400608
609 var Direction string
610 var SchedCfg *tp_pb.SchedulerConfig
611 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000612 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530613 log.Fields{
614 "direction": sq.direction,
615 "intf-id": sq.intfID,
616 "onu-id": sq.onuID,
617 "uni-id": sq.uniID,
618 "uni-port": sq.uniPort,
619 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000620 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000621 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400622 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000623 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000624 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400625 Direction = "downstream"
626 }
627
Girish Kumar8f73fe02019-12-09 13:19:37 +0000628 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530629 return olterrors.NewErrNotFound("scheduler-config",
630 log.Fields{
631 "int-id": sq.intfID,
632 "direction": sq.direction,
633 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000634 }
635
npujarec5762e2020-01-01 14:08:48 +0530636 KVStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400637 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530638 return olterrors.NewErrNotFound("meter",
639 log.Fields{
640 "onu-id": sq.onuID,
641 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400642 }
643 if KVStoreMeter == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000644 logger.Warnw(ctx, "no-meter-installed-yet",
Shrey Baid26912972020-04-16 21:02:31 +0530645 log.Fields{
646 "direction": Direction,
647 "intf-id": sq.intfID,
648 "onu-id": sq.onuID,
649 "uni-id": sq.uniID,
650 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400651 return nil
652 }
653 cir := KVStoreMeter.Bands[0].Rate
654 cbs := KVStoreMeter.Bands[0].BurstSize
655 eir := KVStoreMeter.Bands[1].Rate
656 ebs := KVStoreMeter.Bands[1].BurstSize
657 pir := cir + eir
658 pbs := cbs + ebs
659
660 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
661
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700662 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000663 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000664
Neha Sharma96b7bf22020-06-15 10:37:32 +0000665 TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000666 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530667 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
668 log.Fields{
669 "intf-id": sq.intfID,
670 "direction": sq.direction,
671 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000672 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400673
npujarec5762e2020-01-01 14:08:48 +0530674 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000675 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
676 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000677 TrafficQueues: TrafficQueues,
678 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000679 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530680 log.Fields{
681 "intf-id": sq.intfID,
682 "traffic-queues": TrafficQueues,
683 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400684 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000685 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530686 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Gamze Abakafee36392019-10-03 11:17:24 +0000687 IntfId: sq.intfID, OnuId: sq.onuID,
688 UniId: sq.uniID, PortNo: sq.uniPort,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400689 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000690 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530691 log.Fields{
692 "intf-id": sq.intfID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700693 "traffic-schedulers": TrafficSched,
694 "onu-id": sq.onuID,
695 "uni-id": sq.uniID,
696 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400697 }
698
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700699 logger.Infow(ctx, "removed-traffic-schedulers-successfully",
700 log.Fields{"device-id": f.deviceHandler.device.Id,
701 "intf-id": sq.intfID,
702 "onu-id": sq.onuID,
703 "uni-id": sq.uniID,
704 "uni-port": sq.uniPort})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000705
706 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400707 * delete the meter id on the KV store.
708 */
npujarec5762e2020-01-01 14:08:48 +0530709 err = f.resourceMgr.RemoveMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400710 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530711 return olterrors.NewErrAdapter("unable-to-remove-meter",
712 log.Fields{
713 "onu": sq.onuID,
714 "meter": KVStoreMeter.MeterId,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700715 "device-id": f.deviceHandler.device.Id,
716 "intf-id": sq.intfID,
717 "onu-id": sq.onuID,
718 "uni-id": sq.uniID,
719 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400720 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000721 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530722 log.Fields{
723 "meter-id": KVStoreMeter.MeterId,
724 "dir": Direction,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700725 "device-id": f.deviceHandler.device.Id,
726 "intf-id": sq.intfID,
727 "onu-id": sq.onuID,
728 "uni-id": sq.uniID,
729 "uni-port": sq.uniPort})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400730 return err
731}
732
Gamze Abakafee36392019-10-03 11:17:24 +0000733// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700734func (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 +0000735 var allocIDs []uint32
736 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530737 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530738 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000739 var err error
Gamze Abakafee36392019-10-03 11:17:24 +0000740
npujarec5762e2020-01-01 14:08:48 +0530741 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
742 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000743 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530744
Neha Sharma96b7bf22020-06-15 10:37:32 +0000745 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530746 "intf-id": intfID,
747 "onu-id": onuID,
748 "uni-id": uniID,
749 "device-id": f.deviceHandler.device.Id,
750 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530751
Manikkaraj kb1d51442019-07-23 10:41:02 -0400752 // Check tech profile instance already exists for derived port name
npujarec5762e2020-01-01 14:08:48 +0530753 techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000754 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000755 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530756 log.Fields{
757 "path": tpPath,
758 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530759 techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000760 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530761 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000762 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530763 log.Fields{
764 "error": err,
765 "tp-id": TpID,
766 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000767 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530768 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400769 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
770 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"error": err})
771 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530772 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000773 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530774 log.Fields{
775 "uni": uni,
776 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530777 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530778 }
Gamze Abakafee36392019-10-03 11:17:24 +0000779
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700780 switch tpInst := techProfileInstance.(type) {
781 case *tp.TechProfile:
782 if UsMeterID != 0 {
783 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
784 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
785 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000786 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700787 log.Fields{
788 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700789 "onu-id": onuID,
790 "uni-id": uniID,
791 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700792 "meter-id": UsMeterID,
793 "device-id": f.deviceHandler.device.Id})
794 return 0, nil, nil
795 }
796 }
797 if DsMeterID != 0 {
798 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
799 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
800 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000801 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700802 log.Fields{
803 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700804 "onu-id": onuID,
805 "uni-id": uniID,
806 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700807 "meter-id": DsMeterID,
808 "device-id": f.deviceHandler.device.Id})
809 return 0, nil, nil
810 }
811 }
812 allocID := tpInst.UsScheduler.AllocID
813 for _, gem := range tpInst.UpstreamGemPortAttributeList {
814 gemPortIDs = append(gemPortIDs, gem.GemportID)
815 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700816 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000817
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700818 if tpInstanceExists {
819 return allocID, gemPortIDs, techProfileInstance
820 }
821
822 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700823 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700824 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000825 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700826 log.Fields{
827 "alloc-ids": allocIDs,
828 "gemports": allgemPortIDs,
829 "device-id": f.deviceHandler.device.Id})
830 // Send Tconts and GEM ports to KV store
831 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530832 return allocID, gemPortIDs, techProfileInstance
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700833 case *tp.EponProfile:
834 // CreateSchedulerQueues for EPON needs to be implemented here
835 // when voltha-protos for EPON is completed.
836 allocID := tpInst.AllocID
837 for _, gem := range tpInst.UpstreamQueueAttributeList {
838 gemPortIDs = append(gemPortIDs, gem.GemportID)
839 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700840 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700841
842 if tpInstanceExists {
843 return allocID, gemPortIDs, techProfileInstance
844 }
845
846 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700847 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700848 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000849 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700850 log.Fields{
851 "alloc-ids": allocIDs,
852 "gemports": allgemPortIDs,
853 "device-id": f.deviceHandler.device.Id})
854 // Send Tconts and GEM ports to KV store
855 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
856 return allocID, gemPortIDs, techProfileInstance
857 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000858 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700859 log.Fields{
860 "tpInst": tpInst})
861 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530862 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530863}
864
npujarec5762e2020-01-01 14:08:48 +0530865func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530866
Neha Sharma96b7bf22020-06-15 10:37:32 +0000867 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530868 log.Fields{
869 "intf-id": intfID,
870 "onu-id": onuID,
871 "uni-id": uniID,
872 "alloc-id": allocID,
873 "gemport-ids": gemPortIDs,
874 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530875 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530876 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000877 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 +0530878 }
npujarec5762e2020-01-01 14:08:48 +0530879 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880 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 +0530881 }
npujarec5762e2020-01-01 14:08:48 +0530882 if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000883 logger.Error(ctx, "error-while-uploading-gemtopon-map-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamandf392e12020-12-16 13:33:09 +0000884 } else {
885 //add to gem to uni cache
886 f.addGemPortUniAssociationsToCache(ctx, intfID, onuID, uniID, gemPortIDs)
manikkaraj kbf256be2019-03-25 00:13:48 +0530887 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000888 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 -0400889 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530890 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400891 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530892}
893
Esin Karamandf392e12020-12-16 13:33:09 +0000894//addGemPortUniAssociationsToCache
895func (f *OpenOltFlowMgr) addGemPortUniAssociationsToCache(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortIDs []uint32) {
896 for _, gemPortID := range gemPortIDs {
897 key := gemPortKey{
898 intfID: intfID,
899 gemPort: gemPortID,
900 }
901 f.toGemToUniMap(ctx, key, onuID, uniID)
902 }
903 logger.Debugw(ctx, "gem-to-uni-info-added-to-cache", log.Fields{"device-id": f.deviceHandler.device.Id, "intfID": intfID,
904 "gemPortIDs": gemPortIDs, "onuID": onuID, "uniID": uniID})
905}
906
Neha Sharma96b7bf22020-06-15 10:37:32 +0000907func (f *OpenOltFlowMgr) populateTechProfilePerPonPort(ctx context.Context) error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000908 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530909 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000910 for _, intfID := range techRange.IntfIds {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700911 f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[intfID].TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400912 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000913 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530914 log.Fields{
915 "intf-id": intfID,
916 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530917 }
918 }
919 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400920 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530921 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530922 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800923 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530924 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
925 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530926 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000927 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530928 log.Fields{
929 "numofTech": tpCount,
930 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
931 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530932 return nil
933}
934
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700935func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530936 portNo uint32, uplinkClassifier map[string]interface{},
937 uplinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700938 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700939 uplinkClassifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530941 log.Fields{
942 "uplinkClassifier": uplinkClassifier,
943 "uplinkAction": uplinkAction})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700944 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, uplinkClassifier, uplinkAction,
945 Upstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
Manikkaraj k884c1242019-04-11 16:26:42 +0530946 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530947}
948
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700949func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530950 portNo uint32, downlinkClassifier map[string]interface{},
951 downlinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700952 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700953 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000954 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530955 log.Fields{
956 "downlinkClassifier": downlinkClassifier,
957 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400958 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
959 if vlan, exists := downlinkClassifier[VlanVid]; exists {
960 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700961 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Neha Sharma96b7bf22020-06-15 10:37:32 +0000962 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, intfID, onuID, uniID) {
963 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530964 log.Fields{
965 "flow": logicalFlow,
966 "device-id": f.deviceHandler.device.Id,
967 "onu-id": onuID,
968 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800969 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400970 }
971 }
972 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530973 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400974
Manikkaraj k884c1242019-04-11 16:26:42 +0530975 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700976 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400977 // vlan_vid is a uint32. must be type asserted as such or conversion fails
978 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530979 if ok {
980 downlinkAction[VlanVid] = dlClVid & 0xfff
981 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530982 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530983 "reason": "failed-to-convert-vlanid-classifier",
984 "vlan-id": VlanVid,
985 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530986 }
987
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700988 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, downlinkClassifier, downlinkAction,
989 Downstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
manikkaraj kbf256be2019-03-25 00:13:48 +0530990}
991
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700992func (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 +0530993 action map[string]interface{}, direction string, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700994 allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
995
996 var inverseDirection string
997 if direction == Upstream {
998 inverseDirection = Downstream
999 } else {
1000 inverseDirection = Upstream
1001 }
1002
Neha Sharma96b7bf22020-06-15 10:37:32 +00001003 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301004 log.Fields{
1005 "intf-id": intfID,
1006 "onu-id": onuID,
1007 "uni-id": uniID,
1008 "device-id": f.deviceHandler.device.Id,
1009 "classifier": classifier,
1010 "action": action,
1011 "direction": direction,
1012 "alloc-id": allocID,
1013 "gemport-id": gemPortID,
1014 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001015
1016 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001017 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +05301018 log.Fields{
1019 "device-id": f.deviceHandler.device.Id,
1020 "intf-id": intfID,
1021 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001022 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301023 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001024 classifierProto, err := makeOpenOltClassifierField(classifier)
1025 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301026 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301027 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301029 log.Fields{
1030 "classifier": *classifierProto,
1031 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001032 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001033 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301034 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301035 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001036 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301037 log.Fields{
1038 "action": *actionProto,
1039 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001040 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301041 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301042 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -08001043 log.Fields{
1044 "classifier": classifier,
1045 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301046 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001047 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301048 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001049
1050 // Get symmetric flowID if it exists
1051 // This symmetric flowID will be needed by agent software to use the same device flow-id that was used for the
1052 // symmetric flow earlier
1053 // symmetric flowID 0 is considered by agent as non-existent symmetric flow
1054 keySymm := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: inverseDirection, tpID: tpID}
1055 f.subscriberDataPathFlowIDMapLock.RLock()
1056 symmFlowID := f.subscriberDataPathFlowIDMap[keySymm]
1057 f.subscriberDataPathFlowIDMapLock.RUnlock()
1058
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001059 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001060 OnuId: int32(onuID),
1061 UniId: int32(uniID),
1062 FlowId: logicalFlow.Id,
1063 FlowType: direction,
1064 AllocId: int32(allocID),
1065 NetworkIntfId: int32(networkIntfID),
1066 GemportId: int32(gemPortID),
1067 Classifier: classifierProto,
1068 Action: actionProto,
1069 Priority: int32(logicalFlow.Priority),
1070 Cookie: logicalFlow.Cookie,
1071 PortNo: portNo,
1072 TechProfileId: tpID,
1073 ReplicateFlow: len(pbitToGem) > 0,
1074 PbitToGemport: pbitToGem,
1075 SymmetricFlowId: symmFlowID,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001076 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001078 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301079 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001080 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301081 log.Fields{"direction": direction,
1082 "device-id": f.deviceHandler.device.Id,
1083 "flow": flow,
1084 "intf-id": intfID,
1085 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001086 flowInfo := rsrcMgr.FlowInfo{Flow: &flow, IsSymmtricFlow: true}
1087 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(flow.AccessIntfId), flow.OnuId, flow.UniId, flow.FlowId, flowInfo); err != nil {
1088 return olterrors.NewErrPersistence("update", "flow", logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301089 log.Fields{
1090 "flow": flow,
1091 "device-id": f.deviceHandler.device.Id,
1092 "intf-id": intfID,
1093 "onu-id": onuID}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001094 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001095
1096 // Update the current flowID to the map
1097 keyCurr := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: direction, tpID: tpID}
1098 f.subscriberDataPathFlowIDMapLock.Lock()
1099 f.subscriberDataPathFlowIDMap[keyCurr] = logicalFlow.Id
1100 f.subscriberDataPathFlowIDMapLock.Unlock()
1101
David K. Bainbridge794735f2020-02-11 21:01:37 -08001102 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301103}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001104
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001105func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1106 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001107 gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301108
Neha Sharma96b7bf22020-06-15 10:37:32 +00001109 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301110 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301111 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001112 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301113 "action": action,
1114 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001115 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301116 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301117
1118 // Clear the action map
1119 for k := range action {
1120 delete(action, k)
1121 }
1122
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001123 action[TrapToHost] = true
1124 classifier[UDPSrc] = uint32(68)
1125 classifier[UDPDst] = uint32(67)
1126 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301127
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001128 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001129 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301130 log.Fields{
1131 "device-id": f.deviceHandler.device.Id,
1132 "intf-id": intfID,
1133 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001134 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301135 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301136
Neha Sharma96b7bf22020-06-15 10:37:32 +00001137 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301138 log.Fields{
1139 "ul_classifier": classifier,
1140 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001141 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301142 "intf-id": intfID,
1143 "onu-id": onuID,
1144 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301145
David K. Bainbridge794735f2020-02-11 21:01:37 -08001146 classifierProto, err := makeOpenOltClassifierField(classifier)
1147 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301148 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301149 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001150 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001151 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001152 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301153 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301154 }
1155
David K. Bainbridge794735f2020-02-11 21:01:37 -08001156 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001157 OnuId: int32(onuID),
1158 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001159 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001160 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001161 AllocId: int32(allocID),
1162 NetworkIntfId: int32(networkIntfID),
1163 GemportId: int32(gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301164 Classifier: classifierProto,
1165 Action: actionProto,
1166 Priority: int32(logicalFlow.Priority),
1167 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001168 PortNo: portNo,
1169 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001170 ReplicateFlow: len(pbitToGem) > 0,
1171 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001172 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001173 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001174 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001175 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001176 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301177 log.Fields{
1178 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001179 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301180 "intf-id": intfID,
1181 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001182 flowInfo := rsrcMgr.FlowInfo{Flow: &dhcpFlow}
1183 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 +05301184 return olterrors.NewErrPersistence("update", "flow", dhcpFlow.FlowId,
1185 log.Fields{
1186 "flow": dhcpFlow,
1187 "device-id": f.deviceHandler.device.Id}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301188 }
1189
David K. Bainbridge794735f2020-02-11 21:01:37 -08001190 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301191}
1192
Esin Karamanae41e2b2019-12-17 18:13:13 +00001193//addIGMPTrapFlow creates IGMP trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301194func (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 -07001195 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Marcos Aurelio Carrero (Furukawa)1dc2bfb2021-02-17 15:10:12 -03001196 delete(classifier, VlanVid)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001197 return f.addUpstreamTrapFlow(ctx, intfID, onuID, uniID, portNo, classifier, action, logicalFlow, allocID, gemPortID, tpID, pbitToGem)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001198}
1199
1200//addUpstreamTrapFlow creates a trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301201func (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 -07001202 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 +00001203
Neha Sharma96b7bf22020-06-15 10:37:32 +00001204 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001205 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301206 return olterrors.NewErrNotFound("nni-interface-id",
1207 log.Fields{
1208 "classifier": classifier,
1209 "action": action,
1210 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001211 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001212 }
1213
1214 // Clear the action map
1215 for k := range action {
1216 delete(action, k)
1217 }
1218
1219 action[TrapToHost] = true
1220 classifier[PacketTagType] = SingleTag
Esin Karamanae41e2b2019-12-17 18:13:13 +00001221
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001222 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001223 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001224 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001225 }
1226
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301228 log.Fields{
1229 "ul_classifier": classifier,
1230 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001231 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301232 "device-id": f.deviceHandler.device.Id,
1233 "intf-id": intfID,
1234 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001235
David K. Bainbridge794735f2020-02-11 21:01:37 -08001236 classifierProto, err := makeOpenOltClassifierField(classifier)
1237 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301238 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001239 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001240 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301241 log.Fields{
1242 "classifier": *classifierProto,
1243 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001244 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001245 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301246 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001247 }
1248
David K. Bainbridge794735f2020-02-11 21:01:37 -08001249 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001250 OnuId: int32(onuID),
1251 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001252 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001253 FlowType: Upstream,
1254 AllocId: int32(allocID),
1255 NetworkIntfId: int32(networkIntfID),
1256 GemportId: int32(gemPortID),
1257 Classifier: classifierProto,
1258 Action: actionProto,
1259 Priority: int32(logicalFlow.Priority),
1260 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001261 PortNo: portNo,
1262 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001263 ReplicateFlow: len(pbitToGem) > 0,
1264 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001265 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001266
David K. Bainbridge794735f2020-02-11 21:01:37 -08001267 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001268 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 -08001269 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001270
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001271 flowInfo := rsrcMgr.FlowInfo{Flow: &flow}
1272 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 +05301273 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 +00001274 }
1275
David K. Bainbridge794735f2020-02-11 21:01:37 -08001276 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001277}
1278
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001279// Add EthType flow to device with mac, vlanId as classifier for upstream and downstream
1280func (f *OpenOltFlowMgr) addEthTypeBasedFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001281 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001282 gemPortID uint32, vlanID uint32, tpID uint32, pbitToGem map[uint32]uint32, ethType uint32) error {
1283 logger.Infow(ctx, "adding-ethType-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301284 log.Fields{
1285 "intf-id": intfID,
1286 "onu-id": onuID,
1287 "port-no": portNo,
1288 "alloc-id": allocID,
1289 "gemport-id": gemPortID,
1290 "vlan-id": vlanID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001291 "flow": logicalFlow,
1292 "ethType": ethType})
manikkaraj kbf256be2019-03-25 00:13:48 +05301293
1294 uplinkClassifier := make(map[string]interface{})
1295 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301296
manikkaraj kbf256be2019-03-25 00:13:48 +05301297 // Fill Classfier
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001298 uplinkClassifier[EthType] = uint32(ethType)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001299 uplinkClassifier[PacketTagType] = SingleTag
1300 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001301 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301302 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001303 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001304 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001305 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301306 "device-id": f.deviceHandler.device.Id,
1307 "onu-id": onuID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001308 "intf-id": intfID,
1309 "ethType": ethType})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001310 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301311 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001312 //Add Uplink EthType Flow
1313 logger.Debugw(ctx, "creating-ul-ethType-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301314 log.Fields{
1315 "ul_classifier": uplinkClassifier,
1316 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001317 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301318 "device-id": f.deviceHandler.device.Id,
1319 "intf-id": intfID,
1320 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301321
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1323 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301324 return olterrors.NewErrInvalidValue(log.Fields{
1325 "classifier": uplinkClassifier,
1326 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301327 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001328 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301329 log.Fields{
1330 "classifier": *classifierProto,
1331 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001332 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001333 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301334 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301335 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001336 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301337 log.Fields{
1338 "action": *actionProto,
1339 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001340 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301341 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301342 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001343 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301344 "action": action,
1345 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001346 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301347 }
1348
David K. Bainbridge794735f2020-02-11 21:01:37 -08001349 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001350 OnuId: int32(onuID),
1351 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001352 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001353 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001354 AllocId: int32(allocID),
1355 NetworkIntfId: int32(networkIntfID),
1356 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301357 Classifier: classifierProto,
1358 Action: actionProto,
1359 Priority: int32(logicalFlow.Priority),
1360 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001361 PortNo: portNo,
1362 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001363 ReplicateFlow: len(pbitToGem) > 0,
1364 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001365 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001366 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001367 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001368 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001369 logger.Infow(ctx, "ethType-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301370 log.Fields{
1371 "device-id": f.deviceHandler.device.Id,
1372 "onu-id": onuID,
1373 "intf-id": intfID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001374 "ethType": ethType,
Shrey Baid26912972020-04-16 21:02:31 +05301375 })
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001376 flowInfo := rsrcMgr.FlowInfo{Flow: &upstreamFlow}
1377 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 +05301378 return olterrors.NewErrPersistence("update", "flow", upstreamFlow.FlowId,
1379 log.Fields{
1380 "flow": upstreamFlow,
1381 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301382 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301384}
1385
David K. Bainbridge794735f2020-02-11 21:01:37 -08001386func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001387 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001388
1389 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1390 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1391 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001392 if vlanID != ReservedVlan {
1393 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001394 classifier.OVid = vid
1395 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301396 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001397 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1398 vid := uint32(metadata)
1399 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001400 classifier.IVid = vid
1401 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301402 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301403 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001404 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301405 classifier.OPbits = vlanPcp
1406 } else {
1407 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301408 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001409 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1410 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1411 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1412 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001413 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001414 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1415 classifier.PktTagType = pktTagType
1416
1417 switch pktTagType {
1418 case SingleTag:
1419 case DoubleTag:
1420 case Untagged:
1421 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001422 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301423 }
1424 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001425 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301426}
1427
Gamze Abaka724d0852020-03-18 12:10:24 +00001428func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001429 var actionCmd openoltpb2.ActionCmd
1430 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301431 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001432 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301433 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001434 if _, ok := actionInfo[VlanPcp]; ok {
1435 action.Cmd.RemarkInnerPbits = true
1436 action.IPbits = actionInfo[VlanPcp].(uint32)
1437 if _, ok := actionInfo[VlanVid]; ok {
1438 action.Cmd.TranslateInnerTag = true
1439 action.IVid = actionInfo[VlanVid].(uint32)
1440 }
1441 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001442 } else if _, ok := actionInfo[PushVlan]; ok {
1443 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301444 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001445 if _, ok := actionInfo[VlanPcp]; ok {
1446 action.OPbits = actionInfo[VlanPcp].(uint32)
1447 action.Cmd.RemarkOuterPbits = true
1448 if _, ok := classifierInfo[VlanVid]; ok {
1449 action.IVid = classifierInfo[VlanVid].(uint32)
1450 action.Cmd.TranslateInnerTag = true
1451 }
1452 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001453 } else if _, ok := actionInfo[TrapToHost]; ok {
1454 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301455 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001456 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301457 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001458 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301459}
1460
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001461// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001462func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
1463 return f.techprofile[intfID].GetTechProfileInstanceKVPath(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301464}
1465
Gamze Abakafee36392019-10-03 11:17:24 +00001466// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001467func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301468 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001469 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1470
Gamze Abakafee36392019-10-03 11:17:24 +00001471 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301472 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001473 _ = olterrors.NewErrAdapter("delete-tech-profile-failed", log.Fields{"device-id": f.deviceHandler.device.Id}, err).Log()
Girish Gowdra54934262019-11-13 14:19:55 +05301474 // return err
1475 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001476 }
Girish Kumara1ea2aa2020-08-19 18:14:22 +00001477 logger.Debugw(ctx, "tech-profile-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001478 }
1479 return nil
1480}
1481
1482// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301483func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001484 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001485 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001486 }
npujarec5762e2020-01-01 14:08:48 +05301487 if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301488 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1489 log.Fields{
1490 "tp-id": tpID,
1491 "uni-port-name": uniPortName,
1492 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001493 }
1494 return nil
1495}
1496
David K. Bainbridge794735f2020-02-11 21:01:37 -08001497func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001498
1499 var intfID uint32
1500 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1501 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1502 */
1503 if deviceFlow.AccessIntfId != -1 {
1504 intfID = uint32(deviceFlow.AccessIntfId)
1505 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001506 // We need to log the valid interface ID.
1507 // 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 +00001508 intfID = uint32(deviceFlow.NetworkIntfId)
1509 }
1510
Neha Sharma96b7bf22020-06-15 10:37:32 +00001511 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301512 "flow": *deviceFlow,
1513 "device-id": f.deviceHandler.device.Id,
1514 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001515 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001516
1517 st, _ := status.FromError(err)
1518 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001519 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001520 "err": err,
1521 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301522 "device-id": f.deviceHandler.device.Id,
1523 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001524 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301525 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001526
1527 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001528 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301529 log.Fields{"err": err,
1530 "device-flow": deviceFlow,
1531 "device-id": f.deviceHandler.device.Id,
1532 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001533 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001534 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001535 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301536 log.Fields{
1537 "flow": *deviceFlow,
1538 "device-id": f.deviceHandler.device.Id,
1539 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001540
1541 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1542 if deviceFlow.AccessIntfId != -1 {
1543 // No need to register the flow if it is a trap on nni flow.
1544 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1545 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1546 return err
1547 }
1548 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001549 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001550}
1551
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1553 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301554 log.Fields{
1555 "flow": *deviceFlow,
1556 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001557 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001558 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001559 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301561 log.Fields{
1562 "err": err,
1563 "deviceFlow": deviceFlow,
1564 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001565 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001566 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001567 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001568 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001569
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001570 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001571 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001572 "of-flow-id": ofFlowID,
1573 "flow": *deviceFlow,
1574 "device-id": f.deviceHandler.device.Id,
1575 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001576 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301577}
1578
David K. Bainbridge794735f2020-02-11 21:01:37 -08001579func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001580
1581 classifierInfo := make(map[string]interface{})
1582 actionInfo := make(map[string]interface{})
1583
1584 classifierInfo[EthType] = uint32(LldpEthType)
1585 classifierInfo[PacketTagType] = Untagged
1586 actionInfo[TrapToHost] = true
1587
1588 // LLDP flow is installed to trap LLDP packets on the NNI port.
1589 // We manage flow_id resource pool on per PON port basis.
1590 // Since this situation is tricky, as a hack, we pass the NNI port
1591 // index (network_intf_id) as PON port Index for the flow_id resource
1592 // pool. Also, there is no ONU Id available for trapping LLDP packets
1593 // on NNI port, use onu_id as -1 (invalid)
1594 // ****************** CAVEAT *******************
1595 // This logic works if the NNI Port Id falls within the same valid
1596 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1597 // we need to have a re-look at this.
1598 // *********************************************
1599
1600 var onuID = -1
1601 var uniID = -1
1602 var gemPortID = -1
1603
Neha Sharma96b7bf22020-06-15 10:37:32 +00001604 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001605 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301606 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001607 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001608 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001609 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001610 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001611 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001612
David K. Bainbridge794735f2020-02-11 21:01:37 -08001613 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1614 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301615 return olterrors.NewErrInvalidValue(
1616 log.Fields{
1617 "classifier": classifierInfo,
1618 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001619 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001620 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301621 log.Fields{
1622 "classifier": *classifierProto,
1623 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001624 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001625 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301626 return olterrors.NewErrInvalidValue(
1627 log.Fields{
1628 "action": actionInfo,
1629 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001630 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001631 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301632 log.Fields{
1633 "action": *actionProto,
1634 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001635
1636 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1637 OnuId: int32(onuID), // OnuId not required
1638 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001639 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001640 FlowType: Downstream,
1641 NetworkIntfId: int32(networkInterfaceID),
1642 GemportId: int32(gemPortID),
1643 Classifier: classifierProto,
1644 Action: actionProto,
1645 Priority: int32(flow.Priority),
1646 Cookie: flow.Cookie,
1647 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001648 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001649 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301650 log.Fields{
1651 "flow": downstreamflow,
1652 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001653 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001654 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301655 log.Fields{
1656 "device-id": f.deviceHandler.device.Id,
1657 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001658 "flow-id": flow.Id})
1659 flowInfo := rsrcMgr.FlowInfo{Flow: &downstreamflow}
1660 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id, flowInfo); err != nil {
1661 return olterrors.NewErrPersistence("update", "flow", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301662 log.Fields{
1663 "flow": downstreamflow,
1664 "device-id": f.deviceHandler.device.Id}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001665 }
1666 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301667}
1668
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001669func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1670 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001671}
1672
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001673//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001674func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001675 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1676 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1677 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001678 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301679 log.Fields{
1680 "intf-id": intfID,
1681 "onu-id": onuID,
1682 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001683 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001684 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301685 return nil, olterrors.NewErrNotFound("onu-child-device",
1686 log.Fields{
1687 "onu-id": onuID,
1688 "intf-id": intfID,
1689 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001690 }
1691 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1692 //better to ad the device to cache here.
1693 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1694 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301696 log.Fields{
1697 "intf-id": intfID,
1698 "onu-id": onuID,
1699 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001700 }
1701
1702 return onuDev.(*OnuDevice), nil
1703}
1704
1705//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001706func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1707 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301708 log.Fields{
1709 "pon-port": intfID,
1710 "onu-id": onuID,
1711 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001712 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001714 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301715 return nil, olterrors.NewErrNotFound("onu",
1716 log.Fields{
1717 "interface-id": parentPortNo,
1718 "onu-id": onuID,
1719 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001720 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301721 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001722 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301723 log.Fields{
1724 "device-id": f.deviceHandler.device.Id,
1725 "child_device_id": onuDevice.Id,
1726 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301727 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301728}
1729
Neha Sharma96b7bf22020-06-15 10:37:32 +00001730func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1731 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301732 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001733 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301734 log.Fields{
1735 "intf-id": intfID,
1736 "onu-id": onuID,
1737 "uni-id": uniID,
1738 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001739 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301740 }
1741
1742 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001743 logger.Debugw(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301744 log.Fields{
1745 "msg": *delGemPortMsg,
1746 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001747 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301748 delGemPortMsg,
1749 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001750 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001751 onuDev.deviceType,
1752 onuDev.deviceID,
1753 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301754 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1755 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001756 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301757 "to-adapter": onuDev.deviceType,
1758 "onu-id": onuDev.deviceID,
1759 "proxyDeviceID": onuDev.proxyDeviceID,
1760 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301761 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001762 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301763 log.Fields{
1764 "msg": delGemPortMsg,
1765 "from-adapter": f.deviceHandler.device.Type,
1766 "to-adapter": onuDev.deviceType,
1767 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301768 return nil
1769}
1770
Neha Sharma96b7bf22020-06-15 10:37:32 +00001771func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1772 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301773 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001774 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301775 log.Fields{
1776 "intf-id": intfID,
1777 "onu-id": onuID,
1778 "uni-id": uniID,
1779 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001780 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301781 }
1782
1783 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001784 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301785 log.Fields{
1786 "msg": *delTcontMsg,
1787 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001788 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301789 delTcontMsg,
1790 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001791 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001792 onuDev.deviceType,
1793 onuDev.deviceID,
1794 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301795 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1796 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001797 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301798 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1799 "proxyDeviceID": onuDev.proxyDeviceID,
1800 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301801 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001802 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301803 log.Fields{
1804 "msg": delTcontMsg,
1805 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301806 return nil
1807}
1808
Girish Gowdrac3037402020-01-22 20:29:53 +05301809// Once the gemport is released for a given onu, it also has to be cleared from local cache
1810// which was used for deriving the gemport->logicalPortNo during packet-in.
1811// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1812// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001813func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001814
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001815 f.onuGemInfoLock.Lock()
1816 defer f.onuGemInfoLock.Unlock()
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001817
Neha Sharma96b7bf22020-06-15 10:37:32 +00001818 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301819 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001820 "gem-port-id": gemPortID,
1821 "intf-id": intfID,
1822 "onu-id": onuID,
1823 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001824 "onu-gem": f.onuGemInfo})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001825
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001826 onugem := f.onuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001827deleteLoop:
serkant.uluderya96af4932020-02-20 16:58:48 -08001828 for i, onu := range onugem {
Girish Gowdrac3037402020-01-22 20:29:53 +05301829 if onu.OnuID == onuID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001830 for j, gem := range onu.GemPorts {
Girish Gowdrac3037402020-01-22 20:29:53 +05301831 // If the gemport is found, delete it from local cache.
1832 if gem == gemPortID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001833 onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
1834 onugem[i] = onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835 logger.Infow(ctx, "removed-gemport-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301836 log.Fields{
1837 "intf-id": intfID,
1838 "onu-id": onuID,
1839 "deletedgemport-id": gemPortID,
1840 "gemports": onu.GemPorts,
1841 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001842 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301843 }
1844 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001845 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301846 }
1847 }
1848}
1849
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301850//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001851// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +05301852func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001853 gemPortID int32, flowID uint64, portNum uint32) error {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001854
Neha Sharma96b7bf22020-06-15 10:37:32 +00001855 tpID, err := getTpIDFromFlow(ctx, flow)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001856 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301857 return olterrors.NewErrNotFound("tp-id",
1858 log.Fields{
1859 "flow": flow,
1860 "intf": Intf,
1861 "onu-id": onuID,
1862 "uni-id": uniID,
1863 "device-id": f.deviceHandler.device.Id}, err)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001864 }
Gamze Abakafee36392019-10-03 11:17:24 +00001865
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001866 uni := getUniPortPath(f.deviceHandler.device.Id, Intf, onuID, uniID)
1867 tpPath := f.getTPpath(ctx, Intf, uni, tpID)
1868 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1869 log.Fields{
1870 "tpPath": tpPath,
1871 "device-id": f.deviceHandler.device.Id})
1872 techprofileInst, err := f.techprofile[Intf].GetTPInstanceFromKVStore(ctx, tpID, tpPath)
1873 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1874 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1875 log.Fields{
1876 "tp-id": tpID,
1877 "path": tpPath}, err)
1878 }
1879
1880 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1881
1882 if used {
1883 f.flowsUsedByGemPortKey.Lock()
1884 defer f.flowsUsedByGemPortKey.Unlock()
1885
1886 flowIDs := f.flowsUsedByGemPort[uint32(gemPortID)]
1887 for i, flowIDinMap := range flowIDs {
1888 if flowIDinMap == flowID {
1889 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
1890 // everytime flowsUsedByGemPort cache is updated the same should be updated
1891 // in kv store by calling UpdateFlowIDsForGem
1892 f.flowsUsedByGemPort[uint32(gemPortID)] = flowIDs
1893 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, Intf, uint32(gemPortID), flowIDs); err != nil {
1894 return err
1895 }
1896 break
1897 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001898 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001899 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1900 log.Fields{
1901 "gemport-id": gemPortID,
1902 "usedByFlows": flowIDs,
1903 "device-id": f.deviceHandler.device.Id})
1904 return nil
1905 }
1906 logger.Debugf(ctx, "gem-port-id %d is-not-used-by-another-flow--releasing-the-gem-port", gemPortID)
1907 f.resourceMgr.RemoveGemPortIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1908 // TODO: The TrafficQueue corresponding to this gem-port also should be removed immediately.
1909 // But it is anyway eventually removed later when the TechProfile is freed, so not a big issue for now.
1910 f.resourceMgr.RemoveGEMportPonportToOnuMapOnKVStore(ctx, uint32(gemPortID), Intf)
Esin Karamandf392e12020-12-16 13:33:09 +00001911 // also clear gem to uni cache
1912 f.removeFromGemToUniMap(gemPortKey{
1913 intfID: Intf,
1914 gemPort: uint32(gemPortID),
1915 })
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001916 f.deleteGemPortFromLocalCache(ctx, Intf, uint32(onuID), uint32(gemPortID))
Esin Karamandf392e12020-12-16 13:33:09 +00001917
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001918 f.onuIdsLock.Lock() // TODO: What is this lock?
1919
1920 //everytime an entry is deleted from flowsUsedByGemPort cache, the same should be updated in kv as well
1921 // by calling DeleteFlowIDsForGem
1922 f.flowsUsedByGemPortKey.Lock()
1923 delete(f.flowsUsedByGemPort, uint32(gemPortID))
1924 f.flowsUsedByGemPortKey.Unlock()
1925 f.resourceMgr.DeleteFlowIDsForGem(ctx, Intf, uint32(gemPortID))
1926 f.resourceMgr.FreeGemPortID(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1927
1928 f.onuIdsLock.Unlock()
1929
1930 // Delete the gem port on the ONU.
1931 if err := f.sendDeleteGemPortToChild(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
1932 logger.Errorw(ctx, "error-processing-delete-gem-port-towards-onu",
1933 log.Fields{
1934 "err": err,
1935 "intf": Intf,
1936 "onu-id": onuID,
1937 "uni-id": uniID,
1938 "device-id": f.deviceHandler.device.Id,
1939 "gemport-id": gemPortID})
1940 }
1941 switch techprofileInst := techprofileInst.(type) {
1942 case *tp.TechProfile:
1943 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
1944 if !ok {
1945 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID); err != nil {
1946 logger.Warn(ctx, err)
1947 }
1948 if err := f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID); err != nil {
1949 logger.Warn(ctx, err)
1950 }
1951 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 {
1952 logger.Warn(ctx, err)
1953 }
1954 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 {
1955 logger.Warn(ctx, err)
1956 }
1957 f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
1958 // Delete the TCONT on the ONU.
1959 if err := f.sendDeleteTcontToChild(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID, tpPath); err != nil {
1960 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
1961 log.Fields{
1962 "intf": Intf,
1963 "onu-id": onuID,
1964 "uni-id": uniID,
1965 "device-id": f.deviceHandler.device.Id,
1966