blob: 4e87682347baf16d1ee58a978712ec40fcfa3c45 [file] [log] [blame]
manikkaraj kbf256be2019-03-25 00:13:48 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
manikkaraj kbf256be2019-03-25 00:13:48 +053019
20import (
21 "context"
Matteo Scandolo6056e822019-11-13 14:05:29 -080022 "encoding/hex"
Girish Gowdracefae192020-03-19 18:14:10 -070023 "errors"
manikkaraj kbf256be2019-03-25 00:13:48 +053024 "fmt"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070025 "github.com/opencord/voltha-lib-go/v4/pkg/flows"
26 "github.com/opencord/voltha-lib-go/v4/pkg/log"
27 tp "github.com/opencord/voltha-lib-go/v4/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080028 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070029 "github.com/opencord/voltha-protos/v4/go/common"
30 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
31 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
32 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
33 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
34 "github.com/opencord/voltha-protos/v4/go/voltha"
Girish Gowdra9602eb42020-09-09 15:50:39 -070035 "strings"
36 "sync"
Chaitrashree G S579fe732019-08-20 20:50:47 -040037
Thomas Lee S94109f12020-03-03 16:39:29 +053038 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000039 "google.golang.org/grpc/codes"
40 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053041)
42
43const (
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070044 //IPProtoDhcp flow category
45 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053046
Girish Gowdraa09aeab2020-09-14 16:30:52 -070047 //IgmpProto proto value
48 IgmpProto = 2
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070049
50 //EapEthType eapethtype value
51 EapEthType = 0x888e
52 //LldpEthType lldp ethtype value
53 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000054 //IPv4EthType IPv4 ethernet type value
55 IPv4EthType = 0x800
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070056
Andrea Campanella7acc0b92020-02-14 09:20:49 +010057 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
58 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040059
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070060 //DefaultMgmtVlan default vlan value
61 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053062
manikkaraj kbf256be2019-03-25 00:13:48 +053063 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070064
David K. Bainbridge82efc492019-09-04 09:57:11 -070065 //Upstream constant
66 Upstream = "upstream"
67 //Downstream constant
68 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000069 //Multicast constant
70 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070071 //PacketTagType constant
72 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070073 //Untagged constant
74 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070075 //SingleTag constant
76 SingleTag = "single_tag"
77 //DoubleTag constant
78 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053079
80 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070081
82 //EthType constant
83 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000084 //EthDst constant
85 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070086 //TPID constant
87 TPID = "tpid"
88 //IPProto constant
89 IPProto = "ip_proto"
90 //InPort constant
91 InPort = "in_port"
92 //VlanVid constant
93 VlanVid = "vlan_vid"
94 //VlanPcp constant
95 VlanPcp = "vlan_pcp"
96
97 //UDPDst constant
98 UDPDst = "udp_dst"
99 //UDPSrc constant
100 UDPSrc = "udp_src"
101 //Ipv4Dst constant
102 Ipv4Dst = "ipv4_dst"
103 //Ipv4Src constant
104 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700105 //Metadata constant
106 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700107 //TunnelID constant
108 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700109 //Output constant
110 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000111 //GroupID constant
112 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 // Actions
114
115 //PopVlan constant
116 PopVlan = "pop_vlan"
117 //PushVlan constant
118 PushVlan = "push_vlan"
119 //TrapToHost constant
120 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400121 //MaxMeterBand constant
122 MaxMeterBand = 2
123 //VlanPCPMask contant
124 VlanPCPMask = 0xFF
125 //VlanvIDMask constant
126 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000127 //IntfID constant
128 IntfID = "intfId"
129 //OnuID constant
130 OnuID = "onuId"
131 //UniID constant
132 UniID = "uniId"
133 //PortNo constant
134 PortNo = "portNo"
135 //AllocID constant
136 AllocID = "allocId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000137
138 //NoneOnuID constant
139 NoneOnuID = -1
140 //NoneUniID constant
141 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700142
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700143 // Max number of flows that can be queued per ONU
144 maxConcurrentFlowsPerOnu = 20
manikkaraj kbf256be2019-03-25 00:13:48 +0530145
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700146 bitMapPrefix = "0b"
147 pbit1 = '1'
148)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400149
Gamze Abakafee36392019-10-03 11:17:24 +0000150type schedQueue struct {
151 direction tp_pb.Direction
152 intfID uint32
153 onuID uint32
154 uniID uint32
155 tpID uint32
156 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700157 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000158 meterID uint32
159 flowMetadata *voltha.FlowMetadata
160}
161
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700162// subscriberDataPathFlowIDKey is key to subscriberDataPathFlowIDMap map
163type subscriberDataPathFlowIDKey struct {
164 intfID uint32
165 onuID uint32
166 uniID uint32
167 direction string
168 tpID uint32
169}
170
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700171// This control block is created per flow add/remove and pushed on the incomingFlows channel slice
172// The flowControlBlock is then picked by the perOnuFlowHandlerRoutine for further processing.
173// There is on perOnuFlowHandlerRoutine routine per ONU that constantly monitors for any incoming
174// flow and processes it serially
175type flowControlBlock struct {
176 ctx context.Context // Flow handler context
177 addFlow bool // if true flow to be added, else removed
178 flow *voltha.OfpFlowStats // Flow message
179 flowMetadata *voltha.FlowMetadata // FlowMetadata that contains flow meter information. This can be nil for Flow remove
180 errChan *chan error // channel to report the Flow handling error
Esin Karamanccb714b2019-11-29 15:02:06 +0000181}
182
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700183//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530184type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700185 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
186 techprofile map[uint32]tp.TechProfileIf
187 deviceHandler *DeviceHandler
188 grpMgr *OpenOltGroupMgr
189 resourceMgr *rsrcMgr.OpenOltResourceMgr
190
191 onuIdsLock sync.RWMutex // TODO: Do we need this?
192
193 flowsUsedByGemPort map[uint32][]uint64 // gem port id to flow ids
194 flowsUsedByGemPortKey sync.RWMutex // lock to be used to access the flowsUsedByGemPort map
195
196 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
197 packetInGemPortLock sync.RWMutex
198
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700199 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700200 onuGemInfo []rsrcMgr.OnuGemInfo //onu, gem and uni info local cache
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700201 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700202 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700203
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700204 // Map of voltha flowID associated with subscriberDataPathFlowIDKey
205 // This information is not persisted on Kv store and hence should be reconciled on adapter restart
206 subscriberDataPathFlowIDMap map[subscriberDataPathFlowIDKey]uint64
207 subscriberDataPathFlowIDMapLock sync.RWMutex
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700208
209 // Slice of channels. Each channel in slice, index by ONU ID, queues flows per ONU.
210 // A go routine per ONU, waits on the unique channel (indexed by ONU ID) for incoming flows (add/remove)
211 incomingFlows []chan flowControlBlock
manikkaraj kbf256be2019-03-25 00:13:48 +0530212}
213
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700214//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700215func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000216 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530217 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530218 var err error
219 var idx uint32
220
manikkaraj kbf256be2019-03-25 00:13:48 +0530221 flowMgr.deviceHandler = dh
Girish Gowdra9602eb42020-09-09 15:50:39 -0700222 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530223 flowMgr.resourceMgr = rMgr
Amit Ghoshd4cbe482019-11-21 12:07:14 +0000224 flowMgr.techprofile = make(map[uint32]tp.TechProfileIf)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000225 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
226 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"error": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530227 return nil
228 }
William Kurkian740a09c2019-10-23 17:07:38 -0400229 flowMgr.onuIdsLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700230 flowMgr.flowsUsedByGemPort = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530231 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700232 flowMgr.packetInGemPortLock = sync.RWMutex{}
Girish Gowdra1183b4d2020-08-25 16:12:01 -0700233 flowMgr.onuGemInfoLock = sync.RWMutex{}
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700234 flowMgr.subscriberDataPathFlowIDMap = make(map[subscriberDataPathFlowIDKey]uint64)
235 flowMgr.subscriberDataPathFlowIDMapLock = sync.RWMutex{}
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700236
237 // Create a slice of buffered channels for handling concurrent flows per ONU.
238 // The additional entry (+1) is to handle the NNI trap flows on a separate channel from individual ONUs channel
239 flowMgr.incomingFlows = make([]chan flowControlBlock, MaxOnusPerPon+1)
240 for i := range flowMgr.incomingFlows {
241 flowMgr.incomingFlows[i] = make(chan flowControlBlock, maxConcurrentFlowsPerOnu)
242 // Spin up a go routine to handling incoming flows (add/remove).
243 // There will be on go routine per ONU.
244 // This routine will be blocked on the flowMgr.incomingFlows[onu-id] channel for incoming flows.
245 go flowMgr.perOnuFlowHandlerRoutine(flowMgr.incomingFlows[i])
246 }
247
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530248 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700249 if flowMgr.onuGemInfo, err = rMgr.GetOnuGemInfo(ctx, ponPortIdx); err != nil {
250 logger.Error(ctx, "failed-to-load-onu-gem-info-cache")
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530251 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700252 //Load flowID list per gem map per interface from the kvstore.
253 flowMgr.loadFlowIDlistForGem(ctx, idx)
Esin Karamanccb714b2019-11-29 15:02:06 +0000254 //load interface to multicast queue map from kv store
Girish Gowdra9602eb42020-09-09 15:50:39 -0700255 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700256 flowMgr.reconcileSubscriberDataPathFlowIDMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000257 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530258 return &flowMgr
259}
260
Kent Hagermane6ff1012020-07-14 15:07:53 -0400261func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700262 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
263 // Flow is not replicated in this case, we need to register the flow for a single gem-port
264 return f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
265 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
266 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
267 for _, gemPort := range deviceFlow.PbitToGemport {
268 if err := f.registerFlowIDForGem(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
269 return err
270 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700271 }
Gamze Abakafee36392019-10-03 11:17:24 +0000272 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700273 return nil
274}
275
276func (f *OpenOltFlowMgr) registerFlowIDForGem(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
277 f.flowsUsedByGemPortKey.Lock()
278 flowIDList, ok := f.flowsUsedByGemPort[gemPortID]
279 if !ok {
280 flowIDList = []uint64{flowFromCore.Id}
281 }
282 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
283 f.flowsUsedByGemPort[gemPortID] = flowIDList
284 f.flowsUsedByGemPortKey.Unlock()
285
286 // update the flowids for a gem to the KVstore
287 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400288}
289
Girish Gowdra9602eb42020-09-09 15:50:39 -0700290func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000291 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200292 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000293 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530294 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700295 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530296
Neha Sharma96b7bf22020-06-15 10:37:32 +0000297 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530298 "device-id": f.deviceHandler.device.Id,
299 "intf-id": intfID,
300 "onu-id": onuID,
301 "uni-id": uniID,
302 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700303 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530304 "action": actionInfo,
305 "usmeter-iD": UsMeterID,
306 "dsmeter-iD": DsMeterID,
307 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400308 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
309 // is because the flow is an NNI flow and there would be no onu resources associated with it
310 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400311 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200312 cause := "no-onu-id-for-flow"
313 fields := log.Fields{
314 "onu": onuID,
315 "port-no": portNo,
316 "classifer": classifierInfo,
317 "action": actionInfo,
318 "device-id": f.deviceHandler.device.Id}
319 logger.Errorw(ctx, cause, fields)
320 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530321 }
322
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700323 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000324 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530325 "uni": uni,
326 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530327
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700328 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
329 "device-id": f.deviceHandler.device.Id,
330 "intf-id": intfID,
331 "onu-id": onuID,
332 "uni-id": uniID,
333 "port-no": portNo,
334 "classifier": classifierInfo,
335 "action": actionInfo,
336 "usmeter-id": UsMeterID,
337 "dsmeter-id": DsMeterID,
338 "tp-id": TpID})
339 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
340 if allocID == 0 || gemPorts == nil || TpInst == nil {
341 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
342 return olterrors.NewErrNotFound(
343 "alloc-id-gem-ports-tp-unavailable",
344 nil, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400345 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700346 args := make(map[string]uint32)
347 args[IntfID] = intfID
348 args[OnuID] = onuID
349 args[UniID] = uniID
350 args[PortNo] = portNo
351 args[AllocID] = allocID
352
353 /* Flows can be added specific to gemport if p-bits are received.
354 * If no pbit mentioned then adding flows for all gemports
355 */
356 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
357
Andrea Campanellabfe08432020-09-11 17:07:03 +0200358 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530359}
360
salmansiddiqui7ac62132019-08-22 03:58:50 +0000361// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530362func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400363
Neha Sharma96b7bf22020-06-15 10:37:32 +0000364 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530365 log.Fields{"dir": sq.direction,
366 "intf-id": sq.intfID,
367 "onu-id": sq.onuID,
368 "uni-id": sq.uniID,
369 "tp-id": sq.tpID,
370 "meter-id": sq.meterID,
371 "tp-inst": sq.tpInst,
372 "flowmetadata": sq.flowMetadata,
373 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400374
Gamze Abakafee36392019-10-03 11:17:24 +0000375 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000376 if err != nil {
377 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400378 }
379
380 /* Lets make a simple assumption that if the meter-id is present on the KV store,
381 * then the scheduler and queues configuration is applied on the OLT device
382 * in the given direction.
383 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000384
Manikkaraj kb1d51442019-07-23 10:41:02 -0400385 var SchedCfg *tp_pb.SchedulerConfig
npujarec5762e2020-01-01 14:08:48 +0530386 KvStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400387 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530388 return olterrors.NewErrNotFound("meter",
389 log.Fields{"intf-id": sq.intfID,
390 "onu-id": sq.onuID,
391 "uni-id": sq.uniID,
392 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400393 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000394
Manikkaraj kb1d51442019-07-23 10:41:02 -0400395 if KvStoreMeter != nil {
Gamze Abakafee36392019-10-03 11:17:24 +0000396 if KvStoreMeter.MeterId == sq.meterID {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000397 logger.Debugw(ctx, "scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400398 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400399 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530400 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800401 "unsupported": "meter-id",
402 "kv-store-meter-id": KvStoreMeter.MeterId,
Shrey Baid26912972020-04-16 21:02:31 +0530403 "meter-id-in-flow": sq.meterID,
404 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400405 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000406
Neha Sharma96b7bf22020-06-15 10:37:32 +0000407 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530408 log.Fields{
409 "meter-id": sq.meterID,
410 "direction": Direction,
411 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000412
Gamze Abakafee36392019-10-03 11:17:24 +0000413 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000414 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Gamze Abakafee36392019-10-03 11:17:24 +0000415 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000416 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400417 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000418
419 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530420 return olterrors.NewErrNotFound("scheduler-config",
421 log.Fields{
422 "intf-id": sq.intfID,
423 "direction": sq.direction,
424 "tp-inst": sq.tpInst,
425 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000426 }
427
Manikkaraj kb1d51442019-07-23 10:41:02 -0400428 var meterConfig *ofp.OfpMeterConfig
Gamze Abakafee36392019-10-03 11:17:24 +0000429 if sq.flowMetadata != nil {
430 for _, meter := range sq.flowMetadata.Meters {
431 if sq.meterID == meter.MeterId {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400432 meterConfig = meter
Neha Sharma96b7bf22020-06-15 10:37:32 +0000433 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Shrey Baid26912972020-04-16 21:02:31 +0530434 log.Fields{"meterConfig": meterConfig,
435 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400436 break
437 }
438 }
439 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000440 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400441 }
442 if meterConfig == nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530443 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800444 "reason": "Could-not-get-meterbands-from-flowMetadata",
445 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530446 "meter-id": sq.meterID,
447 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400448 } else if len(meterConfig.Bands) < MaxMeterBand {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000449 logger.Errorw(ctx, "invalid-number-of-bands-in-meter",
Shrey Baid26912972020-04-16 21:02:31 +0530450 log.Fields{"Bands": meterConfig.Bands,
451 "meter-id": sq.meterID,
452 "device-id": f.deviceHandler.device.Id})
Thomas Lee S94109f12020-03-03 16:39:29 +0530453 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800454 "reason": "Invalid-number-of-bands-in-meter",
455 "meterband-count": len(meterConfig.Bands),
456 "metabands": meterConfig.Bands,
Shrey Baid26912972020-04-16 21:02:31 +0530457 "meter-id": sq.meterID,
458 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400459 }
460 cir := meterConfig.Bands[0].Rate
461 cbs := meterConfig.Bands[0].BurstSize
462 eir := meterConfig.Bands[1].Rate
463 ebs := meterConfig.Bands[1].BurstSize
464 pir := cir + eir
465 pbs := cbs + ebs
466 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
467
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700468 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000469 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400470
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700471 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530472 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
473 log.Fields{"intf-id": sq.intfID,
474 "direction": sq.direction,
475 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400476 }
477
salmansiddiqui7ac62132019-08-22 03:58:50 +0000478 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400479 * store the meter id on the KV store, for further reference.
480 */
npujarec5762e2020-01-01 14:08:48 +0530481 if err := f.resourceMgr.UpdateMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, meterConfig); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530482 return olterrors.NewErrAdapter("failed-updating-meter-id",
483 log.Fields{"onu-id": sq.onuID,
484 "meter-id": sq.meterID,
485 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400486 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000487 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530488 log.Fields{"direction": Direction,
489 "Meter": meterConfig,
490 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400491 return nil
492}
493
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700494func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000495 trafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000496
497 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530498 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
499 log.Fields{"intf-id": sq.intfID,
500 "direction": sq.direction,
501 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000502 }
503
Neha Sharma96b7bf22020-06-15 10:37:32 +0000504 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530505 log.Fields{
506 "direction": sq.direction,
507 "TrafficScheds": TrafficSched,
508 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530509 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Girish Kumar8f73fe02019-12-09 13:19:37 +0000510 IntfId: sq.intfID, OnuId: sq.onuID,
511 UniId: sq.uniID, PortNo: sq.uniPort,
512 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000513 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000514 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000515 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530516 "direction": sq.direction,
517 "traffic-queues": trafficQueues,
518 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000519
520 // On receiving the CreateTrafficQueues request, the driver should create corresponding
521 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000522 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530523 log.Fields{"direction": sq.direction,
524 "traffic-queues": trafficQueues,
525 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530526 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000527 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
528 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000529 TrafficQueues: trafficQueues,
530 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530531 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000532 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000533 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530534 "direction": sq.direction,
535 "traffic-queues": trafficQueues,
536 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000537
Esin Karamanccb714b2019-11-29 15:02:06 +0000538 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000539 multicastTrafficQueues := f.techprofile[sq.intfID].GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile))
Esin Karamanccb714b2019-11-29 15:02:06 +0000540 if len(multicastTrafficQueues) > 0 {
Girish Gowdra9602eb42020-09-09 15:50:39 -0700541 if _, present := f.grpMgr.GetInterfaceToMcastQueueMap(sq.intfID); !present {
Esin Karamanccb714b2019-11-29 15:02:06 +0000542 //assumed that there is only one queue per PON for the multicast service
543 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
544 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000545 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000546 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700547 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000548 gemPortID: multicastQueuePerPonPort.GemportId,
549 servicePriority: multicastQueuePerPonPort.Priority,
550 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700551 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000552 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400553 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
554 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"error": err})
555 return err
556 }
Shrey Baid26912972020-04-16 21:02:31 +0530557
Neha Sharma96b7bf22020-06-15 10:37:32 +0000558 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000559 }
560 }
561 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000562 return nil
563}
564
salmansiddiqui7ac62132019-08-22 03:58:50 +0000565// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530566func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400567
568 var Direction string
569 var SchedCfg *tp_pb.SchedulerConfig
570 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000571 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530572 log.Fields{
573 "direction": sq.direction,
574 "intf-id": sq.intfID,
575 "onu-id": sq.onuID,
576 "uni-id": sq.uniID,
577 "uni-port": sq.uniPort,
578 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000579 if sq.direction == tp_pb.Direction_UPSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000580 SchedCfg, err = f.techprofile[sq.intfID].GetUsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400581 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000582 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000583 SchedCfg, err = f.techprofile[sq.intfID].GetDsScheduler(ctx, sq.tpInst.(*tp.TechProfile))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400584 Direction = "downstream"
585 }
586
Girish Kumar8f73fe02019-12-09 13:19:37 +0000587 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530588 return olterrors.NewErrNotFound("scheduler-config",
589 log.Fields{
590 "int-id": sq.intfID,
591 "direction": sq.direction,
592 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000593 }
594
npujarec5762e2020-01-01 14:08:48 +0530595 KVStoreMeter, err := f.resourceMgr.GetMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400596 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530597 return olterrors.NewErrNotFound("meter",
598 log.Fields{
599 "onu-id": sq.onuID,
600 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400601 }
602 if KVStoreMeter == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000603 logger.Warnw(ctx, "no-meter-installed-yet",
Shrey Baid26912972020-04-16 21:02:31 +0530604 log.Fields{
605 "direction": Direction,
606 "intf-id": sq.intfID,
607 "onu-id": sq.onuID,
608 "uni-id": sq.uniID,
609 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400610 return nil
611 }
612 cir := KVStoreMeter.Bands[0].Rate
613 cbs := KVStoreMeter.Bands[0].BurstSize
614 eir := KVStoreMeter.Bands[1].Rate
615 ebs := KVStoreMeter.Bands[1].BurstSize
616 pir := cir + eir
617 pbs := cbs + ebs
618
619 TrafficShaping := &tp_pb.TrafficShapingInfo{Cir: cir, Cbs: cbs, Pir: pir, Pbs: pbs}
620
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700621 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile[sq.intfID].GetTrafficScheduler(sq.tpInst.(*tp.TechProfile), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000622 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000623
Neha Sharma96b7bf22020-06-15 10:37:32 +0000624 TrafficQueues, err := f.techprofile[sq.intfID].GetTrafficQueues(ctx, sq.tpInst.(*tp.TechProfile), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000625 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530626 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
627 log.Fields{
628 "intf-id": sq.intfID,
629 "direction": sq.direction,
630 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000631 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400632
npujarec5762e2020-01-01 14:08:48 +0530633 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000634 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
635 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000636 TrafficQueues: TrafficQueues,
637 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000638 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530639 log.Fields{
640 "intf-id": sq.intfID,
641 "traffic-queues": TrafficQueues,
642 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400643 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000644 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530645 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
Gamze Abakafee36392019-10-03 11:17:24 +0000646 IntfId: sq.intfID, OnuId: sq.onuID,
647 UniId: sq.uniID, PortNo: sq.uniPort,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400648 TrafficScheds: TrafficSched}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000649 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530650 log.Fields{
651 "intf-id": sq.intfID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700652 "traffic-schedulers": TrafficSched,
653 "onu-id": sq.onuID,
654 "uni-id": sq.uniID,
655 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400656 }
657
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700658 logger.Infow(ctx, "removed-traffic-schedulers-successfully",
659 log.Fields{"device-id": f.deviceHandler.device.Id,
660 "intf-id": sq.intfID,
661 "onu-id": sq.onuID,
662 "uni-id": sq.uniID,
663 "uni-port": sq.uniPort})
salmansiddiqui7ac62132019-08-22 03:58:50 +0000664
665 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400666 * delete the meter id on the KV store.
667 */
npujarec5762e2020-01-01 14:08:48 +0530668 err = f.resourceMgr.RemoveMeterIDForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400669 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530670 return olterrors.NewErrAdapter("unable-to-remove-meter",
671 log.Fields{
672 "onu": sq.onuID,
673 "meter": KVStoreMeter.MeterId,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700674 "device-id": f.deviceHandler.device.Id,
675 "intf-id": sq.intfID,
676 "onu-id": sq.onuID,
677 "uni-id": sq.uniID,
678 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400679 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000680 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530681 log.Fields{
682 "meter-id": KVStoreMeter.MeterId,
683 "dir": Direction,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700684 "device-id": f.deviceHandler.device.Id,
685 "intf-id": sq.intfID,
686 "onu-id": sq.onuID,
687 "uni-id": sq.uniID,
688 "uni-port": sq.uniPort})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400689 return err
690}
691
Gamze Abakafee36392019-10-03 11:17:24 +0000692// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700693func (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 +0000694 var allocIDs []uint32
695 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530696 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530697 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000698 var err error
Gamze Abakafee36392019-10-03 11:17:24 +0000699
npujarec5762e2020-01-01 14:08:48 +0530700 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
701 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000702 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530703
Neha Sharma96b7bf22020-06-15 10:37:32 +0000704 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530705 "intf-id": intfID,
706 "onu-id": onuID,
707 "uni-id": uniID,
708 "device-id": f.deviceHandler.device.Id,
709 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530710
Manikkaraj kb1d51442019-07-23 10:41:02 -0400711 // Check tech profile instance already exists for derived port name
npujarec5762e2020-01-01 14:08:48 +0530712 techProfileInstance, _ := f.techprofile[intfID].GetTPInstanceFromKVStore(ctx, TpID, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000713 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000714 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530715 log.Fields{
716 "path": tpPath,
717 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530718 techProfileInstance, err = f.techprofile[intfID].CreateTechProfInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000719 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530720 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000721 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530722 log.Fields{
723 "error": err,
724 "tp-id": TpID,
725 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000726 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530727 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400728 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
729 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"error": err})
730 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530731 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000732 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530733 log.Fields{
734 "uni": uni,
735 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530736 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530737 }
Gamze Abakafee36392019-10-03 11:17:24 +0000738
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700739 switch tpInst := techProfileInstance.(type) {
740 case *tp.TechProfile:
741 if UsMeterID != 0 {
742 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
743 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
744 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000745 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700746 log.Fields{
747 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700748 "onu-id": onuID,
749 "uni-id": uniID,
750 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700751 "meter-id": UsMeterID,
752 "device-id": f.deviceHandler.device.Id})
753 return 0, nil, nil
754 }
755 }
756 if DsMeterID != 0 {
757 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
758 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
759 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000760 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700761 log.Fields{
762 "error": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700763 "onu-id": onuID,
764 "uni-id": uniID,
765 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700766 "meter-id": DsMeterID,
767 "device-id": f.deviceHandler.device.Id})
768 return 0, nil, nil
769 }
770 }
771 allocID := tpInst.UsScheduler.AllocID
772 for _, gem := range tpInst.UpstreamGemPortAttributeList {
773 gemPortIDs = append(gemPortIDs, gem.GemportID)
774 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700775 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000776
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700777 if tpInstanceExists {
778 return allocID, gemPortIDs, techProfileInstance
779 }
780
781 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700782 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700783 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000784 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700785 log.Fields{
786 "alloc-ids": allocIDs,
787 "gemports": allgemPortIDs,
788 "device-id": f.deviceHandler.device.Id})
789 // Send Tconts and GEM ports to KV store
790 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530791 return allocID, gemPortIDs, techProfileInstance
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700792 case *tp.EponProfile:
793 // CreateSchedulerQueues for EPON needs to be implemented here
794 // when voltha-protos for EPON is completed.
795 allocID := tpInst.AllocID
796 for _, gem := range tpInst.UpstreamQueueAttributeList {
797 gemPortIDs = append(gemPortIDs, gem.GemportID)
798 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700799 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700800
801 if tpInstanceExists {
802 return allocID, gemPortIDs, techProfileInstance
803 }
804
805 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700806 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700807 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000808 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700809 log.Fields{
810 "alloc-ids": allocIDs,
811 "gemports": allgemPortIDs,
812 "device-id": f.deviceHandler.device.Id})
813 // Send Tconts and GEM ports to KV store
814 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
815 return allocID, gemPortIDs, techProfileInstance
816 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000817 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700818 log.Fields{
819 "tpInst": tpInst})
820 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530821 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530822}
823
npujarec5762e2020-01-01 14:08:48 +0530824func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530825
Neha Sharma96b7bf22020-06-15 10:37:32 +0000826 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530827 log.Fields{
828 "intf-id": intfID,
829 "onu-id": onuID,
830 "uni-id": uniID,
831 "alloc-id": allocID,
832 "gemport-ids": gemPortIDs,
833 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530834 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530835 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000836 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 +0530837 }
npujarec5762e2020-01-01 14:08:48 +0530838 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000839 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 +0530840 }
npujarec5762e2020-01-01 14:08:48 +0530841 if err := f.resourceMgr.UpdateGEMportsPonportToOnuMapOnKVStore(ctx, gemPortIDs, intfID, onuID, uniID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000842 logger.Error(ctx, "error-while-uploading-gemtopon-map-to-kv-store", log.Fields{"device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530843 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000844 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 -0400845 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530846 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400847 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530848}
849
Neha Sharma96b7bf22020-06-15 10:37:32 +0000850func (f *OpenOltFlowMgr) populateTechProfilePerPonPort(ctx context.Context) error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000851 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530852 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000853 for _, intfID := range techRange.IntfIds {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700854 f.techprofile[intfID] = f.resourceMgr.ResourceMgrs[intfID].TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400855 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000856 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530857 log.Fields{
858 "intf-id": intfID,
859 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530860 }
861 }
862 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400863 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530864 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530865 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800866 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530867 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
868 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530869 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000870 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530871 log.Fields{
872 "numofTech": tpCount,
873 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
874 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530875 return nil
876}
877
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700878func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530879 portNo uint32, uplinkClassifier map[string]interface{},
880 uplinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700881 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700882 uplinkClassifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000883 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530884 log.Fields{
885 "uplinkClassifier": uplinkClassifier,
886 "uplinkAction": uplinkAction})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700887 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, uplinkClassifier, uplinkAction,
888 Upstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
Manikkaraj k884c1242019-04-11 16:26:42 +0530889 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530890}
891
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700892func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32,
Manikkaraj k884c1242019-04-11 16:26:42 +0530893 portNo uint32, downlinkClassifier map[string]interface{},
894 downlinkAction map[string]interface{}, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700895 allocID uint32, gemportID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700896 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000897 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530898 log.Fields{
899 "downlinkClassifier": downlinkClassifier,
900 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400901 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
902 if vlan, exists := downlinkClassifier[VlanVid]; exists {
903 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700904 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Neha Sharma96b7bf22020-06-15 10:37:32 +0000905 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, intfID, onuID, uniID) {
906 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530907 log.Fields{
908 "flow": logicalFlow,
909 "device-id": f.deviceHandler.device.Id,
910 "onu-id": onuID,
911 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800912 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400913 }
914 }
915 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530916 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400917
Manikkaraj k884c1242019-04-11 16:26:42 +0530918 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700919 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400920 // vlan_vid is a uint32. must be type asserted as such or conversion fails
921 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530922 if ok {
923 downlinkAction[VlanVid] = dlClVid & 0xfff
924 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530925 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530926 "reason": "failed-to-convert-vlanid-classifier",
927 "vlan-id": VlanVid,
928 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530929 }
930
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700931 return f.addSymmetricDataPathFlow(ctx, intfID, onuID, uniID, portNo, downlinkClassifier, downlinkAction,
932 Downstream, logicalFlow, allocID, gemportID, tpID, pbitToGem)
manikkaraj kbf256be2019-03-25 00:13:48 +0530933}
934
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700935func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Manikkaraj k884c1242019-04-11 16:26:42 +0530936 action map[string]interface{}, direction string, logicalFlow *ofp.OfpFlowStats,
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700937 allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
938
939 var inverseDirection string
940 if direction == Upstream {
941 inverseDirection = Downstream
942 } else {
943 inverseDirection = Upstream
944 }
945
Neha Sharma96b7bf22020-06-15 10:37:32 +0000946 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530947 log.Fields{
948 "intf-id": intfID,
949 "onu-id": onuID,
950 "uni-id": uniID,
951 "device-id": f.deviceHandler.device.Id,
952 "classifier": classifier,
953 "action": action,
954 "direction": direction,
955 "alloc-id": allocID,
956 "gemport-id": gemPortID,
957 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700958
959 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +0530961 log.Fields{
962 "device-id": f.deviceHandler.device.Id,
963 "intf-id": intfID,
964 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800965 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530966 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800967 classifierProto, err := makeOpenOltClassifierField(classifier)
968 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530969 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530970 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000971 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530972 log.Fields{
973 "classifier": *classifierProto,
974 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +0000975 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800976 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530977 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530978 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000979 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530980 log.Fields{
981 "action": *actionProto,
982 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +0000983 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530984 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530985 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800986 log.Fields{
987 "classifier": classifier,
988 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +0530989 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800990 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530991 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700992
993 // Get symmetric flowID if it exists
994 // This symmetric flowID will be needed by agent software to use the same device flow-id that was used for the
995 // symmetric flow earlier
996 // symmetric flowID 0 is considered by agent as non-existent symmetric flow
997 keySymm := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: inverseDirection, tpID: tpID}
998 f.subscriberDataPathFlowIDMapLock.RLock()
999 symmFlowID := f.subscriberDataPathFlowIDMap[keySymm]
1000 f.subscriberDataPathFlowIDMapLock.RUnlock()
1001
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001002 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001003 OnuId: int32(onuID),
1004 UniId: int32(uniID),
1005 FlowId: logicalFlow.Id,
1006 FlowType: direction,
1007 AllocId: int32(allocID),
1008 NetworkIntfId: int32(networkIntfID),
1009 GemportId: int32(gemPortID),
1010 Classifier: classifierProto,
1011 Action: actionProto,
1012 Priority: int32(logicalFlow.Priority),
1013 Cookie: logicalFlow.Cookie,
1014 PortNo: portNo,
1015 TechProfileId: tpID,
1016 ReplicateFlow: len(pbitToGem) > 0,
1017 PbitToGemport: pbitToGem,
1018 SymmetricFlowId: symmFlowID,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001019 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001020 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001021 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301022 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001023 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301024 log.Fields{"direction": direction,
1025 "device-id": f.deviceHandler.device.Id,
1026 "flow": flow,
1027 "intf-id": intfID,
1028 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001029 flowInfo := rsrcMgr.FlowInfo{Flow: &flow, IsSymmtricFlow: true}
1030 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, uint32(flow.AccessIntfId), flow.OnuId, flow.UniId, flow.FlowId, flowInfo); err != nil {
1031 return olterrors.NewErrPersistence("update", "flow", logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301032 log.Fields{
1033 "flow": flow,
1034 "device-id": f.deviceHandler.device.Id,
1035 "intf-id": intfID,
1036 "onu-id": onuID}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001037 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001038
1039 // Update the current flowID to the map
1040 keyCurr := subscriberDataPathFlowIDKey{intfID: intfID, onuID: onuID, uniID: uniID, direction: direction, tpID: tpID}
1041 f.subscriberDataPathFlowIDMapLock.Lock()
1042 f.subscriberDataPathFlowIDMap[keyCurr] = logicalFlow.Id
1043 f.subscriberDataPathFlowIDMapLock.Unlock()
1044
David K. Bainbridge794735f2020-02-11 21:01:37 -08001045 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301046}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001047
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001048func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1049 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001050 gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301051
Neha Sharma96b7bf22020-06-15 10:37:32 +00001052 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301053 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301054 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001055 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301056 "action": action,
1057 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001058 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301059 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301060
1061 // Clear the action map
1062 for k := range action {
1063 delete(action, k)
1064 }
1065
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001066 action[TrapToHost] = true
1067 classifier[UDPSrc] = uint32(68)
1068 classifier[UDPDst] = uint32(67)
1069 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301070
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001071 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001072 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301073 log.Fields{
1074 "device-id": f.deviceHandler.device.Id,
1075 "intf-id": intfID,
1076 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301078 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301079
Neha Sharma96b7bf22020-06-15 10:37:32 +00001080 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301081 log.Fields{
1082 "ul_classifier": classifier,
1083 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001084 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301085 "intf-id": intfID,
1086 "onu-id": onuID,
1087 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301088
David K. Bainbridge794735f2020-02-11 21:01:37 -08001089 classifierProto, err := makeOpenOltClassifierField(classifier)
1090 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301091 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301092 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001093 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001094 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001095 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301096 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301097 }
1098
David K. Bainbridge794735f2020-02-11 21:01:37 -08001099 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001100 OnuId: int32(onuID),
1101 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001102 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001103 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001104 AllocId: int32(allocID),
1105 NetworkIntfId: int32(networkIntfID),
1106 GemportId: int32(gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301107 Classifier: classifierProto,
1108 Action: actionProto,
1109 Priority: int32(logicalFlow.Priority),
1110 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001111 PortNo: portNo,
1112 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001113 ReplicateFlow: len(pbitToGem) > 0,
1114 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001115 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001116 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001117 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001118 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001119 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301120 log.Fields{
1121 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001122 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301123 "intf-id": intfID,
1124 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001125 flowInfo := rsrcMgr.FlowInfo{Flow: &dhcpFlow}
1126 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 +05301127 return olterrors.NewErrPersistence("update", "flow", dhcpFlow.FlowId,
1128 log.Fields{
1129 "flow": dhcpFlow,
1130 "device-id": f.deviceHandler.device.Id}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301131 }
1132
David K. Bainbridge794735f2020-02-11 21:01:37 -08001133 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301134}
1135
Esin Karamanae41e2b2019-12-17 18:13:13 +00001136//addIGMPTrapFlow creates IGMP trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301137func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001138 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
1139 return f.addUpstreamTrapFlow(ctx, intfID, onuID, uniID, portNo, classifier, action, logicalFlow, allocID, gemPortID, tpID, pbitToGem)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001140}
1141
1142//addUpstreamTrapFlow creates a trap-to-host flow
npujarec5762e2020-01-01 14:08:48 +05301143func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32, classifier map[string]interface{},
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001144 action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32, gemPortID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Esin Karamanae41e2b2019-12-17 18:13:13 +00001145
Neha Sharma96b7bf22020-06-15 10:37:32 +00001146 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001147 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301148 return olterrors.NewErrNotFound("nni-interface-id",
1149 log.Fields{
1150 "classifier": classifier,
1151 "action": action,
1152 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001153 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001154 }
1155
1156 // Clear the action map
1157 for k := range action {
1158 delete(action, k)
1159 }
1160
1161 action[TrapToHost] = true
1162 classifier[PacketTagType] = SingleTag
1163 delete(classifier, VlanVid)
1164
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001165 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001166 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001167 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001168 }
1169
Neha Sharma96b7bf22020-06-15 10:37:32 +00001170 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301171 log.Fields{
1172 "ul_classifier": classifier,
1173 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001174 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301175 "device-id": f.deviceHandler.device.Id,
1176 "intf-id": intfID,
1177 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001178
David K. Bainbridge794735f2020-02-11 21:01:37 -08001179 classifierProto, err := makeOpenOltClassifierField(classifier)
1180 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301181 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001182 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001183 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301184 log.Fields{
1185 "classifier": *classifierProto,
1186 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001187 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001188 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301189 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001190 }
1191
David K. Bainbridge794735f2020-02-11 21:01:37 -08001192 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001193 OnuId: int32(onuID),
1194 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001195 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001196 FlowType: Upstream,
1197 AllocId: int32(allocID),
1198 NetworkIntfId: int32(networkIntfID),
1199 GemportId: int32(gemPortID),
1200 Classifier: classifierProto,
1201 Action: actionProto,
1202 Priority: int32(logicalFlow.Priority),
1203 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001204 PortNo: portNo,
1205 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001206 ReplicateFlow: len(pbitToGem) > 0,
1207 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001208 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001209
David K. Bainbridge794735f2020-02-11 21:01:37 -08001210 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001211 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 -08001212 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001213
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001214 flowInfo := rsrcMgr.FlowInfo{Flow: &flow}
1215 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 +05301216 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 +00001217 }
1218
David K. Bainbridge794735f2020-02-11 21:01:37 -08001219 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001220}
1221
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001222// Add EAPOL flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001223func (f *OpenOltFlowMgr) addEAPOLFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
1224 classifier map[string]interface{}, action map[string]interface{}, logicalFlow *ofp.OfpFlowStats, allocID uint32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001225 gemPortID uint32, vlanID uint32, tpID uint32, pbitToGem map[uint32]uint32) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001226 logger.Infow(ctx, "adding-eapol-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301227 log.Fields{
1228 "intf-id": intfID,
1229 "onu-id": onuID,
1230 "port-no": portNo,
1231 "alloc-id": allocID,
1232 "gemport-id": gemPortID,
1233 "vlan-id": vlanID,
1234 "flow": logicalFlow})
manikkaraj kbf256be2019-03-25 00:13:48 +05301235
1236 uplinkClassifier := make(map[string]interface{})
1237 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301238
manikkaraj kbf256be2019-03-25 00:13:48 +05301239 // Fill Classfier
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001240 uplinkClassifier[EthType] = uint32(EapEthType)
1241 uplinkClassifier[PacketTagType] = SingleTag
1242 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001243 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301244 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001245 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001246 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001247 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301248 "device-id": f.deviceHandler.device.Id,
1249 "onu-id": onuID,
1250 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001251 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301252 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301253 //Add Uplink EAPOL Flow
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 logger.Debugw(ctx, "creating-ul-eapol-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301255 log.Fields{
1256 "ul_classifier": uplinkClassifier,
1257 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001258 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301259 "device-id": f.deviceHandler.device.Id,
1260 "intf-id": intfID,
1261 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301262
David K. Bainbridge794735f2020-02-11 21:01:37 -08001263 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1264 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301265 return olterrors.NewErrInvalidValue(log.Fields{
1266 "classifier": uplinkClassifier,
1267 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301268 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001269 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301270 log.Fields{
1271 "classifier": *classifierProto,
1272 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001273 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001274 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301275 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301276 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001277 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301278 log.Fields{
1279 "action": *actionProto,
1280 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001281 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301282 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301283 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001284 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301285 "action": action,
1286 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001287 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301288 }
1289
David K. Bainbridge794735f2020-02-11 21:01:37 -08001290 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001291 OnuId: int32(onuID),
1292 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001293 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001294 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001295 AllocId: int32(allocID),
1296 NetworkIntfId: int32(networkIntfID),
1297 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301298 Classifier: classifierProto,
1299 Action: actionProto,
1300 Priority: int32(logicalFlow.Priority),
1301 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001302 PortNo: portNo,
1303 TechProfileId: tpID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001304 ReplicateFlow: len(pbitToGem) > 0,
1305 PbitToGemport: pbitToGem,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001306 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001307 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001308 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001309 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001310 logger.Infow(ctx, "eapol-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301311 log.Fields{
1312 "device-id": f.deviceHandler.device.Id,
1313 "onu-id": onuID,
1314 "intf-id": intfID,
1315 })
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001316 flowInfo := rsrcMgr.FlowInfo{Flow: &upstreamFlow}
1317 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 +05301318 return olterrors.NewErrPersistence("update", "flow", upstreamFlow.FlowId,
1319 log.Fields{
1320 "flow": upstreamFlow,
1321 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301322 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001323 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301324}
1325
David K. Bainbridge794735f2020-02-11 21:01:37 -08001326func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001327 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001328
1329 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1330 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1331 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001332 if vlanID != ReservedVlan {
1333 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001334 classifier.OVid = vid
1335 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301336 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001337 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1338 vid := uint32(metadata)
1339 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001340 classifier.IVid = vid
1341 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301342 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301343 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001344 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301345 classifier.OPbits = vlanPcp
1346 } else {
1347 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301348 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001349 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1350 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1351 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1352 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001353 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001354 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1355 classifier.PktTagType = pktTagType
1356
1357 switch pktTagType {
1358 case SingleTag:
1359 case DoubleTag:
1360 case Untagged:
1361 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001362 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301363 }
1364 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001365 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301366}
1367
Gamze Abaka724d0852020-03-18 12:10:24 +00001368func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001369 var actionCmd openoltpb2.ActionCmd
1370 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301371 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001372 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301373 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001374 if _, ok := actionInfo[VlanPcp]; ok {
1375 action.Cmd.RemarkInnerPbits = true
1376 action.IPbits = actionInfo[VlanPcp].(uint32)
1377 if _, ok := actionInfo[VlanVid]; ok {
1378 action.Cmd.TranslateInnerTag = true
1379 action.IVid = actionInfo[VlanVid].(uint32)
1380 }
1381 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001382 } else if _, ok := actionInfo[PushVlan]; ok {
1383 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301384 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001385 if _, ok := actionInfo[VlanPcp]; ok {
1386 action.OPbits = actionInfo[VlanPcp].(uint32)
1387 action.Cmd.RemarkOuterPbits = true
1388 if _, ok := classifierInfo[VlanVid]; ok {
1389 action.IVid = classifierInfo[VlanVid].(uint32)
1390 action.Cmd.TranslateInnerTag = true
1391 }
1392 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001393 } else if _, ok := actionInfo[TrapToHost]; ok {
1394 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301395 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001396 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301397 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001398 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301399}
1400
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001401// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001402func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
1403 return f.techprofile[intfID].GetTechProfileInstanceKVPath(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301404}
1405
Gamze Abakafee36392019-10-03 11:17:24 +00001406// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001407func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301408 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001409 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1410
Gamze Abakafee36392019-10-03 11:17:24 +00001411 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301412 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Kent Hagermane6ff1012020-07-14 15:07:53 -04001413 _ = olterrors.NewErrAdapter("delete-tech-profile-failed", log.Fields{"device-id": f.deviceHandler.device.Id}, err).Log()
Girish Gowdra54934262019-11-13 14:19:55 +05301414 // return err
1415 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001416 }
Girish Kumara1ea2aa2020-08-19 18:14:22 +00001417 logger.Debugw(ctx, "tech-profile-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001418 }
1419 return nil
1420}
1421
1422// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301423func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001424 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001425 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001426 }
npujarec5762e2020-01-01 14:08:48 +05301427 if err := f.techprofile[intfID].DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301428 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1429 log.Fields{
1430 "tp-id": tpID,
1431 "uni-port-name": uniPortName,
1432 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001433 }
1434 return nil
1435}
1436
David K. Bainbridge794735f2020-02-11 21:01:37 -08001437func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001438
1439 var intfID uint32
1440 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1441 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1442 */
1443 if deviceFlow.AccessIntfId != -1 {
1444 intfID = uint32(deviceFlow.AccessIntfId)
1445 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001446 // We need to log the valid interface ID.
1447 // 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 +00001448 intfID = uint32(deviceFlow.NetworkIntfId)
1449 }
1450
Neha Sharma96b7bf22020-06-15 10:37:32 +00001451 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301452 "flow": *deviceFlow,
1453 "device-id": f.deviceHandler.device.Id,
1454 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001455 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001456
1457 st, _ := status.FromError(err)
1458 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001459 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001460 "err": err,
1461 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301462 "device-id": f.deviceHandler.device.Id,
1463 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001464 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301465 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001466
1467 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001468 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301469 log.Fields{"err": err,
1470 "device-flow": deviceFlow,
1471 "device-id": f.deviceHandler.device.Id,
1472 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001473 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001474 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301476 log.Fields{
1477 "flow": *deviceFlow,
1478 "device-id": f.deviceHandler.device.Id,
1479 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001480
1481 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1482 if deviceFlow.AccessIntfId != -1 {
1483 // No need to register the flow if it is a trap on nni flow.
1484 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1485 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1486 return err
1487 }
1488 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001489 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001490}
1491
Neha Sharma96b7bf22020-06-15 10:37:32 +00001492func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1493 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301494 log.Fields{
1495 "flow": *deviceFlow,
1496 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001497 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001498 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001499 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001500 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301501 log.Fields{
1502 "err": err,
1503 "deviceFlow": deviceFlow,
1504 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001505 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001506 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001507 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001508 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001509
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001510 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001511 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001512 "of-flow-id": ofFlowID,
1513 "flow": *deviceFlow,
1514 "device-id": f.deviceHandler.device.Id,
1515 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001516 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301517}
1518
David K. Bainbridge794735f2020-02-11 21:01:37 -08001519func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001520
1521 classifierInfo := make(map[string]interface{})
1522 actionInfo := make(map[string]interface{})
1523
1524 classifierInfo[EthType] = uint32(LldpEthType)
1525 classifierInfo[PacketTagType] = Untagged
1526 actionInfo[TrapToHost] = true
1527
1528 // LLDP flow is installed to trap LLDP packets on the NNI port.
1529 // We manage flow_id resource pool on per PON port basis.
1530 // Since this situation is tricky, as a hack, we pass the NNI port
1531 // index (network_intf_id) as PON port Index for the flow_id resource
1532 // pool. Also, there is no ONU Id available for trapping LLDP packets
1533 // on NNI port, use onu_id as -1 (invalid)
1534 // ****************** CAVEAT *******************
1535 // This logic works if the NNI Port Id falls within the same valid
1536 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1537 // we need to have a re-look at this.
1538 // *********************************************
1539
1540 var onuID = -1
1541 var uniID = -1
1542 var gemPortID = -1
1543
Neha Sharma96b7bf22020-06-15 10:37:32 +00001544 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001545 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301546 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001547 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001548 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001549 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001550 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001551 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001552
David K. Bainbridge794735f2020-02-11 21:01:37 -08001553 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1554 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301555 return olterrors.NewErrInvalidValue(
1556 log.Fields{
1557 "classifier": classifierInfo,
1558 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001559 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001560 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301561 log.Fields{
1562 "classifier": *classifierProto,
1563 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001564 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001565 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301566 return olterrors.NewErrInvalidValue(
1567 log.Fields{
1568 "action": actionInfo,
1569 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001570 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001571 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301572 log.Fields{
1573 "action": *actionProto,
1574 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001575
1576 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1577 OnuId: int32(onuID), // OnuId not required
1578 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001579 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001580 FlowType: Downstream,
1581 NetworkIntfId: int32(networkInterfaceID),
1582 GemportId: int32(gemPortID),
1583 Classifier: classifierProto,
1584 Action: actionProto,
1585 Priority: int32(flow.Priority),
1586 Cookie: flow.Cookie,
1587 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001588 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001589 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301590 log.Fields{
1591 "flow": downstreamflow,
1592 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001593 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301595 log.Fields{
1596 "device-id": f.deviceHandler.device.Id,
1597 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001598 "flow-id": flow.Id})
1599 flowInfo := rsrcMgr.FlowInfo{Flow: &downstreamflow}
1600 if err := f.resourceMgr.UpdateFlowIDInfo(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id, flowInfo); err != nil {
1601 return olterrors.NewErrPersistence("update", "flow", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301602 log.Fields{
1603 "flow": downstreamflow,
1604 "device-id": f.deviceHandler.device.Id}, err)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001605 }
1606 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301607}
1608
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001609func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1610 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001611}
1612
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001613//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001614func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001615 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1616 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1617 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001618 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301619 log.Fields{
1620 "intf-id": intfID,
1621 "onu-id": onuID,
1622 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001623 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001624 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301625 return nil, olterrors.NewErrNotFound("onu-child-device",
1626 log.Fields{
1627 "onu-id": onuID,
1628 "intf-id": intfID,
1629 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001630 }
1631 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1632 //better to ad the device to cache here.
1633 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1634 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001635 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301636 log.Fields{
1637 "intf-id": intfID,
1638 "onu-id": onuID,
1639 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001640 }
1641
1642 return onuDev.(*OnuDevice), nil
1643}
1644
1645//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001646func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1647 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301648 log.Fields{
1649 "pon-port": intfID,
1650 "onu-id": onuID,
1651 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001652 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001653 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001654 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301655 return nil, olterrors.NewErrNotFound("onu",
1656 log.Fields{
1657 "interface-id": parentPortNo,
1658 "onu-id": onuID,
1659 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001660 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301661 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001662 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301663 log.Fields{
1664 "device-id": f.deviceHandler.device.Id,
1665 "child_device_id": onuDevice.Id,
1666 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301667 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301668}
1669
Neha Sharma96b7bf22020-06-15 10:37:32 +00001670func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1671 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301672 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001673 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301674 log.Fields{
1675 "intf-id": intfID,
1676 "onu-id": onuID,
1677 "uni-id": uniID,
1678 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001679 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301680 }
1681
1682 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpPath: tpPath, GemPortId: gemPortID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001683 logger.Debugw(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301684 log.Fields{
1685 "msg": *delGemPortMsg,
1686 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001687 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301688 delGemPortMsg,
1689 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301690 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001691 onuDev.deviceType,
1692 onuDev.deviceID,
1693 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301694 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1695 log.Fields{
1696 "from-adapter": f.deviceHandler.device.Type,
1697 "to-adapter": onuDev.deviceType,
1698 "onu-id": onuDev.deviceID,
1699 "proxyDeviceID": onuDev.proxyDeviceID,
1700 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301701 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001702 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301703 log.Fields{
1704 "msg": delGemPortMsg,
1705 "from-adapter": f.deviceHandler.device.Type,
1706 "to-adapter": onuDev.deviceType,
1707 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301708 return nil
1709}
1710
Neha Sharma96b7bf22020-06-15 10:37:32 +00001711func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1712 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301713 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301715 log.Fields{
1716 "intf-id": intfID,
1717 "onu-id": onuID,
1718 "uni-id": uniID,
1719 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001720 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301721 }
1722
1723 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpPath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301725 log.Fields{
1726 "msg": *delTcontMsg,
1727 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001728 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301729 delTcontMsg,
1730 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
Thomas Lee S985938d2020-05-04 11:40:41 +05301731 f.deviceHandler.device.Type,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001732 onuDev.deviceType,
1733 onuDev.deviceID,
1734 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301735 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1736 log.Fields{
1737 "from-adapter": f.deviceHandler.device.Type,
1738 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1739 "proxyDeviceID": onuDev.proxyDeviceID,
1740 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301741 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001742 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301743 log.Fields{
1744 "msg": delTcontMsg,
1745 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301746 return nil
1747}
1748
Girish Gowdrac3037402020-01-22 20:29:53 +05301749// Once the gemport is released for a given onu, it also has to be cleared from local cache
1750// which was used for deriving the gemport->logicalPortNo during packet-in.
1751// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1752// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001753func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001754
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001755 f.onuGemInfoLock.Lock()
1756 defer f.onuGemInfoLock.Unlock()
Matteo Scandolo2c0d2742020-06-10 11:28:42 -07001757
Neha Sharma96b7bf22020-06-15 10:37:32 +00001758 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301759 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001760 "gem-port-id": gemPortID,
1761 "intf-id": intfID,
1762 "onu-id": onuID,
1763 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001764 "onu-gem": f.onuGemInfo})
Girish Gowdra9602eb42020-09-09 15:50:39 -07001765
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001766 onugem := f.onuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001767deleteLoop:
serkant.uluderya96af4932020-02-20 16:58:48 -08001768 for i, onu := range onugem {
Girish Gowdrac3037402020-01-22 20:29:53 +05301769 if onu.OnuID == onuID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001770 for j, gem := range onu.GemPorts {
Girish Gowdrac3037402020-01-22 20:29:53 +05301771 // If the gemport is found, delete it from local cache.
1772 if gem == gemPortID {
serkant.uluderya96af4932020-02-20 16:58:48 -08001773 onu.GemPorts = append(onu.GemPorts[:j], onu.GemPorts[j+1:]...)
1774 onugem[i] = onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001775 logger.Infow(ctx, "removed-gemport-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301776 log.Fields{
1777 "intf-id": intfID,
1778 "onu-id": onuID,
1779 "deletedgemport-id": gemPortID,
1780 "gemports": onu.GemPorts,
1781 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001782 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301783 }
1784 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001785 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301786 }
1787 }
1788}
1789
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301790//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001791// nolint: gocyclo
npujarec5762e2020-01-01 14:08:48 +05301792func (f *OpenOltFlowMgr) clearResources(ctx context.Context, flow *ofp.OfpFlowStats, Intf uint32, onuID int32, uniID int32,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001793 gemPortID int32, flowID uint64, portNum uint32) error {
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001794
Neha Sharma96b7bf22020-06-15 10:37:32 +00001795 tpID, err := getTpIDFromFlow(ctx, flow)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001796 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301797 return olterrors.NewErrNotFound("tp-id",
1798 log.Fields{
1799 "flow": flow,
1800 "intf": Intf,
1801 "onu-id": onuID,
1802 "uni-id": uniID,
1803 "device-id": f.deviceHandler.device.Id}, err)
Chaitrashree G S90a17952019-11-14 21:51:21 -05001804 }
Gamze Abakafee36392019-10-03 11:17:24 +00001805
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001806 uni := getUniPortPath(f.deviceHandler.device.Id, Intf, onuID, uniID)
1807 tpPath := f.getTPpath(ctx, Intf, uni, tpID)
1808 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1809 log.Fields{
1810 "tpPath": tpPath,
1811 "device-id": f.deviceHandler.device.Id})
1812 techprofileInst, err := f.techprofile[Intf].GetTPInstanceFromKVStore(ctx, tpID, tpPath)
1813 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1814 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1815 log.Fields{
1816 "tp-id": tpID,
1817 "path": tpPath}, err)
1818 }
1819
1820 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1821
1822 if used {
1823 f.flowsUsedByGemPortKey.Lock()
1824 defer f.flowsUsedByGemPortKey.Unlock()
1825
1826 flowIDs := f.flowsUsedByGemPort[uint32(gemPortID)]
1827 for i, flowIDinMap := range flowIDs {
1828 if flowIDinMap == flowID {
1829 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
1830 // everytime flowsUsedByGemPort cache is updated the same should be updated
1831 // in kv store by calling UpdateFlowIDsForGem
1832 f.flowsUsedByGemPort[uint32(gemPortID)] = flowIDs
1833 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, Intf, uint32(gemPortID), flowIDs); err != nil {
1834 return err
1835 }
1836 break
1837 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001838 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001839 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1840 log.Fields{
1841 "gemport-id": gemPortID,
1842 "usedByFlows": flowIDs,
1843 "device-id": f.deviceHandler.device.Id})
1844 return nil
1845 }
1846 logger.Debugf(ctx, "gem-port-id %d is-not-used-by-another-flow--releasing-the-gem-port", gemPortID)
1847 f.resourceMgr.RemoveGemPortIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1848 // TODO: The TrafficQueue corresponding to this gem-port also should be removed immediately.
1849 // But it is anyway eventually removed later when the TechProfile is freed, so not a big issue for now.
1850 f.resourceMgr.RemoveGEMportPonportToOnuMapOnKVStore(ctx, uint32(gemPortID), Intf)
1851 f.deleteGemPortFromLocalCache(ctx, Intf, uint32(onuID), uint32(gemPortID))
1852 f.onuIdsLock.Lock() // TODO: What is this lock?
1853
1854 //everytime an entry is deleted from flowsUsedByGemPort cache, the same should be updated in kv as well
1855 // by calling DeleteFlowIDsForGem
1856 f.flowsUsedByGemPortKey.Lock()
1857 delete(f.flowsUsedByGemPort, uint32(gemPortID))
1858 f.flowsUsedByGemPortKey.Unlock()
1859 f.resourceMgr.DeleteFlowIDsForGem(ctx, Intf, uint32(gemPortID))
1860 f.resourceMgr.FreeGemPortID(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID))
1861
1862 f.onuIdsLock.Unlock()
1863
1864 // Delete the gem port on the ONU.
1865 if err := f.sendDeleteGemPortToChild(ctx, Intf, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
1866 logger.Errorw(ctx, "error-processing-delete-gem-port-towards-onu",
1867 log.Fields{
1868 "err": err,
1869 "intf": Intf,
1870 "onu-id": onuID,
1871 "uni-id": uniID,
1872 "device-id": f.deviceHandler.device.Id,
1873 "gemport-id": gemPortID})
1874 }
1875 switch techprofileInst := techprofileInst.(type) {
1876 case *tp.TechProfile:
1877 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, Intf, uint32(onuID), uint32(uniID), tpID, techprofileInst, uint32(gemPortID))
1878 if !ok {
1879 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID); err != nil {
1880 logger.Warn(ctx, err)
1881 }
1882 if err := f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID); err != nil {
1883 logger.Warn(ctx, err)
1884 }
1885 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
1886 logger.Warn(ctx, err)
1887 }
1888 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: Intf, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
1889 logger.Warn(ctx, err)
1890 }
1891 f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID)
1892 // Delete the TCONT on the ONU.
1893 if err := f.sendDeleteTcontToChild(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.UsScheduler.AllocID, tpPath); err != nil {
1894 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
1895 log.Fields{
1896 "intf": Intf,
1897 "onu-id": onuID,
1898 "uni-id": uniID,
1899 "device-id": f.deviceHandler.device.Id,
1900 "alloc-id": techprofileInst.UsScheduler.AllocID})
1901 }
1902 }
1903 case *tp.EponProfile:
1904 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, Intf, uint32(onuID), uint32(uniID), tpID); err != nil {
1905 logger.Warn(ctx, err)
1906 }
1907 if err := f.DeleteTechProfileInstance(ctx, Intf, uint32(onuID), uint32(uniID), "", tpID); err != nil {
1908 logger.Warn(ctx, err)
1909 }
1910 f.resourceMgr.FreeAllocID(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.AllocID)
1911 // Delete the TCONT on the ONU.
1912 if err := f.sendDeleteTcontToChild(ctx, Intf, uint32(onuID), uint32(uniID), techprofileInst.AllocID, tpPath); err != nil {
1913 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
Shrey Baid26912972020-04-16 21:02:31 +05301914 log.Fields{
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001915 "intf": Intf,
Shrey Baid26912972020-04-16 21:02:31 +05301916 "onu-id": onuID,
1917 "uni-id": uniID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001918 "device-id": f.deviceHandler.device.Id,
1919 "alloc-id": techprofileInst.AllocID})
Gamze Abakafee36392019-10-03 11:17:24 +00001920 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001921 default:
1922 logger.Errorw(ctx, "error-unknown-tech",
1923 log.Fields{
1924 "techprofileInst": techprofileInst})
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001925 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001926
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301927 return nil
1928}
1929
David K. Bainbridge794735f2020-02-11 21:01:37 -08001930// nolint: gocyclo
Girish Gowdrae8f473b2020-10-16 11:07:21 -07001931func (f *OpenOltFlowMgr) clearFlowFromDeviceAndResourceManager(ctx context.Context, flow *ofp.OfpFlowStats, flowDirection string) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001932 var flowInfo *rsrcMgr.FlowInfo
Neha Sharma96b7bf22020-06-15 10:37:32 +00001933 logger.Infow(ctx, "clear-flow-from-resource-manager",
Shrey Baid26912972020-04-16 21:02:31 +05301934 log.Fields{
1935 "flowDirection": flowDirection,
1936 "flow": *flow,
1937 "device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +00001938
1939 if flowDirection == Multicast {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001940 return f.clearMulticastFlowFromResourceManager(ctx, flow)
Esin Karamanccb714b2019-11-29 15:02:06 +00001941 }
1942
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301943 classifierInfo := make(map[string]interface{})
1944
Neha Sharma96b7bf22020-06-15 10:37:32 +00001945 portNum, Intf, onu, uni, inPort, ethType, err := FlowExtractInfo(ctx, flow, flowDirection)
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301946 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001947 logger.Error(ctx, err)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001948 return err
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301949 }
Girish Gowdra3d633032019-12-10 16:37:05 +05301950
David K. Bainbridge794735f2020-02-11 21:01:37 -08001951 onuID := int32(onu)
1952 uniID := int32(uni)
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301953
1954 for _, field := range flows.GetOfbFields(flow) {
1955 if field.Type == flows.IP_PROTO {
1956 classifierInfo[IPProto] = field.GetIpProto()
Neha Sharma96b7bf22020-06-15 10:37:32 +00001957 logger.Debugw(ctx