blob: eb3592597daf3841a7baeccade13f309201812ad [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"
Gamze Abaka01174422021-03-10 06:55:27 +000025 "github.com/opencord/voltha-lib-go/v4/pkg/meters"
Gamze Abaka7650be62021-02-26 10:50:36 +000026 "strconv"
serkant.uluderya4aff1862020-09-17 23:35:26 +030027 "strings"
28 "sync"
29
Girish Gowdraa09aeab2020-09-14 16:30:52 -070030 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
31 "github.com/opencord/voltha-lib-go/v4/pkg/log"
32 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080033 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070034 "github.com/opencord/voltha-protos/v4/go/common"
35 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
36 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
37 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
38 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
39 "github.com/opencord/voltha-protos/v4/go/voltha"
Chaitrashree G S579fe732019-08-20 20:50:47 -040040
Thomas Lee S94109f12020-03-03 16:39:29 +053041 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000042 "google.golang.org/grpc/codes"
43 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053044)
45
46const (
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070047 //IPProtoDhcp flow category
48 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053049
Girish Gowdraa09aeab2020-09-14 16:30:52 -070050 //IgmpProto proto value
51 IgmpProto = 2
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070052
53 //EapEthType eapethtype value
54 EapEthType = 0x888e
55 //LldpEthType lldp ethtype value
56 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000057 //IPv4EthType IPv4 ethernet type value
58 IPv4EthType = 0x800
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -030059 //PPPoEDEthType PPPoE discovery ethernet type value
60 PPPoEDEthType = 0x8863
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070061
Andrea Campanella7acc0b92020-02-14 09:20:49 +010062 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
63 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040064
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070065 //DefaultMgmtVlan default vlan value
66 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053067
manikkaraj kbf256be2019-03-25 00:13:48 +053068 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070069
David K. Bainbridge82efc492019-09-04 09:57:11 -070070 //Upstream constant
71 Upstream = "upstream"
72 //Downstream constant
73 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000074 //Multicast constant
75 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070076 //PacketTagType constant
77 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070078 //Untagged constant
79 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070080 //SingleTag constant
81 SingleTag = "single_tag"
82 //DoubleTag constant
83 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053084
85 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070086
87 //EthType constant
88 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000089 //EthDst constant
90 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070091 //TPID constant
92 TPID = "tpid"
93 //IPProto constant
94 IPProto = "ip_proto"
95 //InPort constant
96 InPort = "in_port"
97 //VlanVid constant
98 VlanVid = "vlan_vid"
99 //VlanPcp constant
100 VlanPcp = "vlan_pcp"
101
102 //UDPDst constant
103 UDPDst = "udp_dst"
104 //UDPSrc constant
105 UDPSrc = "udp_src"
106 //Ipv4Dst constant
107 Ipv4Dst = "ipv4_dst"
108 //Ipv4Src constant
109 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700110 //Metadata constant
111 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700112 //TunnelID constant
113 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700114 //Output constant
115 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000116 //GroupID constant
117 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700118 // Actions
119
120 //PopVlan constant
121 PopVlan = "pop_vlan"
122 //PushVlan constant
123 PushVlan = "push_vlan"
124 //TrapToHost constant
125 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400126 //MaxMeterBand constant
127 MaxMeterBand = 2
128 //VlanPCPMask contant
129 VlanPCPMask = 0xFF
130 //VlanvIDMask constant
131 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000132 //IntfID constant
133 IntfID = "intfId"
134 //OnuID constant
135 OnuID = "onuId"
136 //UniID constant
137 UniID = "uniId"
138 //PortNo constant
139 PortNo = "portNo"
140 //AllocID constant
141 AllocID = "allocId"
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000142 //GemID constant
143 GemID = "gemId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000144
145 //NoneOnuID constant
146 NoneOnuID = -1
147 //NoneUniID constant
148 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700149
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700150 // Max number of flows that can be queued per ONU
151 maxConcurrentFlowsPerOnu = 20
manikkaraj kbf256be2019-03-25 00:13:48 +0530152
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700153 bitMapPrefix = "0b"
154 pbit1 = '1'
155)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400156
Esin Karamandf392e12020-12-16 13:33:09 +0000157type gemPortKey struct {
158 intfID uint32
159 gemPort uint32
160}
161
Gamze Abakafee36392019-10-03 11:17:24 +0000162type schedQueue struct {
163 direction tp_pb.Direction
164 intfID uint32
165 onuID uint32
166 uniID uint32
167 tpID uint32
168 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700169 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000170 meterID uint32
171 flowMetadata *voltha.FlowMetadata
172}
173
Gamze Abaka7650be62021-02-26 10:50:36 +0000174type flowContext struct {
175 intfID uint32
176 onuID uint32
177 uniID uint32
178 portNo uint32
179 classifier map[string]interface{}
180 action map[string]interface{}
181 logicalFlow *ofp.OfpFlowStats
182 allocID uint32
183 gemPortID uint32
184 tpID uint32
185 pbitToGem map[uint32]uint32
186 gemToAes map[uint32]bool
187}
188
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700189// subscriberDataPathFlowIDKey is key to subscriberDataPathFlowIDMap map
190type subscriberDataPathFlowIDKey struct {
191 intfID uint32
192 onuID uint32
193 uniID uint32
194 direction string
195 tpID uint32
196}
197
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700198// This control block is created per flow add/remove and pushed on the incomingFlows channel slice
199// The flowControlBlock is then picked by the perOnuFlowHandlerRoutine for further processing.
200// There is on perOnuFlowHandlerRoutine routine per ONU that constantly monitors for any incoming
201// flow and processes it serially
202type flowControlBlock struct {
203 ctx context.Context // Flow handler context
204 addFlow bool // if true flow to be added, else removed
205 flow *voltha.OfpFlowStats // Flow message
206 flowMetadata *voltha.FlowMetadata // FlowMetadata that contains flow meter information. This can be nil for Flow remove
207 errChan *chan error // channel to report the Flow handling error
Esin Karamanccb714b2019-11-29 15:02:06 +0000208}
209
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700210//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530211type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700212 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
213 techprofile map[uint32]tp.TechProfileIf
214 deviceHandler *DeviceHandler
215 grpMgr *OpenOltGroupMgr
216 resourceMgr *rsrcMgr.OpenOltResourceMgr
217
218 onuIdsLock sync.RWMutex // TODO: Do we need this?
219
220 flowsUsedByGemPort map[uint32][]uint64 // gem port id to flow ids
221 flowsUsedByGemPortKey sync.RWMutex // lock to be used to access the flowsUsedByGemPort map
222
223 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
224 packetInGemPortLock sync.RWMutex
225
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700226 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700227 onuGemInfo []rsrcMgr.OnuGemInfo //onu, gem and uni info local cache
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700228 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700229 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700230
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700231 // Map of voltha flowID associated with subscriberDataPathFlowIDKey
232 // This information is not persisted on Kv store and hence should be reconciled on adapter restart
233 subscriberDataPathFlowIDMap map[subscriberDataPathFlowIDKey]uint64
234 subscriberDataPathFlowIDMapLock sync.RWMutex
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700235
236 // Slice of channels. Each channel in slice, index by ONU ID, queues flows per ONU.
237 // A go routine per ONU, waits on the unique channel (indexed by ONU ID) for incoming flows (add/remove)
238 incomingFlows []chan flowControlBlock
Esin Karamandf392e12020-12-16 13:33:09 +0000239
240 //this map keeps uni port info by gem and pon port. This relation shall be used for packet-out operations
241 gemToUniMap map[gemPortKey][]uint32
242 //We need to have a global lock on the gemToUniLock map
243 gemToUniLock sync.RWMutex
manikkaraj kbf256be2019-03-25 00:13:48 +0530244}
245
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700246//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700247func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000248 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530249 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530250 var err error
251 var idx uint32
252
manikkaraj kbf256be2019-03-25 00:13:48 +0530253 flowMgr.deviceHandler = dh
Girish Gowdra9602eb42020-09-09 15:50:39 -0700254 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530255 flowMgr.resourceMgr = rMgr
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000256 flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000257 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
258 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"error": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530259 return nil
260 }
William Kurkian740a09c2019-10-23 17:07:38 -0400261 flowMgr.onuIdsLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700262 flowMgr.flowsUsedByGemPort = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530263 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700264 flowMgr.packetInGemPortLock = sync.RWMutex{}
Girish Gowdra1183b4d2020-08-25 16:12:01 -0700265 flowMgr.onuGemInfoLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700266 flowMgr.subscriberDataPathFlowIDMap = make(map[subscriberDataPathFlowIDKey]uint64)
267 flowMgr.subscriberDataPathFlowIDMapLock = sync.RWMutex{}
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700268
269 // Create a slice of buffered channels for handling concurrent flows per ONU.
270 // The additional entry (+1) is to handle the NNI trap flows on a separate channel from individual ONUs channel
271 flowMgr.incomingFlows = make([]chan flowControlBlock, MaxOnusPerPon+1)
272 for i := range flowMgr.incomingFlows {
273 flowMgr.incomingFlows[i] = make(chan flowControlBlock, maxConcurrentFlowsPerOnu)
274 // Spin up a go routine to handling incoming flows (add/remove).
275 // There will be on go routine per ONU.
276 // This routine will be blocked on the flowMgr.incomingFlows[onu-id] channel for incoming flows.
277 go flowMgr.perOnuFlowHandlerRoutine(flowMgr.incomingFlows[i])
278 }
279
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530280 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700281 if flowMgr.onuGemInfo, err = rMgr.GetOnuGemInfo(ctx, ponPortIdx); err != nil {
282 logger.Error(ctx, "failed-to-load-onu-gem-info-cache")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530283 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700284 //Load flowID list per gem map per interface from the kvstore.
285 flowMgr.loadFlowIDlistForGem(ctx, idx)
Esin Karamanccb714b2019-11-29 15:02:06 +0000286 //load interface to multicast queue map from kv store
Esin Karamandf392e12020-12-16 13:33:09 +0000287
288 flowMgr.gemToUniMap = make(map[gemPortKey][]uint32)
289 flowMgr.gemToUniLock = sync.RWMutex{}
290
Girish Gowdra9602eb42020-09-09 15:50:39 -0700291 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700292 flowMgr.reconcileSubscriberDataPathFlowIDMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000293 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530294 return &flowMgr
295}
296
Esin Karamandf392e12020-12-16 13:33:09 +0000297// toGemToUniMap adds uni info consisting of onu and uni ID to the map and associates it with a gem port
298func (f *OpenOltFlowMgr) toGemToUniMap(ctx context.Context, gemPK gemPortKey, onuID uint32, uniID uint32) {
299 f.gemToUniLock.Lock()
300 f.gemToUniMap[gemPK] = []uint32{onuID, uniID}
301 f.gemToUniLock.Unlock()
302}
303
304// fromGemToUniMap returns onu and uni ID associated with the given key
305func (f *OpenOltFlowMgr) fromGemToUniMap(key gemPortKey) ([]uint32, bool) {
306 f.gemToUniLock.RLock()
307 defer f.gemToUniLock.RUnlock()
308 val, ok := f.gemToUniMap[key]
309 return val, ok
310}
311
312// removeFromGemToUniMap removes an entry associated with the given key from gemToUniMap
313func (f *OpenOltFlowMgr) removeFromGemToUniMap(key gemPortKey) {
314 f.gemToUniLock.Lock()
315 defer f.gemToUniLock.Unlock()
316 delete(f.gemToUniMap, key)
317}
318
Kent Hagermane6ff1012020-07-14 15:07:53 -0400319func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700320 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
321 // Flow is not replicated in this case, we need to register the flow for a single gem-port
322 return f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
323 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
324 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
325 for _, gemPort := range deviceFlow.PbitToGemport {
326 if err := f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
327 return err
328 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700329 }
Gamze Abakafee36392019-10-03 11:17:24 +0000330 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700331 return nil
332}
333
334func (f *OpenOltFlowMgr) registerFlowIDForGem(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
335 f.flowsUsedByGemPortKey.Lock()
336 flowIDList, ok := f.flowsUsedByGemPort[gemPortID]
337 if !ok {
338 flowIDList = []uint64{flowFromCore.Id}
339 }
340 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
341 f.flowsUsedByGemPort[gemPortID] = flowIDList
342 f.flowsUsedByGemPortKey.Unlock()
343
344 // update the flowids for a gem to the KVstore
345 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400346}
347
Girish Gowdra9602eb42020-09-09 15:50:39 -0700348func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000349 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200350 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000351 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530352 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700353 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530354
Neha Sharma96b7bf22020-06-15 10:37:32 +0000355 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530356 "device-id": f.deviceHandler.device.Id,
357 "intf-id": intfID,
358 "onu-id": onuID,
359 "uni-id": uniID,
360 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700361 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530362 "action": actionInfo,
363 "usmeter-iD": UsMeterID,
364 "dsmeter-iD": DsMeterID,
365 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400366 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
367 // is because the flow is an NNI flow and there would be no onu resources associated with it
368 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400369 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200370 cause := "no-onu-id-for-flow"
371 fields := log.Fields{
372 "onu": onuID,
373 "port-no": portNo,
374 "classifer": classifierInfo,
375 "action": actionInfo,
376 "device-id": f.deviceHandler.device.Id}
377 logger.Errorw(ctx, cause, fields)
378 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530379 }
380
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700381 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000382 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530383 "uni": uni,
384 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530385
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700386 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
387 "device-id": f.deviceHandler.device.Id,
388 "intf-id": intfID,
389 "onu-id": onuID,
390 "uni-id": uniID,
391 "port-no": portNo,
392 "classifier": classifierInfo,
393 "action": actionInfo,
394 "usmeter-id": UsMeterID,
395 "dsmeter-id": DsMeterID,
396 "tp-id": TpID})
397 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
398 if allocID == 0 || gemPorts == nil || TpInst == nil {
399 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
400 return olterrors.NewErrNotFound(
401 "alloc-id-gem-ports-tp-unavailable",
402 nil, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400403 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700404 args := make(map[string]uint32)
405 args[IntfID] = intfID
406 args[OnuID] = onuID
407 args[UniID] = uniID
408 args[PortNo] = portNo
409 args[AllocID] = allocID
410
411 /* Flows can be added specific to gemport if p-bits are received.
412 * If no pbit mentioned then adding flows for all gemports
413 */
414 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
415
Andrea Campanellabfe08432020-09-11 17:07:03 +0200416 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530417}
418
salmansiddiqui7ac62132019-08-22 03:58:50 +0000419// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530420func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400421
Neha Sharma96b7bf22020-06-15 10:37:32 +0000422 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530423 log.Fields{"dir": sq.direction,
424 "intf-id": sq.intfID,
425 "onu-id": sq.onuID,
426 "uni-id": sq.uniID,
427 "tp-id": sq.tpID,
428 "meter-id": sq.meterID,
429 "tp-inst": sq.tpInst,
430 "flowmetadata": sq.flowMetadata,
431 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400432
Gamze Abakafee36392019-10-03 11:17:24 +0000433 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000434 if err != nil {
435 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400436 }
437
438 /* Lets make a simple assumption that if the meter-id is present on the KV store,
439 * then the scheduler and queues configuration is applied on the OLT device
440 * in the given direction.
441 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000442
Manikkaraj kb1d51442019-07-23 10:41:02 -0400443 var SchedCfg *tp_pb.SchedulerConfig
Girish Gowdraa482f272021-03-24 23:04:19 -0700444 meterInfo, err := f.resourceMgr.GetMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400445 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530446 return olterrors.NewErrNotFound("meter",
447 log.Fields{"intf-id": sq.intfID,
448 "onu-id": sq.onuID,
449 "uni-id": sq.uniID,
450 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400451 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000452
Girish Gowdraa482f272021-03-24 23:04:19 -0700453 if meterInfo != nil {
454 logger.Debugw(ctx, "scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id, "meter-id": sq.meterID})
455 if meterInfo.MeterConfig.MeterId == sq.meterID {
456 if err := f.resourceMgr.HandleMeterInfoRefCntUpdate(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, true); err != nil {
457 return err
458 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400459 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400460 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530461 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800462 "unsupported": "meter-id",
Girish Gowdraa482f272021-03-24 23:04:19 -0700463 "kv-store-meter-id": meterInfo.MeterConfig.MeterId,
Shrey Baid26912972020-04-16 21:02:31 +0530464 "meter-id-in-flow": sq.meterID,
465 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400466 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000467
Neha Sharma96b7bf22020-06-15 10:37:32 +0000468 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530469 log.Fields{
470 "meter-id": sq.meterID,
471 "direction": Direction,
472 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000473
Gamze Abakafee36392019-10-03 11:17:24 +0000474 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000475 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Gamze Abakafee36392019-10-03 11:17:24 +0000476 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000477 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400478 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000479
480 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530481 return olterrors.NewErrNotFound("scheduler-config",
482 log.Fields{
483 "intf-id": sq.intfID,
484 "direction": sq.direction,
485 "tp-inst": sq.tpInst,
486 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000487 }
488
Girish Gowdraa482f272021-03-24 23:04:19 -0700489 found := false
490 meterInfo = &rsrcMgr.MeterInfo{}
Gamze Abakafee36392019-10-03 11:17:24 +0000491 if sq.flowMetadata != nil {
492 for _, meter := range sq.flowMetadata.Meters {
493 if sq.meterID == meter.MeterId {
Girish Gowdraa482f272021-03-24 23:04:19 -0700494 meterInfo.MeterConfig = ofp.OfpMeterConfig{}
495 meterInfo.MeterConfig.MeterId = meter.MeterId
496 meterInfo.MeterConfig.Flags = meter.Flags
497 meterInfo.RefCnt = 1 // initialize it to 1, since this is the first flow that referenced the meter id.
498 meterInfo.MeterConfig.Bands = append(meterInfo.MeterConfig.Bands, meter.Bands...)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000499 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Girish Gowdraa482f272021-03-24 23:04:19 -0700500 log.Fields{"meterConfig": meterInfo.MeterConfig,
Shrey Baid26912972020-04-16 21:02:31 +0530501 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -0700502 found = true
Manikkaraj kb1d51442019-07-23 10:41:02 -0400503 break
504 }
505 }
506 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000507 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400508 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700509 if !found {
Thomas Lee S94109f12020-03-03 16:39:29 +0530510 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800511 "reason": "Could-not-get-meterbands-from-flowMetadata",
512 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530513 "meter-id": sq.meterID,
514 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400515 }
Gamze Abaka01174422021-03-10 06:55:27 +0000516
517 var TrafficShaping *tp_pb.TrafficShapingInfo
518 if TrafficShaping, err = meters.GetTrafficShapingInfo(ctx, &meterInfo.MeterConfig); err != nil {
519 return olterrors.NewErrInvalidValue(log.Fields{
520 "reason": "invalid-meter-config",
521 "meter-id": sq.meterID,
522 "device-id": f.deviceHandler.device.Id}, nil)
523 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400524
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700525 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000526 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400527
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700528 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530529 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
530 log.Fields{"intf-id": sq.intfID,
531 "direction": sq.direction,
532 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400533 }
534
salmansiddiqui7ac62132019-08-22 03:58:50 +0000535 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400536 * store the meter id on the KV store, for further reference.
537 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700538 if err := f.resourceMgr.StoreMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, meterInfo); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530539 return olterrors.NewErrAdapter("failed-updating-meter-id",
540 log.Fields{"onu-id": sq.onuID,
541 "meter-id": sq.meterID,
542 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400543 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000544 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530545 log.Fields{"direction": Direction,
Girish Gowdraa482f272021-03-24 23:04:19 -0700546 "meter-info": meterInfo,
547 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400548 return nil
549}
550
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700551func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000552 trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000553
554 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530555 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
556 log.Fields{"intf-id": sq.intfID,
557 "direction": sq.direction,
558 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000559 }
560
Neha Sharma96b7bf22020-06-15 10:37:32 +0000561 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530562 log.Fields{
563 "direction": sq.direction,
564 "TrafficScheds": TrafficSched,
565 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530566 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Girish Kumar8f73fe02019-12-09 13:19:37 +0000567 IntfId: sq.intfID, OnuId: sq.onuID,
568 UniId: sq.uniID, PortNo: sq.uniPort,
569 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000570 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000571 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530573 "direction": sq.direction,
574 "traffic-queues": trafficQueues,
575 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000576
577 // On receiving the CreateTrafficQueues request, the driver should create corresponding
578 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000579 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530580 log.Fields{"direction": sq.direction,
581 "traffic-queues": trafficQueues,
582 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530583 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000584 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
585 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000586 TrafficQueues: trafficQueues,
587 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530588 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000589 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000590 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530591 "direction": sq.direction,
592 "traffic-queues": trafficQueues,
593 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000594
Esin Karamanccb714b2019-11-29 15:02:06 +0000595 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000596 multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile))
Esin Karamanccb714b2019-11-29 15:02:06 +0000597 if len(multicastTrafficQueues) > 0 {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700598 if _, present := f.grpMgr.GetInterfaceToMcastQueueMap(sq.intfID); !present {
Esin Karamanccb714b2019-11-29 15:02:06 +0000599 //assumed that there is only one queue per PON for the multicast service
600 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
601 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000602 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000603 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700604 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000605 gemPortID: multicastQueuePerPonPort.GemportId,
606 servicePriority: multicastQueuePerPonPort.Priority,
607 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700608 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000609 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400610 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
611 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"error": err})
612 return err
613 }
Shrey Baid26912972020-04-16 21:02:31 +0530614
Neha Sharma96b7bf22020-06-15 10:37:32 +0000615 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000616 }
617 }
618 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000619 return nil
620}
621
salmansiddiqui7ac62132019-08-22 03:58:50 +0000622// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530623func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400624
625 var Direction string
626 var SchedCfg *tp_pb.SchedulerConfig
627 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000628 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530629 log.Fields{
630 "direction": sq.direction,
631 "intf-id": sq.intfID,
632 "onu-id": sq.onuID,
633 "uni-id": sq.uniID,
634 "uni-port": sq.uniPort,
635 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000636 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000637 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400638 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000639 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000640 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400641 Direction = "downstream"
642 }
643
Girish Kumar8f73fe02019-12-09 13:19:37 +0000644 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530645 return olterrors.NewErrNotFound("scheduler-config",
646 log.Fields{
647 "int-id": sq.intfID,
648 "direction": sq.direction,
649 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000650 }
651
Girish Gowdraa482f272021-03-24 23:04:19 -0700652 TrafficShaping := &tp_pb.TrafficShapingInfo{} // this info is not really useful for the agent during flow removal. Just use default values.
Manikkaraj kb1d51442019-07-23 10:41:02 -0400653
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700654 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000655 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000656
Neha Sharma96b7bf22020-06-15 10:37:32 +0000657 TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000658 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530659 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
660 log.Fields{
661 "intf-id": sq.intfID,
662 "direction": sq.direction,
663 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000664 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400665
npujarec5762e2020-01-01 14:08:48 +0530666 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000667 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
668 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000669 TrafficQueues: TrafficQueues,
670 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000671 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530672 log.Fields{
673 "intf-id": sq.intfID,
674 "traffic-queues": TrafficQueues,
675 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400676 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000677 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530678 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Gamze Abakafee36392019-10-03 11:17:24 +0000679 IntfId: sq.intfID, OnuId: sq.onuID,
680 UniId: sq.uniID, PortNo: sq.uniPort,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400681 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000682 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530683 log.Fields{
684 "intf-id": sq.intfID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700685 "traffic-schedulers": TrafficSched,
686 "onu-id": sq.onuID,
687 "uni-id": sq.uniID,
688 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400689 }
690
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700691 logger.Infow(ctx, "removed-traffic-schedulers-successfully",
692 log.Fields{"device-id": f.deviceHandler.device.Id,
693 "intf-id": sq.intfID,
694 "onu-id": sq.onuID,
695 "uni-id": sq.uniID,
696 "uni-port": sq.uniPort})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000697
698 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400699 * delete the meter id on the KV store.
700 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700701 err = f.resourceMgr.RemoveMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400702 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530703 return olterrors.NewErrAdapter("unable-to-remove-meter",
704 log.Fields{
705 "onu": sq.onuID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700706 "device-id": f.deviceHandler.device.Id,
707 "intf-id": sq.intfID,
708 "onu-id": sq.onuID,
709 "uni-id": sq.uniID,
710 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400711 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000712 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530713 log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530714 "dir": Direction,
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})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400720 return err
721}
722
Gamze Abakafee36392019-10-03 11:17:24 +0000723// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700724func (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 +0000725 var allocIDs []uint32
726 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530727 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530728 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000729 var err error
Gamze Abakafee36392019-10-03 11:17:24 +0000730
npujarec5762e2020-01-01 14:08:48 +0530731 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
732 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000733 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530734
Neha Sharma96b7bf22020-06-15 10:37:32 +0000735 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530736 "intf-id": intfID,
737 "onu-id": onuID,
738 "uni-id": uniID,
739 "device-id": f.deviceHandler.device.Id,
740 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530741
Manikkaraj kb1d51442019-07-23 10:41:02 -0400742 // Check tech profile instance already exists for derived port name
npujarec5762e2020-01-01 14:08:48 +0530743 techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000744 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000745 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530746 log.Fields{
747 "path": tpPath,
748 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530749 techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000750 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530751 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000752 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530753 log.Fields{
754 "error": err,
755 "tp-id": TpID,
756 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000757 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530758 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400759 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
760 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"error": err})
761 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530762 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000763 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530764 log.Fields{
765 "uni": uni,
766 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530767 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530768 }
Gamze Abakafee36392019-10-03 11:17:24 +0000769
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700770 switch tpInst := techProfileInstance.(type) {
771 case *tp.TechProfile:
772 if UsMeterID != 0 {
773 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
774 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
775 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000776 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700777 log.Fields{
778 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700779 "onu-id": onuID,
780 "uni-id": uniID,
781 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700782 "meter-id": UsMeterID,
783 "device-id": f.deviceHandler.device.Id})
784 return 0, nil, nil
785 }
786 }
787 if DsMeterID != 0 {
788 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
789 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
790 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000791 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700792 log.Fields{
793 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700794 "onu-id": onuID,
795 "uni-id": uniID,
796 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700797 "meter-id": DsMeterID,
798 "device-id": f.deviceHandler.device.Id})
799 return 0, nil, nil
800 }
801 }
802 allocID := tpInst.UsScheduler.AllocID
803 for _, gem := range tpInst.UpstreamGemPortAttributeList {
804 gemPortIDs = append(gemPortIDs, gem.GemportID)
805 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700806 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000807
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700808 if tpInstanceExists {
809 return allocID, gemPortIDs, techProfileInstance
810 }
811
812 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700813 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700814 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000815 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700816 log.Fields{
Matteo Scandolo84585372021-03-18 14:21:22 -0700817 "intf-id": intfID,
818 "onu-id": onuID,
819 "uni-id": uniID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700820 "alloc-ids": allocIDs,
821 "gemports": allgemPortIDs,
822 "device-id": f.deviceHandler.device.Id})
823 // Send Tconts and GEM ports to KV store
824 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530825 return allocID, gemPortIDs, techProfileInstance
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700826 case *tp.EponProfile:
827 // CreateSchedulerQueues for EPON needs to be implemented here
828 // when voltha-protos for EPON is completed.
829 allocID := tpInst.AllocID
830 for _, gem := range tpInst.UpstreamQueueAttributeList {
831 gemPortIDs = append(gemPortIDs, gem.GemportID)
832 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700833 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700834
835 if tpInstanceExists {
836 return allocID, gemPortIDs, techProfileInstance
837 }
838
839 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700840 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700841 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000842 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700843 log.Fields{
844 "alloc-ids": allocIDs,
845 "gemports": allgemPortIDs,
846 "device-id": f.deviceHandler.device.Id})
847 // Send Tconts and GEM ports to KV store
848 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
849 return allocID, gemPortIDs, techProfileInstance
850 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000851 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700852 log.Fields{
853 "tpInst": tpInst})
854 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530855 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530856}
857
npujarec5762e2020-01-01 14:08:48 +0530858func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530859
Neha Sharma96b7bf22020-06-15 10:37:32 +0000860 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530861 log.Fields{
862 "intf-id": intfID,
863 "onu-id": onuID,
864 "uni-id": uniID,
865 "alloc-id": allocID,
866 "gemport-ids": gemPortIDs,
867 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530868 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530869 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 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 +0530871 }
npujarec5762e2020-01-01 14:08:48 +0530872 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000873 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 +0530874 }
npujarec5762e2020-01-01 14:08:48 +0530875 if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000876 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 +0000877 } else {
878 //add to gem to uni cache
879 f.addGemPortUniAssociationsToCache(ctx, intfID, onuID, uniID, gemPortIDs)
manikkaraj kbf256be2019-03-25 00:13:48 +0530880 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000881 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 -0400882 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530883 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400884 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530885}
886
Esin Karamandf392e12020-12-16 13:33:09 +0000887//addGemPortUniAssociationsToCache
888func (f *OpenOltFlowMgr) addGemPortUniAssociationsToCache(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortIDs []uint32) {
889 for _, gemPortID := range gemPortIDs {
890 key := gemPortKey{
891 intfID: intfID,
892 gemPort: gemPortID,
893 }
894 f.toGemToUniMap(ctx, key, onuID, uniID)
895 }
896 logger.Debugw(ctx, "gem-to-uni-info-added-to-cache", log.Fields{"device-id": f.deviceHandler.device.Id, "intfID": intfID,
897 "gemPortIDs": gemPortIDs, "onuID": onuID, "uniID": uniID})
898}
899
Neha Sharma96b7bf22020-06-15 10:37:32 +0000900func (f *OpenOltFlowMgr) populateTechProfilePerPonPort(ctx context.Context) error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000901 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530902 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000903 for _, intfID := range techRange.IntfIds {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700904 f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[intfID].TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400905 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000906 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530907 log.Fields{
908 "intf-id": intfID,
909 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530910 }
911 }
912 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400913 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530914 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530915 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800916 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530917 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
918 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530919 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000920 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530921 log.Fields{
922 "numofTech": tpCount,
923 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
924 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530925 return nil
926}
927
Gamze Abaka7650be62021-02-26 10:50:36 +0000928func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
929 flowContext.classifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000930 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530931 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000932 "uplinkClassifier": flowContext.classifier,
933 "uplinkAction": flowContext.action})
934 return f.addSymmetricDataPathFlow(ctx, flowContext, Upstream)
Manikkaraj k884c1242019-04-11 16:26:42 +0530935 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530936}
937
Gamze Abaka7650be62021-02-26 10:50:36 +0000938func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
939 downlinkClassifier := flowContext.classifier
940 downlinkAction := flowContext.action
941
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700942 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000943 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530944 log.Fields{
945 "downlinkClassifier": downlinkClassifier,
946 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400947 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
948 if vlan, exists := downlinkClassifier[VlanVid]; exists {
949 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700950 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Gamze Abaka7650be62021-02-26 10:50:36 +0000951 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, flowContext.intfID, flowContext.onuID, flowContext.uniID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000952 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530953 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000954 "flow": flowContext.logicalFlow,
Shrey Baid26912972020-04-16 21:02:31 +0530955 "device-id": f.deviceHandler.device.Id,
Gamze Abaka7650be62021-02-26 10:50:36 +0000956 "onu-id": flowContext.onuID,
957 "intf-id": flowContext.intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800958 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400959 }
960 }
961 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530962 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400963
Manikkaraj k884c1242019-04-11 16:26:42 +0530964 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700965 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400966 // vlan_vid is a uint32. must be type asserted as such or conversion fails
967 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530968 if ok {
969 downlinkAction[VlanVid] = dlClVid & 0xfff
970 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530971 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530972 "reason": "failed-to-convert-vlanid-classifier",
973 "vlan-id": VlanVid,
974 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530975 }
976
Gamze Abaka7650be62021-02-26 10:50:36 +0000977 return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
manikkaraj kbf256be2019-03-25 00:13:48 +0530978}
979
Gamze Abaka7650be62021-02-26 10:50:36 +0000980func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, flowContext *flowContext, direction string) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700981
982 var inverseDirection string
983 if direction == Upstream {
984 inverseDirection = Downstream
985 } else {
986 inverseDirection = Upstream
987 }
988
Gamze Abaka7650be62021-02-26 10:50:36 +0000989 intfID := flowContext.intfID
990 onuID := flowContext.onuID
991 uniID := flowContext.uniID
992 classifier := flowContext.classifier
993 action := flowContext.action
994 allocID := flowContext.allocID
995 gemPortID := flowContext.gemPortID
996 tpID := flowContext.tpID
997 logicalFlow := flowContext.logicalFlow
Neha Sharma96b7bf22020-06-15 10:37:32 +0000998 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530999 log.Fields{
1000 "intf-id": intfID,
1001 "onu-id": onuID,
1002 "uni-id": uniID,
1003 "device-id": f.deviceHandler.device.Id,
1004 "classifier": classifier,
1005 "action": action,
1006 "direction": direction,
1007 "alloc-id": allocID,
1008 "gemport-id": gemPortID,
1009 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001010
1011 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001012 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +05301013 log.Fields{
1014 "device-id": f.deviceHandler.device.Id,
1015 "intf-id": intfID,
1016 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001017 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301018 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001019 classifierProto, err := makeOpenOltClassifierField(classifier)
1020 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301021 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301022 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001023 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301024 log.Fields{
1025 "classifier": *classifierProto,
1026 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001027 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001028 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301029 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301030 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301032 log.Fields{
1033 "action": *actionProto,
1034 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001035 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301036 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301037 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -08001038 log.Fields{
1039 "classifier": classifier,
1040 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301041 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001042 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301043 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001044
1045 // Get symmetric flowID if it exists
1046 // This symmetric flowID will be needed by agent software to use the same device flow-id that was used for the
1047 // symmetric flow earlier
1048 // symmetric flowID 0 is considered by agent as non-existent symmetric flow
1049 keySymm := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: inverseDirection, tpID: tpID}
1050 f.subscriberDataPathFlowIDMapLock.RLock()
1051 symmFlowID := f.subscriberDataPathFlowIDMap[keySymm]
1052 f.subscriberDataPathFlowIDMapLock.RUnlock()
1053
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001054 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001055 OnuId: int32(onuID),
1056 UniId: int32(uniID),
1057 FlowId: logicalFlow.Id,
1058 FlowType: direction,
1059 AllocId: int32(allocID),
1060 NetworkIntfId: int32(networkIntfID),
1061 GemportId: int32(gemPortID),
1062 Classifier: classifierProto,
1063 Action: actionProto,
1064 Priority: int32(logicalFlow.Priority),
1065 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001066 PortNo: flowContext.portNo,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001067 TechProfileId: tpID,
Gamze Abaka7650be62021-02-26 10:50:36 +00001068 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1069 PbitToGemport: flowContext.pbitToGem,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001070 SymmetricFlowId: symmFlowID,
Gamze Abaka7650be62021-02-26 10:50:36 +00001071 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001072 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001073 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001074 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301075 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001076 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301077 log.Fields{"direction": direction,
1078 "device-id": f.deviceHandler.device.Id,
1079 "flow": flow,
1080 "intf-id": intfID,
1081 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001082 flowInfo := rsrcMgr.FlowInfo{Flow: &flow, IsSymmtricFlow: true}
1083 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(flow.AccessIntfId), flow.OnuId, flow.UniId, flow.FlowId, flowInfo); err != nil {
1084 return olterrors.NewErrPersistence("update", "flow", logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301085 log.Fields{
1086 "flow": flow,
1087 "device-id": f.deviceHandler.device.Id,
1088 "intf-id": intfID,
1089 "onu-id": onuID}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001090 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001091
1092 // Update the current flowID to the map
1093 keyCurr := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: direction, tpID: tpID}
1094 f.subscriberDataPathFlowIDMapLock.Lock()
1095 f.subscriberDataPathFlowIDMap[keyCurr] = logicalFlow.Id
1096 f.subscriberDataPathFlowIDMapLock.Unlock()
1097
David K. Bainbridge794735f2020-02-11 21:01:37 -08001098 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301099}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001100
Gamze Abaka7650be62021-02-26 10:50:36 +00001101func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1102
1103 intfID := flowContext.intfID
1104 onuID := flowContext.onuID
1105 uniID := flowContext.uniID
1106 logicalFlow := flowContext.logicalFlow
1107 classifier := flowContext.classifier
1108 action := flowContext.action
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301109
Neha Sharma96b7bf22020-06-15 10:37:32 +00001110 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301111 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301112 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001113 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301114 "action": action,
1115 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001116 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301117 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301118
1119 // Clear the action map
1120 for k := range action {
1121 delete(action, k)
1122 }
1123
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001124 action[TrapToHost] = true
1125 classifier[UDPSrc] = uint32(68)
1126 classifier[UDPDst] = uint32(67)
1127 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301128
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001129 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001130 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301131 log.Fields{
1132 "device-id": f.deviceHandler.device.Id,
1133 "intf-id": intfID,
1134 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001135 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301136 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301137
Neha Sharma96b7bf22020-06-15 10:37:32 +00001138 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301139 log.Fields{
1140 "ul_classifier": classifier,
1141 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001142 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301143 "intf-id": intfID,
1144 "onu-id": onuID,
1145 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301146
David K. Bainbridge794735f2020-02-11 21:01:37 -08001147 classifierProto, err := makeOpenOltClassifierField(classifier)
1148 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301149 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301150 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001151 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001152 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001153 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301154 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301155 }
1156
David K. Bainbridge794735f2020-02-11 21:01:37 -08001157 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001158 OnuId: int32(onuID),
1159 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001160 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001161 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001162 AllocId: int32(flowContext.allocID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001163 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001164 GemportId: int32(flowContext.gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301165 Classifier: classifierProto,
1166 Action: actionProto,
1167 Priority: int32(logicalFlow.Priority),
1168 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001169 PortNo: flowContext.portNo,
1170 TechProfileId: flowContext.tpID,
1171 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1172 PbitToGemport: flowContext.pbitToGem,
1173 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001174 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001175 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001176 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001177 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001178 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301179 log.Fields{
1180 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001181 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301182 "intf-id": intfID,
1183 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001184 flowInfo := rsrcMgr.FlowInfo{Flow: &dhcpFlow}
1185 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 +05301186 return olterrors.NewErrPersistence("update", "flow", dhcpFlow.FlowId,
1187 log.Fields{
1188 "flow": dhcpFlow,
1189 "device-id": f.deviceHandler.device.Id}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301190 }
1191
David K. Bainbridge794735f2020-02-11 21:01:37 -08001192 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301193}
1194
Esin Karamanae41e2b2019-12-17 18:13:13 +00001195//addIGMPTrapFlow creates IGMP trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001196func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1197 delete(flowContext.classifier, VlanVid)
1198 return f.addUpstreamTrapFlow(ctx, flowContext)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001199}
1200
1201//addUpstreamTrapFlow creates a trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001202func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, flowContext *flowContext) error {
1203
1204 intfID := flowContext.intfID
1205 onuID := flowContext.onuID
1206 uniID := flowContext.uniID
1207 logicalFlow := flowContext.logicalFlow
1208 classifier := flowContext.classifier
1209 action := flowContext.action
Esin Karamanae41e2b2019-12-17 18:13:13 +00001210
Neha Sharma96b7bf22020-06-15 10:37:32 +00001211 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001212 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301213 return olterrors.NewErrNotFound("nni-interface-id",
1214 log.Fields{
1215 "classifier": classifier,
1216 "action": action,
1217 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001218 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001219 }
1220
1221 // Clear the action map
1222 for k := range action {
1223 delete(action, k)
1224 }
1225
1226 action[TrapToHost] = true
1227 classifier[PacketTagType] = SingleTag
Esin Karamanae41e2b2019-12-17 18:13:13 +00001228
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001229 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001230 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001231 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001232 }
1233
Neha Sharma96b7bf22020-06-15 10:37:32 +00001234 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301235 log.Fields{
1236 "ul_classifier": classifier,
1237 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001238 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301239 "device-id": f.deviceHandler.device.Id,
1240 "intf-id": intfID,
1241 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001242
David K. Bainbridge794735f2020-02-11 21:01:37 -08001243 classifierProto, err := makeOpenOltClassifierField(classifier)
1244 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301245 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001246 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301248 log.Fields{
1249 "classifier": *classifierProto,
1250 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001251 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001252 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301253 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001254 }
1255
David K. Bainbridge794735f2020-02-11 21:01:37 -08001256 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001257 OnuId: int32(onuID),
1258 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001259 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001260 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001261 AllocId: int32(flowContext.allocID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001262 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001263 GemportId: int32(flowContext.gemPortID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001264 Classifier: classifierProto,
1265 Action: actionProto,
1266 Priority: int32(logicalFlow.Priority),
1267 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001268 PortNo: flowContext.portNo,
1269 TechProfileId: flowContext.tpID,
1270 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1271 PbitToGemport: flowContext.pbitToGem,
1272 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001273 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001274
David K. Bainbridge794735f2020-02-11 21:01:37 -08001275 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001276 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 -08001277 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001278
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001279 flowInfo := rsrcMgr.FlowInfo{Flow: &flow}
1280 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 +05301281 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 +00001282 }
1283
David K. Bainbridge794735f2020-02-11 21:01:37 -08001284 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001285}
1286
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001287// Add EthType flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka7650be62021-02-26 10:50:36 +00001288func (f *OpenOltFlowMgr) addEthTypeBasedFlow(ctx context.Context, flowContext *flowContext, vlanID uint32, ethType uint32) error {
1289 intfID := flowContext.intfID
1290 onuID := flowContext.onuID
1291 uniID := flowContext.uniID
1292 portNo := flowContext.portNo
1293 allocID := flowContext.allocID
1294 gemPortID := flowContext.gemPortID
1295 logicalFlow := flowContext.logicalFlow
1296 classifier := flowContext.classifier
1297 action := flowContext.action
1298
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001299 logger.Infow(ctx, "adding-ethType-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301300 log.Fields{
1301 "intf-id": intfID,
1302 "onu-id": onuID,
1303 "port-no": portNo,
1304 "alloc-id": allocID,
1305 "gemport-id": gemPortID,
1306 "vlan-id": vlanID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001307 "flow": logicalFlow,
1308 "ethType": ethType})
manikkaraj kbf256be2019-03-25 00:13:48 +05301309
1310 uplinkClassifier := make(map[string]interface{})
1311 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301312
manikkaraj kbf256be2019-03-25 00:13:48 +05301313 // Fill Classfier
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001314 uplinkClassifier[EthType] = uint32(ethType)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001315 uplinkClassifier[PacketTagType] = SingleTag
1316 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001317 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301318 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001319 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001320 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001321 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301322 "device-id": f.deviceHandler.device.Id,
1323 "onu-id": onuID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001324 "intf-id": intfID,
1325 "ethType": ethType})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301327 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001328 //Add Uplink EthType Flow
1329 logger.Debugw(ctx, "creating-ul-ethType-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301330 log.Fields{
1331 "ul_classifier": uplinkClassifier,
1332 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001333 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301334 "device-id": f.deviceHandler.device.Id,
1335 "intf-id": intfID,
1336 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301337
David K. Bainbridge794735f2020-02-11 21:01:37 -08001338 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1339 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301340 return olterrors.NewErrInvalidValue(log.Fields{
1341 "classifier": uplinkClassifier,
1342 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301343 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001344 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301345 log.Fields{
1346 "classifier": *classifierProto,
1347 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001348 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001349 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301350 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301351 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301353 log.Fields{
1354 "action": *actionProto,
1355 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001356 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301357 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301358 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001359 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301360 "action": action,
1361 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001362 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301363 }
1364
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001366 OnuId: int32(onuID),
1367 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001368 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001369 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001370 AllocId: int32(allocID),
1371 NetworkIntfId: int32(networkIntfID),
1372 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301373 Classifier: classifierProto,
1374 Action: actionProto,
1375 Priority: int32(logicalFlow.Priority),
1376 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001377 PortNo: portNo,
Gamze Abaka7650be62021-02-26 10:50:36 +00001378 TechProfileId: flowContext.tpID,
1379 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1380 PbitToGemport: flowContext.pbitToGem,
1381 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001382 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001383 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001384 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001385 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001386 logger.Infow(ctx, "ethType-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301387 log.Fields{
1388 "device-id": f.deviceHandler.device.Id,
1389 "onu-id": onuID,
1390 "intf-id": intfID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001391 "ethType": ethType,
Shrey Baid26912972020-04-16 21:02:31 +05301392 })
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001393 flowInfo := rsrcMgr.FlowInfo{Flow: &upstreamFlow}
1394 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 +05301395 return olterrors.NewErrPersistence("update", "flow", upstreamFlow.FlowId,
1396 log.Fields{
1397 "flow": upstreamFlow,
1398 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301399 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001400 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301401}
1402
David K. Bainbridge794735f2020-02-11 21:01:37 -08001403func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001404 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001405
1406 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1407 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1408 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001409 if vlanID != ReservedVlan {
1410 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001411 classifier.OVid = vid
1412 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301413 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001414 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1415 vid := uint32(metadata)
1416 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001417 classifier.IVid = vid
1418 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301419 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301420 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001421 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301422 classifier.OPbits = vlanPcp
1423 } else {
1424 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301425 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001426 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1427 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1428 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1429 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001430 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001431 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1432 classifier.PktTagType = pktTagType
1433
1434 switch pktTagType {
1435 case SingleTag:
1436 case DoubleTag:
1437 case Untagged:
1438 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001439 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301440 }
1441 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001442 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301443}
1444
Gamze Abaka724d0852020-03-18 12:10:24 +00001445func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001446 var actionCmd openoltpb2.ActionCmd
1447 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301448 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001449 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301450 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001451 if _, ok := actionInfo[VlanPcp]; ok {
1452 action.Cmd.RemarkInnerPbits = true
1453 action.IPbits = actionInfo[VlanPcp].(uint32)
1454 if _, ok := actionInfo[VlanVid]; ok {
1455 action.Cmd.TranslateInnerTag = true
1456 action.IVid = actionInfo[VlanVid].(uint32)
1457 }
1458 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001459 } else if _, ok := actionInfo[PushVlan]; ok {
1460 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301461 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001462 if _, ok := actionInfo[VlanPcp]; ok {
1463 action.OPbits = actionInfo[VlanPcp].(uint32)
1464 action.Cmd.RemarkOuterPbits = true
1465 if _, ok := classifierInfo[VlanVid]; ok {
1466 action.IVid = classifierInfo[VlanVid].(uint32)
1467 action.Cmd.TranslateInnerTag = true
1468 }
1469 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001470 } else if _, ok := actionInfo[TrapToHost]; ok {
1471 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301472 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001473 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301474 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001475 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301476}
1477
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001478// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001479func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
1480 return f.techprofile[intfID].GetTechProfileInstanceKVPath(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301481}
1482
Gamze Abakafee36392019-10-03 11:17:24 +00001483// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001484func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301485 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001486 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1487
Gamze Abakafee36392019-10-03 11:17:24 +00001488 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301489 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001490 _ = olterrors.NewErrAdapter("delete-tech-profile-failed", log.Fields{"device-id": f.deviceHandler.device.Id}, err).Log()
Girish Gowdra54934262019-11-13 14:19:55 +05301491 // return err
1492 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001493 }
Girish Kumara1ea2aa2020-08-19 18:14:22 +00001494 logger.Debugw(ctx, "tech-profile-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001495 }
1496 return nil
1497}
1498
1499// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301500func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001501 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001502 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001503 }
npujarec5762e2020-01-01 14:08:48 +05301504 if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301505 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1506 log.Fields{
1507 "tp-id": tpID,
1508 "uni-port-name": uniPortName,
1509 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001510 }
1511 return nil
1512}
1513
David K. Bainbridge794735f2020-02-11 21:01:37 -08001514func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001515
1516 var intfID uint32
1517 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1518 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1519 */
1520 if deviceFlow.AccessIntfId != -1 {
1521 intfID = uint32(deviceFlow.AccessIntfId)
1522 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001523 // We need to log the valid interface ID.
1524 // 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 +00001525 intfID = uint32(deviceFlow.NetworkIntfId)
1526 }
1527
Neha Sharma96b7bf22020-06-15 10:37:32 +00001528 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301529 "flow": *deviceFlow,
1530 "device-id": f.deviceHandler.device.Id,
1531 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001532 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001533
1534 st, _ := status.FromError(err)
1535 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001536 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001537 "err": err,
1538 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301539 "device-id": f.deviceHandler.device.Id,
1540 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001541 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301542 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001543
1544 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001545 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301546 log.Fields{"err": err,
1547 "device-flow": deviceFlow,
1548 "device-id": f.deviceHandler.device.Id,
1549 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001550 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001551 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001552 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301553 log.Fields{
1554 "flow": *deviceFlow,
1555 "device-id": f.deviceHandler.device.Id,
1556 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001557
1558 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1559 if deviceFlow.AccessIntfId != -1 {
1560 // No need to register the flow if it is a trap on nni flow.
1561 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1562 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1563 return err
1564 }
1565 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001566 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001567}
1568
Neha Sharma96b7bf22020-06-15 10:37:32 +00001569func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1570 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301571 log.Fields{
1572 "flow": *deviceFlow,
1573 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001574 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001575 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001576 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001577 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301578 log.Fields{
1579 "err": err,
1580 "deviceFlow": deviceFlow,
1581 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001582 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001583 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001584 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001585 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001586
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001587 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001588 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001589 "of-flow-id": ofFlowID,
1590 "flow": *deviceFlow,
1591 "device-id": f.deviceHandler.device.Id,
1592 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001593 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301594}
1595
David K. Bainbridge794735f2020-02-11 21:01:37 -08001596func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001597
1598 classifierInfo := make(map[string]interface{})
1599 actionInfo := make(map[string]interface{})
1600
1601 classifierInfo[EthType] = uint32(LldpEthType)
1602 classifierInfo[PacketTagType] = Untagged
1603 actionInfo[TrapToHost] = true
1604
1605 // LLDP flow is installed to trap LLDP packets on the NNI port.
1606 // We manage flow_id resource pool on per PON port basis.
1607 // Since this situation is tricky, as a hack, we pass the NNI port
1608 // index (network_intf_id) as PON port Index for the flow_id resource
1609 // pool. Also, there is no ONU Id available for trapping LLDP packets
1610 // on NNI port, use onu_id as -1 (invalid)
1611 // ****************** CAVEAT *******************
1612 // This logic works if the NNI Port Id falls within the same valid
1613 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1614 // we need to have a re-look at this.
1615 // *********************************************
1616
1617 var onuID = -1
1618 var uniID = -1
1619 var gemPortID = -1
1620
Neha Sharma96b7bf22020-06-15 10:37:32 +00001621 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001622 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301623 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001624 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001625 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001626 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001627 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001628 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001629
David K. Bainbridge794735f2020-02-11 21:01:37 -08001630 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1631 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301632 return olterrors.NewErrInvalidValue(
1633 log.Fields{
1634 "classifier": classifierInfo,
1635 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001636 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001637 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301638 log.Fields{
1639 "classifier": *classifierProto,
1640 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001641 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001642 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301643 return olterrors.NewErrInvalidValue(
1644 log.Fields{
1645 "action": actionInfo,
1646 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001647 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001648 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301649 log.Fields{
1650 "action": *actionProto,
1651 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001652
1653 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1654 OnuId: int32(onuID), // OnuId not required
1655 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001656 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001657 FlowType: Downstream,
1658 NetworkIntfId: int32(networkInterfaceID),
1659 GemportId: int32(gemPortID),
1660 Classifier: classifierProto,
1661 Action: actionProto,
1662 Priority: int32(flow.Priority),
1663 Cookie: flow.Cookie,
1664 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001665 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001666 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301667 log.Fields{
1668 "flow": downstreamflow,
1669 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001670 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001671 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301672 log.Fields{
1673 "device-id": f.deviceHandler.device.Id,
1674 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001675 "flow-id": flow.Id})
1676 flowInfo := rsrcMgr.FlowInfo{Flow: &downstreamflow}
1677 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id, flowInfo); err != nil {
1678 return olterrors.NewErrPersistence("update", "flow", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301679 log.Fields{
1680 "flow": downstreamflow,
1681 "device-id": f.deviceHandler.device.Id}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001682 }
1683 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301684}
1685
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001686func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1687 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001688}
1689
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001690//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001691func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001692 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1693 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1694 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "couldnt-find-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})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001700 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001701 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301702 return nil, olterrors.NewErrNotFound("onu-child-device",
1703 log.Fields{
1704 "onu-id": onuID,
1705 "intf-id": intfID,
1706 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001707 }
1708 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1709 //better to ad the device to cache here.
1710 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1711 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001712 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301713 log.Fields{
1714 "intf-id": intfID,
1715 "onu-id": onuID,
1716 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001717 }
1718
1719 return onuDev.(*OnuDevice), nil
1720}
1721
1722//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001723func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1724 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301725 log.Fields{
1726 "pon-port": intfID,
1727 "onu-id": onuID,
1728 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001729 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001730 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001731 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301732 return nil, olterrors.NewErrNotFound("onu",
1733 log.Fields{
1734 "interface-id": parentPortNo,
1735 "onu-id": onuID,
1736 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001737 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301738 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001739 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301740 log.Fields{
1741 "device-id": f.deviceHandler.device.Id,
1742 "child_device_id": onuDevice.Id,
1743 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301744 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301745}
1746
Neha Sharma96b7bf22020-06-15 10:37:32 +00001747func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1748 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301749 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001750 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301751 log.Fields{
1752 "intf-id": intfID,
1753 "onu-id": onuID,
1754 "uni-id": uniID,
1755 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001756 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301757 }
1758
1759 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001760 logger.Debugw(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301761 log.Fields{
1762 "msg": *delGemPortMsg,
1763 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001764 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301765 delGemPortMsg,
1766 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001767 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001768 onuDev.deviceType,
1769 onuDev.deviceID,
1770 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301771 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1772 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001773 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301774 "to-adapter": onuDev.deviceType,
1775 "onu-id": onuDev.deviceID,
1776 "proxyDeviceID": onuDev.proxyDeviceID,
1777 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301778 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001779 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301780 log.Fields{
1781 "msg": delGemPortMsg,
1782 "from-adapter": f.deviceHandler.device.Type,
1783 "to-adapter": onuDev.deviceType,
1784 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301785 return nil
1786}
1787
Neha Sharma96b7bf22020-06-15 10:37:32 +00001788func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1789 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301790 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001791 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301792 log.Fields{
1793 "intf-id": intfID,
1794 "onu-id": onuID,
1795 "uni-id": uniID,
1796 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001797 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301798 }
1799
1800 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301802 log.Fields{
1803 "msg": *delTcontMsg,
1804 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001805 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301806 delTcontMsg,
1807 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001808 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001809 onuDev.deviceType,
1810 onuDev.deviceID,
1811 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301812 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1813 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001814 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301815 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1816 "proxyDeviceID": onuDev.proxyDeviceID,
1817 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301818 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001819 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301820 log.Fields{
1821 "msg": delTcontMsg,
1822 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301823 return nil
1824}
1825
Girish Gowdrac3037402020-01-22 20:29:53 +05301826// Once the gemport is released for a given onu, it also has to be cleared from local cache
1827// which was used for deriving the gemport->logicalPortNo during packet-in.
1828// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1829// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001830func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001831
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001832 f.onuGemInfoLock.Lock()
1833 defer f.onuGemInfoLock.Unlock()
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001834
Neha Sharma96b7bf22020-06-15 10:37:32 +00001835 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301836 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001837 "gem-port-id": gemPortID,
1838 "intf-id": intfID,
1839 "onu-id": onuID,
1840 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001841 "onu-gem": f.onuGemInfo})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001842
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001843 onugem := f.onuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001844deleteLoop:
serkant.uluderya96af4932020-02-20 16:58:48 -08001845 for i, onu := range onugem {
Girish Gowdrac3037402020-01-22 20:29:53 +05301846 if onu.OnuID == onuID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001847 for j, gem := range onu.GemPorts {
Girish Gowdrac3037402020-01-22 20:29:53 +05301848 // If the gemport is found, delete it from local cache.
1849 if gem == gemPortID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001850 onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
1851 onugem[i] = onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001852 logger.Infow(ctx, "removed-gemport-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301853 log.Fields{
1854 "intf-id": intfID,
1855 "onu-id": onuID,
1856 "deletedgemport-id": gemPortID,
1857 "gemports": onu.GemPorts,
1858 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001859 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301860 }
1861 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001862 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301863 }
1864 }
1865}
1866
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301867//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001868// nolint: gocyclo
Girish Gowdraa482f272021-03-24 23:04:19 -07001869func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, intfID uint32, onuID int32, uniID int32,
Girish Gowdra82c80982021-03-26 16:22:02 -07001870 gemPortID int32, flowID uint64, portNum uint32, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001871
Girish Gowdraa482f272021-03-24 23:04:19 -07001872 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, onuID, uniID)
1873 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001874 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1875 log.Fields{
1876 "tpPath": tpPath,
1877 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -07001878 techprofileInst, err := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, tpID, tpPath)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001879 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1880 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1881 log.Fields{
1882 "tp-id": tpID,
1883 "path": tpPath}, err)
1884 }
1885
1886 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1887
1888 if used {
1889 f.flowsUsedByGemPortKey.Lock()
1890 defer f.flowsUsedByGemPortKey.Unlock()
1891
1892 flowIDs := f.flowsUsedByGemPort[uint32(gemPortID)]
1893 for i, flowIDinMap := range flowIDs {
1894 if flowIDinMap == flowID {
1895 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
1896 // everytime flowsUsedByGemPort cache is updated the same should be updated
1897 // in kv store by calling UpdateFlowIDsForGem
1898 f.flowsUsedByGemPort[uint32(gemPortID)] = flowIDs
Girish Gowdraa482f272021-03-24 23:04:19 -07001899 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, intfID, uint32(gemPortID), flowIDs); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001900 return err
1901 }
1902 break
1903 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001904 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001905 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1906 log.Fields{
1907 "gemport-id": gemPortID,
1908 "usedByFlows": flowIDs,
1909 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -07001910
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001911 return nil
1912 }
1913 logger.Debugf(ctx, "gem-port-id %d is-not-used-by-another-flow--releasing-the-gem-port", gemPortID)
Girish Gowdraa482f272021-03-24 23:04:19 -07001914 f.resourceMgr.RemoveGemPortIDForOnu(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001915 // TODO: The TrafficQueue corresponding to this gem-port also should be removed immediately.
1916 // But it is anyway eventually removed later when the TechProfile is freed, so not a big issue for now.
Girish Gowdraa482f272021-03-24 23:04:19 -07001917 f.resourceMgr.RemoveGEMportPonportToOnuMapOnKVStore(ctx, uint32(gemPortID), intfID)
Esin Karamandf392e12020-12-16 13:33:09 +00001918 // also clear gem to uni cache
1919 f.removeFromGemToUniMap(gemPortKey{
Girish Gowdraa482f272021-03-24 23:04:19 -07001920 intfID: intfID,
Esin Karamandf392e12020-12-16 13:33:09 +00001921 gemPort: uint32(gemPortID),
1922 })
Girish Gowdraa482f272021-03-24 23:04:19 -07001923 f.deleteGemPortFromLocalCache(ctx, intfID, uint32(onuID), uint32(gemPortID))
Esin Karamandf392e12020-12-16 13:33:09 +00001924
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001925 f.onuIdsLock.Lock() // TODO: What is this lock?
1926
1927 //everytime an entry is deleted from flowsUsedByGemPort cache, the same should be updated in kv as well
1928 // by calling DeleteFlowIDsForGem
1929 f.flowsUsedByGemPortKey.Lock()
1930 delete(f.flowsUsedByGemPort, uint32(gemPortID))
1931 f.flowsUsedByGemPortKey.Unlock()
Girish Gowdraa482f272021-03-24 23:04:19 -07001932 f.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, uint32(gemPortID))
1933 f.resourceMgr.FreeGemPortID(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001934
1935 f.onuIdsLock.Unlock()
1936
1937 // Delete the gem port on the ONU.
Girish Gowdraa482f272021-03-24 23:04:19 -07001938 if err := f.sendDeleteGemPortToChild(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001939 logger.Errorw(ctx, "error-processing-delete-gem-port-towards-onu",
1940 log.Fields{
1941 "err": err,
Girish Gowdraa482f272021-03-24 23:04:19 -0700