blob: 9c1cb09c9a4b98d0f9991785671cf855ba767862 [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 Gowdra8a0bdcd2021-05-13 12:31:04 -070025 "github.com/opencord/voltha-lib-go/v5/pkg/meters"
Gamze Abaka7650be62021-02-26 10:50:36 +000026 "strconv"
serkant.uluderya4aff1862020-09-17 23:35:26 +030027 "strings"
28 "sync"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070029 "time"
serkant.uluderya4aff1862020-09-17 23:35:26 +030030
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070031 "github.com/opencord/voltha-lib-go/v5/pkg/flows"
32 "github.com/opencord/voltha-lib-go/v5/pkg/log"
33 tp "github.com/opencord/voltha-lib-go/v5/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080034 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070035 "github.com/opencord/voltha-protos/v4/go/common"
36 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
37 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
38 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
39 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
40 "github.com/opencord/voltha-protos/v4/go/voltha"
Chaitrashree G S579fe732019-08-20 20:50:47 -040041
Thomas Lee S94109f12020-03-03 16:39:29 +053042 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000043 "google.golang.org/grpc/codes"
44 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053045)
46
47const (
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070048 //IPProtoDhcp flow category
49 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053050
Girish Gowdraa09aeab2020-09-14 16:30:52 -070051 //IgmpProto proto value
52 IgmpProto = 2
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070053
54 //EapEthType eapethtype value
55 EapEthType = 0x888e
56 //LldpEthType lldp ethtype value
57 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000058 //IPv4EthType IPv4 ethernet type value
59 IPv4EthType = 0x800
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -030060 //PPPoEDEthType PPPoE discovery ethernet type value
61 PPPoEDEthType = 0x8863
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070062
Andrea Campanella7acc0b92020-02-14 09:20:49 +010063 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
64 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040065
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070066 //DefaultMgmtVlan default vlan value
67 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053068
manikkaraj kbf256be2019-03-25 00:13:48 +053069 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070070
David K. Bainbridge82efc492019-09-04 09:57:11 -070071 //Upstream constant
72 Upstream = "upstream"
73 //Downstream constant
74 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000075 //Multicast constant
76 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070077 //PacketTagType constant
78 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070079 //Untagged constant
80 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070081 //SingleTag constant
82 SingleTag = "single_tag"
83 //DoubleTag constant
84 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053085
86 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070087
88 //EthType constant
89 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000090 //EthDst constant
91 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070092 //TPID constant
93 TPID = "tpid"
94 //IPProto constant
95 IPProto = "ip_proto"
96 //InPort constant
97 InPort = "in_port"
98 //VlanVid constant
99 VlanVid = "vlan_vid"
100 //VlanPcp constant
101 VlanPcp = "vlan_pcp"
102
103 //UDPDst constant
104 UDPDst = "udp_dst"
105 //UDPSrc constant
106 UDPSrc = "udp_src"
107 //Ipv4Dst constant
108 Ipv4Dst = "ipv4_dst"
109 //Ipv4Src constant
110 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700111 //Metadata constant
112 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700113 //TunnelID constant
114 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700115 //Output constant
116 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000117 //GroupID constant
118 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700119 // Actions
120
121 //PopVlan constant
122 PopVlan = "pop_vlan"
123 //PushVlan constant
124 PushVlan = "push_vlan"
125 //TrapToHost constant
126 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400127 //MaxMeterBand constant
128 MaxMeterBand = 2
129 //VlanPCPMask contant
130 VlanPCPMask = 0xFF
131 //VlanvIDMask constant
132 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000133 //IntfID constant
134 IntfID = "intfId"
135 //OnuID constant
136 OnuID = "onuId"
137 //UniID constant
138 UniID = "uniId"
139 //PortNo constant
140 PortNo = "portNo"
141 //AllocID constant
142 AllocID = "allocId"
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000143 //GemID constant
144 GemID = "gemId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000145
146 //NoneOnuID constant
147 NoneOnuID = -1
148 //NoneUniID constant
149 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700150
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700151 // Max number of flows that can be queued per ONU
152 maxConcurrentFlowsPerOnu = 20
manikkaraj kbf256be2019-03-25 00:13:48 +0530153
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700154 bitMapPrefix = "0b"
155 pbit1 = '1'
156)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400157
Gamze Abakafee36392019-10-03 11:17:24 +0000158type schedQueue struct {
159 direction tp_pb.Direction
160 intfID uint32
161 onuID uint32
162 uniID uint32
163 tpID uint32
164 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700165 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000166 meterID uint32
167 flowMetadata *voltha.FlowMetadata
168}
169
Gamze Abaka7650be62021-02-26 10:50:36 +0000170type flowContext struct {
171 intfID uint32
172 onuID uint32
173 uniID uint32
174 portNo uint32
175 classifier map[string]interface{}
176 action map[string]interface{}
177 logicalFlow *ofp.OfpFlowStats
178 allocID uint32
179 gemPortID uint32
180 tpID uint32
181 pbitToGem map[uint32]uint32
182 gemToAes map[uint32]bool
183}
184
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700185// This control block is created per flow add/remove and pushed on the incomingFlows channel slice
186// The flowControlBlock is then picked by the perOnuFlowHandlerRoutine for further processing.
187// There is on perOnuFlowHandlerRoutine routine per ONU that constantly monitors for any incoming
188// flow and processes it serially
189type flowControlBlock struct {
190 ctx context.Context // Flow handler context
191 addFlow bool // if true flow to be added, else removed
192 flow *voltha.OfpFlowStats // Flow message
193 flowMetadata *voltha.FlowMetadata // FlowMetadata that contains flow meter information. This can be nil for Flow remove
194 errChan *chan error // channel to report the Flow handling error
Esin Karamanccb714b2019-11-29 15:02:06 +0000195}
196
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700197//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530198type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700199 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700200 techprofile tp.TechProfileIf
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700201 deviceHandler *DeviceHandler
202 grpMgr *OpenOltGroupMgr
203 resourceMgr *rsrcMgr.OpenOltResourceMgr
204
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700205 gemToFlowIDs map[uint32][]uint64 // gem port id to flow ids
206 gemToFlowIDsKey sync.RWMutex // lock to be used to access the gemToFlowIDs map
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700207
208 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
209 packetInGemPortLock sync.RWMutex
210
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700211 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700212 onuGemInfoMap map[uint32]*rsrcMgr.OnuGemInfo //onu, gem and uni info local cache -> map of onuID to OnuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700213 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700214 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700215
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700216 flowIDToGems map[uint64][]uint32
217 flowIDToGemsLock sync.RWMutex
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700218
219 // Slice of channels. Each channel in slice, index by ONU ID, queues flows per ONU.
220 // A go routine per ONU, waits on the unique channel (indexed by ONU ID) for incoming flows (add/remove)
221 incomingFlows []chan flowControlBlock
manikkaraj kbf256be2019-03-25 00:13:48 +0530222}
223
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700224//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700225func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000226 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530227 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530228 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530229
manikkaraj kbf256be2019-03-25 00:13:48 +0530230 flowMgr.deviceHandler = dh
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700231 flowMgr.ponPortIdx = ponPortIdx
Girish Gowdra9602eb42020-09-09 15:50:39 -0700232 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530233 flowMgr.resourceMgr = rMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000234 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700235 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"err": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530236 return nil
237 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700238 flowMgr.gemToFlowIDs = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530239 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700240 flowMgr.flowIDToGems = make(map[uint64][]uint32)
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700241
242 // Create a slice of buffered channels for handling concurrent flows per ONU.
243 // The additional entry (+1) is to handle the NNI trap flows on a separate channel from individual ONUs channel
244 flowMgr.incomingFlows = make([]chan flowControlBlock, MaxOnusPerPon+1)
245 for i := range flowMgr.incomingFlows {
246 flowMgr.incomingFlows[i] = make(chan flowControlBlock, maxConcurrentFlowsPerOnu)
247 // Spin up a go routine to handling incoming flows (add/remove).
248 // There will be on go routine per ONU.
249 // This routine will be blocked on the flowMgr.incomingFlows[onu-id] channel for incoming flows.
250 go flowMgr.perOnuFlowHandlerRoutine(flowMgr.incomingFlows[i])
251 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700252 flowMgr.onuGemInfoMap = make(map[uint32]*rsrcMgr.OnuGemInfo)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530253 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700254 onuIDStart := flowMgr.deviceHandler.deviceInfo.OnuIdStart
255 onuIDEnd := flowMgr.deviceHandler.deviceInfo.OnuIdEnd
256 for onuID := onuIDStart; onuID <= onuIDEnd; onuID++ {
257 // check for a valid serial number in onuGem as GetOnuGemInfo can return nil error in case of nothing found in the path.
258 onugem, err := rMgr.GetOnuGemInfo(ctx, onuID, ponPortIdx)
259 if err == nil && onugem != nil && onugem.SerialNumber != "" {
260 flowMgr.onuGemInfoMap[onuID] = onugem
261 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530262 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700263
264 //Load flowID list per gem map And gemIDs per flow per interface from the kvstore.
265 flowMgr.loadFlowIDsForGemAndGemIDsForFlow(ctx)
266
Esin Karamanccb714b2019-11-29 15:02:06 +0000267 //load interface to multicast queue map from kv store
Girish Gowdra9602eb42020-09-09 15:50:39 -0700268 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000269 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530270 return &flowMgr
271}
272
Kent Hagermane6ff1012020-07-14 15:07:53 -0400273func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700274 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
275 // Flow is not replicated in this case, we need to register the flow for a single gem-port
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700276 return f.registerFlowIDForGemAndGemIDForFlow(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700277 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
278 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
279 for _, gemPort := range deviceFlow.PbitToGemport {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700280 if err := f.registerFlowIDForGemAndGemIDForFlow(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700281 return err
282 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700283 }
Gamze Abakafee36392019-10-03 11:17:24 +0000284 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700285 return nil
286}
287
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700288func (f *OpenOltFlowMgr) registerFlowIDForGemAndGemIDForFlow(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
289 // update gem->flows map
290 f.gemToFlowIDsKey.Lock()
291 flowIDList, ok := f.gemToFlowIDs[gemPortID]
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700292 if !ok {
293 flowIDList = []uint64{flowFromCore.Id}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700294 } else {
295 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700296 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700297 f.gemToFlowIDs[gemPortID] = flowIDList
298 f.gemToFlowIDsKey.Unlock()
299
300 // update flow->gems map
301 f.flowIDToGemsLock.Lock()
302 if _, ok := f.flowIDToGems[flowFromCore.Id]; !ok {
303 f.flowIDToGems[flowFromCore.Id] = []uint32{gemPortID}
304 } else {
305 f.flowIDToGems[flowFromCore.Id] = appendUnique32bit(f.flowIDToGems[flowFromCore.Id], gemPortID)
306 }
307 f.flowIDToGemsLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700308
309 // update the flowids for a gem to the KVstore
310 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400311}
312
Girish Gowdra9602eb42020-09-09 15:50:39 -0700313func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000314 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200315 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000316 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530317 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700318 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530319
Neha Sharma96b7bf22020-06-15 10:37:32 +0000320 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530321 "device-id": f.deviceHandler.device.Id,
322 "intf-id": intfID,
323 "onu-id": onuID,
324 "uni-id": uniID,
325 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700326 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530327 "action": actionInfo,
328 "usmeter-iD": UsMeterID,
329 "dsmeter-iD": DsMeterID,
330 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400331 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
332 // is because the flow is an NNI flow and there would be no onu resources associated with it
333 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400334 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200335 cause := "no-onu-id-for-flow"
336 fields := log.Fields{
337 "onu": onuID,
338 "port-no": portNo,
339 "classifer": classifierInfo,
340 "action": actionInfo,
341 "device-id": f.deviceHandler.device.Id}
342 logger.Errorw(ctx, cause, fields)
343 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530344 }
345
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700346 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000347 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530348 "uni": uni,
349 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530350
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700351 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
352 "device-id": f.deviceHandler.device.Id,
353 "intf-id": intfID,
354 "onu-id": onuID,
355 "uni-id": uniID,
356 "port-no": portNo,
357 "classifier": classifierInfo,
358 "action": actionInfo,
359 "usmeter-id": UsMeterID,
360 "dsmeter-id": DsMeterID,
361 "tp-id": TpID})
362 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
363 if allocID == 0 || gemPorts == nil || TpInst == nil {
364 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
365 return olterrors.NewErrNotFound(
366 "alloc-id-gem-ports-tp-unavailable",
367 nil, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400368 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700369 args := make(map[string]uint32)
370 args[IntfID] = intfID
371 args[OnuID] = onuID
372 args[UniID] = uniID
373 args[PortNo] = portNo
374 args[AllocID] = allocID
375
376 /* Flows can be added specific to gemport if p-bits are received.
377 * If no pbit mentioned then adding flows for all gemports
378 */
379 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
380
Andrea Campanellabfe08432020-09-11 17:07:03 +0200381 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530382}
383
salmansiddiqui7ac62132019-08-22 03:58:50 +0000384// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530385func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400386
Neha Sharma96b7bf22020-06-15 10:37:32 +0000387 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530388 log.Fields{"dir": sq.direction,
389 "intf-id": sq.intfID,
390 "onu-id": sq.onuID,
391 "uni-id": sq.uniID,
392 "tp-id": sq.tpID,
393 "meter-id": sq.meterID,
394 "tp-inst": sq.tpInst,
395 "flowmetadata": sq.flowMetadata,
396 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400397
Gamze Abakafee36392019-10-03 11:17:24 +0000398 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000399 if err != nil {
400 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400401 }
402
403 /* Lets make a simple assumption that if the meter-id is present on the KV store,
404 * then the scheduler and queues configuration is applied on the OLT device
405 * in the given direction.
406 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000407
Manikkaraj kb1d51442019-07-23 10:41:02 -0400408 var SchedCfg *tp_pb.SchedulerConfig
Girish Gowdraa482f272021-03-24 23:04:19 -0700409 meterInfo, err := f.resourceMgr.GetMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400410 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530411 return olterrors.NewErrNotFound("meter",
412 log.Fields{"intf-id": sq.intfID,
413 "onu-id": sq.onuID,
414 "uni-id": sq.uniID,
415 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400416 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000417
Girish Gowdraa482f272021-03-24 23:04:19 -0700418 if meterInfo != nil {
419 logger.Debugw(ctx, "scheduler-already-created-for-upstream", log.Fields{"device-id": f.deviceHandler.device.Id, "meter-id": sq.meterID})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700420 if meterInfo.MeterID == sq.meterID {
Girish Gowdraa482f272021-03-24 23:04:19 -0700421 if err := f.resourceMgr.HandleMeterInfoRefCntUpdate(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, true); err != nil {
422 return err
423 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400424 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400425 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530426 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800427 "unsupported": "meter-id",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700428 "kv-store-meter-id": meterInfo.MeterID,
Shrey Baid26912972020-04-16 21:02:31 +0530429 "meter-id-in-flow": sq.meterID,
430 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400431 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000432
Neha Sharma96b7bf22020-06-15 10:37:32 +0000433 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530434 log.Fields{
435 "meter-id": sq.meterID,
436 "direction": Direction,
437 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000438
Gamze Abakafee36392019-10-03 11:17:24 +0000439 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700440 SchedCfg = f.techprofile.GetUsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Gamze Abakafee36392019-10-03 11:17:24 +0000441 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700442 SchedCfg = f.techprofile.GetDsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Girish Kumar8f73fe02019-12-09 13:19:37 +0000443 }
444
Girish Gowdraa482f272021-03-24 23:04:19 -0700445 found := false
446 meterInfo = &rsrcMgr.MeterInfo{}
Gamze Abakafee36392019-10-03 11:17:24 +0000447 if sq.flowMetadata != nil {
448 for _, meter := range sq.flowMetadata.Meters {
449 if sq.meterID == meter.MeterId {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700450 meterInfo.MeterID = meter.MeterId
Girish Gowdraa482f272021-03-24 23:04:19 -0700451 meterInfo.RefCnt = 1 // initialize it to 1, since this is the first flow that referenced the meter id.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000452 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700453 log.Fields{"meter": meter,
Shrey Baid26912972020-04-16 21:02:31 +0530454 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -0700455 found = true
Manikkaraj kb1d51442019-07-23 10:41:02 -0400456 break
457 }
458 }
459 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000460 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400461 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700462 if !found {
Thomas Lee S94109f12020-03-03 16:39:29 +0530463 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800464 "reason": "Could-not-get-meterbands-from-flowMetadata",
465 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530466 "meter-id": sq.meterID,
467 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400468 }
Gamze Abaka01174422021-03-10 06:55:27 +0000469
470 var TrafficShaping *tp_pb.TrafficShapingInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700471 if TrafficShaping, err = meters.GetTrafficShapingInfo(ctx, sq.flowMetadata.Meters[0]); err != nil {
Gamze Abaka01174422021-03-10 06:55:27 +0000472 return olterrors.NewErrInvalidValue(log.Fields{
473 "reason": "invalid-meter-config",
474 "meter-id": sq.meterID,
475 "device-id": f.deviceHandler.device.Id}, nil)
476 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400477
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700478 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile.GetTrafficScheduler(sq.tpInst.(*tp_pb.TechProfileInstance), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000479 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400480
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700481 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530482 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
483 log.Fields{"intf-id": sq.intfID,
484 "direction": sq.direction,
485 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400486 }
487
salmansiddiqui7ac62132019-08-22 03:58:50 +0000488 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400489 * store the meter id on the KV store, for further reference.
490 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700491 if err := f.resourceMgr.StoreMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, meterInfo); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530492 return olterrors.NewErrAdapter("failed-updating-meter-id",
493 log.Fields{"onu-id": sq.onuID,
494 "meter-id": sq.meterID,
495 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400496 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000497 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530498 log.Fields{"direction": Direction,
Girish Gowdraa482f272021-03-24 23:04:19 -0700499 "meter-info": meterInfo,
500 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400501 return nil
502}
503
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700504func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700505 trafficQueues, err := f.techprofile.GetTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000506
507 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530508 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
509 log.Fields{"intf-id": sq.intfID,
510 "direction": sq.direction,
511 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000512 }
513
Gamze Abakacb0e6772021-06-10 08:32:12 +0000514 if allocExists := f.isAllocUsedByAnotherUNI(ctx, sq); !allocExists {
515 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
516 log.Fields{
517 "direction": sq.direction,
518 "TrafficScheds": TrafficSched,
519 "device-id": f.deviceHandler.device.Id,
520 "intfID": sq.intfID,
521 "onuID": sq.onuID,
522 "uniID": sq.uniID})
523 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
524 IntfId: sq.intfID, OnuId: sq.onuID,
525 UniId: sq.uniID, PortNo: sq.uniPort,
526 TrafficScheds: TrafficSched}); err != nil {
527 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
528 }
529 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
530 "direction": sq.direction,
531 "traffic-queues": trafficQueues,
532 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000533 }
534
535 // On receiving the CreateTrafficQueues request, the driver should create corresponding
536 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000537 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530538 log.Fields{"direction": sq.direction,
539 "traffic-queues": trafficQueues,
540 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530541 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000542 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
543 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000544 TrafficQueues: trafficQueues,
545 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530546 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000547 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000548 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530549 "direction": sq.direction,
550 "traffic-queues": trafficQueues,
551 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000552
Esin Karamanccb714b2019-11-29 15:02:06 +0000553 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700554 multicastTrafficQueues := f.techprofile.GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance))
Esin Karamanccb714b2019-11-29 15:02:06 +0000555 if len(multicastTrafficQueues) > 0 {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700556 if _, present := f.grpMgr.GetInterfaceToMcastQueueMap(sq.intfID); !present { //assumed that there is only one queue per PON for the multicast service
Esin Karamanccb714b2019-11-29 15:02:06 +0000557 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
558 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000559 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000560 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700561 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000562 gemPortID: multicastQueuePerPonPort.GemportId,
563 servicePriority: multicastQueuePerPonPort.Priority,
564 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700565 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000566 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400567 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700568 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -0400569 return err
570 }
Shrey Baid26912972020-04-16 21:02:31 +0530571
Neha Sharma96b7bf22020-06-15 10:37:32 +0000572 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000573 }
574 }
575 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000576 return nil
577}
578
salmansiddiqui7ac62132019-08-22 03:58:50 +0000579// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530580func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400581
582 var Direction string
583 var SchedCfg *tp_pb.SchedulerConfig
584 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000585 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530586 log.Fields{
587 "direction": sq.direction,
588 "intf-id": sq.intfID,
589 "onu-id": sq.onuID,
590 "uni-id": sq.uniID,
591 "uni-port": sq.uniPort,
592 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000593 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700594 SchedCfg = f.techprofile.GetUsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400595 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000596 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700597 SchedCfg = f.techprofile.GetDsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400598 Direction = "downstream"
599 }
600
Girish Gowdraa482f272021-03-24 23:04:19 -0700601 TrafficShaping := &tp_pb.TrafficShapingInfo{} // this info is not really useful for the agent during flow removal. Just use default values.
Manikkaraj kb1d51442019-07-23 10:41:02 -0400602
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700603 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile.GetTrafficScheduler(sq.tpInst.(*tp_pb.TechProfileInstance), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000604 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000605
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700606 TrafficQueues, err := f.techprofile.GetTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000607 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530608 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
609 log.Fields{
610 "intf-id": sq.intfID,
611 "direction": sq.direction,
612 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000613 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400614
npujarec5762e2020-01-01 14:08:48 +0530615 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000616 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
617 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000618 TrafficQueues: TrafficQueues,
619 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000620 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530621 log.Fields{
622 "intf-id": sq.intfID,
623 "traffic-queues": TrafficQueues,
624 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400625 }
Gamze Abakacb0e6772021-06-10 08:32:12 +0000626 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id, "trafficQueues": TrafficQueues})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400627
Gamze Abakacb0e6772021-06-10 08:32:12 +0000628 if allocExists := f.isAllocUsedByAnotherUNI(ctx, sq); !allocExists {
629 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
630 IntfId: sq.intfID, OnuId: sq.onuID,
631 UniId: sq.uniID, PortNo: sq.uniPort,
632 TrafficScheds: TrafficSched}); err != nil {
633 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
634 log.Fields{
635 "intf-id": sq.intfID,
636 "traffic-schedulers": TrafficSched,
637 "onu-id": sq.onuID,
638 "uni-id": sq.uniID,
639 "uni-port": sq.uniPort}, err)
640 }
641
642 logger.Infow(ctx, "removed-traffic-schedulers-successfully",
643 log.Fields{"device-id": f.deviceHandler.device.Id,
644 "intf-id": sq.intfID,
645 "onu-id": sq.onuID,
646 "uni-id": sq.uniID,
647 "uni-port": sq.uniPort})
648
649 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700650 allocID := sq.tpInst.(*tp_pb.TechProfileInstance).UsScheduler.AllocId
Gamze Abakacb0e6772021-06-10 08:32:12 +0000651 f.resourceMgr.FreeAllocID(ctx, sq.intfID, sq.onuID, sq.uniID, allocID)
652 // Delete the TCONT on the ONU.
653 uni := getUniPortPath(f.deviceHandler.device.Id, sq.intfID, int32(sq.onuID), int32(sq.uniID))
654 tpPath := f.getTPpath(ctx, sq.intfID, uni, sq.tpID)
655 if err := f.sendDeleteTcontToChild(ctx, sq.intfID, sq.onuID, sq.uniID, allocID, tpPath); err != nil {
656 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
657 log.Fields{
658 "intf": sq.intfID,
659 "onu-id": sq.onuID,
660 "uni-id": sq.uniID,
661 "device-id": f.deviceHandler.device.Id,
662 "alloc-id": allocID})
663 }
664 }
665 }
salmansiddiqui7ac62132019-08-22 03:58:50 +0000666
667 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400668 * delete the meter id on the KV store.
669 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700670 err = f.resourceMgr.RemoveMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400671 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530672 return olterrors.NewErrAdapter("unable-to-remove-meter",
673 log.Fields{
674 "onu": sq.onuID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700675 "device-id": f.deviceHandler.device.Id,
676 "intf-id": sq.intfID,
677 "onu-id": sq.onuID,
678 "uni-id": sq.uniID,
679 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400680 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000681 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530682 log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530683 "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
npujarec5762e2020-01-01 14:08:48 +0530699 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
700 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000701 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530702
Neha Sharma96b7bf22020-06-15 10:37:32 +0000703 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530704 "intf-id": intfID,
705 "onu-id": onuID,
706 "uni-id": uniID,
707 "device-id": f.deviceHandler.device.Id,
708 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530709
Manikkaraj kb1d51442019-07-23 10:41:02 -0400710 // Check tech profile instance already exists for derived port name
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700711 techProfileInstance, _ := f.techprofile.GetTPInstance(ctx, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000712 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000713 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530714 log.Fields{
715 "path": tpPath,
716 "device-id": f.deviceHandler.device.Id})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700717 techProfileInstance, err = f.techprofile.CreateTechProfileInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000718 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530719 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000720 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530721 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700722 "err": err,
Shrey Baid26912972020-04-16 21:02:31 +0530723 "tp-id": TpID,
724 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000725 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530726 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400727 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700728 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -0400729 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530730 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000731 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530732 log.Fields{
733 "uni": uni,
734 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530735 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530736 }
Gamze Abakafee36392019-10-03 11:17:24 +0000737
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700738 switch tpInst := techProfileInstance.(type) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700739 case *tp_pb.TechProfileInstance:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700740 if UsMeterID != 0 {
741 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
742 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
743 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000744 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700745 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700746 "err": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700747 "onu-id": onuID,
748 "uni-id": uniID,
749 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700750 "meter-id": UsMeterID,
751 "device-id": f.deviceHandler.device.Id})
752 return 0, nil, nil
753 }
754 }
755 if DsMeterID != 0 {
756 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
757 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
758 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000759 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700760 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700761 "err": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700762 "onu-id": onuID,
763 "uni-id": uniID,
764 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700765 "meter-id": DsMeterID,
766 "device-id": f.deviceHandler.device.Id})
767 return 0, nil, nil
768 }
769 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700770 allocID := tpInst.UsScheduler.AllocId
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700771 for _, gem := range tpInst.UpstreamGemPortAttributeList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700772 gemPortIDs = append(gemPortIDs, gem.GemportId)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700773 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700774 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000775
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700776 if tpInstanceExists {
777 return allocID, gemPortIDs, techProfileInstance
778 }
779
780 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700781 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700782 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000783 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700784 log.Fields{
Matteo Scandolo84585372021-03-18 14:21:22 -0700785 "intf-id": intfID,
786 "onu-id": onuID,
787 "uni-id": uniID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700788 "alloc-ids": allocIDs,
789 "gemports": allgemPortIDs,
790 "device-id": f.deviceHandler.device.Id})
791 // Send Tconts and GEM ports to KV store
792 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530793 return allocID, gemPortIDs, techProfileInstance
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700794 case *openoltpb2.EponTechProfileInstance:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700795 // CreateSchedulerQueues for EPON needs to be implemented here
796 // when voltha-protos for EPON is completed.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700797 allocID := tpInst.AllocId
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700798 for _, gem := range tpInst.UpstreamQueueAttributeList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700799 gemPortIDs = append(gemPortIDs, gem.GemportId)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700800 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700801 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700802
803 if tpInstanceExists {
804 return allocID, gemPortIDs, techProfileInstance
805 }
806
807 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700808 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700809 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700811 log.Fields{
812 "alloc-ids": allocIDs,
813 "gemports": allgemPortIDs,
814 "device-id": f.deviceHandler.device.Id})
815 // Send Tconts and GEM ports to KV store
816 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
817 return allocID, gemPortIDs, techProfileInstance
818 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000819 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700820 log.Fields{
821 "tpInst": tpInst})
822 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530823 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530824}
825
npujarec5762e2020-01-01 14:08:48 +0530826func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530827
Neha Sharma96b7bf22020-06-15 10:37:32 +0000828 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530829 log.Fields{
830 "intf-id": intfID,
831 "onu-id": onuID,
832 "uni-id": uniID,
833 "alloc-id": allocID,
834 "gemport-ids": gemPortIDs,
835 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530836 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530837 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000838 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 +0530839 }
npujarec5762e2020-01-01 14:08:48 +0530840 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000841 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 +0530842 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700843
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 Gowdra8a0bdcd2021-05-13 12:31:04 -0700854 f.techprofile = f.resourceMgr.PonRsrMgr.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
Gamze Abaka7650be62021-02-26 10:50:36 +0000878func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
879 flowContext.classifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000880 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530881 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000882 "uplinkClassifier": flowContext.classifier,
883 "uplinkAction": flowContext.action})
884 return f.addSymmetricDataPathFlow(ctx, flowContext, Upstream)
Manikkaraj k884c1242019-04-11 16:26:42 +0530885 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530886}
887
Gamze Abaka7650be62021-02-26 10:50:36 +0000888func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
889 downlinkClassifier := flowContext.classifier
890 downlinkAction := flowContext.action
891
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700892 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000893 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530894 log.Fields{
895 "downlinkClassifier": downlinkClassifier,
896 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400897 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
898 if vlan, exists := downlinkClassifier[VlanVid]; exists {
899 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700900 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Gamze Abaka7650be62021-02-26 10:50:36 +0000901 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, flowContext.intfID, flowContext.onuID, flowContext.uniID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000902 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530903 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000904 "flow": flowContext.logicalFlow,
Shrey Baid26912972020-04-16 21:02:31 +0530905 "device-id": f.deviceHandler.device.Id,
Gamze Abaka7650be62021-02-26 10:50:36 +0000906 "onu-id": flowContext.onuID,
907 "intf-id": flowContext.intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800908 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400909 }
910 }
911 }
Manikkaraj k884c1242019-04-11 16:26:42 +0530912 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400913
Manikkaraj k884c1242019-04-11 16:26:42 +0530914 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700915 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -0400916 // vlan_vid is a uint32. must be type asserted as such or conversion fails
917 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +0530918 if ok {
919 downlinkAction[VlanVid] = dlClVid & 0xfff
920 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +0530921 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530922 "reason": "failed-to-convert-vlanid-classifier",
923 "vlan-id": VlanVid,
924 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +0530925 }
926
Gamze Abaka7650be62021-02-26 10:50:36 +0000927 return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
manikkaraj kbf256be2019-03-25 00:13:48 +0530928}
929
Gamze Abaka7650be62021-02-26 10:50:36 +0000930func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, flowContext *flowContext, direction string) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700931
Gamze Abaka7650be62021-02-26 10:50:36 +0000932 intfID := flowContext.intfID
933 onuID := flowContext.onuID
934 uniID := flowContext.uniID
935 classifier := flowContext.classifier
936 action := flowContext.action
937 allocID := flowContext.allocID
938 gemPortID := flowContext.gemPortID
939 tpID := flowContext.tpID
940 logicalFlow := flowContext.logicalFlow
Neha Sharma96b7bf22020-06-15 10:37:32 +0000941 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530942 log.Fields{
943 "intf-id": intfID,
944 "onu-id": onuID,
945 "uni-id": uniID,
946 "device-id": f.deviceHandler.device.Id,
947 "classifier": classifier,
948 "action": action,
949 "direction": direction,
950 "alloc-id": allocID,
951 "gemport-id": gemPortID,
952 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700953
954 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000955 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +0530956 log.Fields{
957 "device-id": f.deviceHandler.device.Id,
958 "intf-id": intfID,
959 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800960 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530961 }
David K. Bainbridge794735f2020-02-11 21:01:37 -0800962 classifierProto, err := makeOpenOltClassifierField(classifier)
963 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530964 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530965 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530967 log.Fields{
968 "classifier": *classifierProto,
969 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +0000970 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -0800971 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530972 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +0530973 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000974 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +0530975 log.Fields{
976 "action": *actionProto,
977 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +0000978 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530979 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +0530980 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800981 log.Fields{
982 "classifier": classifier,
983 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +0530984 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -0800985 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530986 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700987
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700988 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700989 OnuId: int32(onuID),
990 UniId: int32(uniID),
991 FlowId: logicalFlow.Id,
992 FlowType: direction,
993 AllocId: int32(allocID),
994 NetworkIntfId: int32(networkIntfID),
995 GemportId: int32(gemPortID),
996 Classifier: classifierProto,
997 Action: actionProto,
998 Priority: int32(logicalFlow.Priority),
999 Cookie: logicalFlow.Cookie,
1000 PortNo: flowContext.portNo,
1001 TechProfileId: tpID,
1002 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1003 PbitToGemport: flowContext.pbitToGem,
1004 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001005 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001006 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001007 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301008 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001009 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301010 log.Fields{"direction": direction,
1011 "device-id": f.deviceHandler.device.Id,
1012 "flow": flow,
1013 "intf-id": intfID,
1014 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001015
David K. Bainbridge794735f2020-02-11 21:01:37 -08001016 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301017}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001018
Gamze Abaka7650be62021-02-26 10:50:36 +00001019func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1020
1021 intfID := flowContext.intfID
1022 onuID := flowContext.onuID
1023 uniID := flowContext.uniID
1024 logicalFlow := flowContext.logicalFlow
1025 classifier := flowContext.classifier
1026 action := flowContext.action
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301027
Neha Sharma96b7bf22020-06-15 10:37:32 +00001028 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301029 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301030 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001031 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301032 "action": action,
1033 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001034 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301035 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301036
1037 // Clear the action map
1038 for k := range action {
1039 delete(action, k)
1040 }
1041
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001042 action[TrapToHost] = true
1043 classifier[UDPSrc] = uint32(68)
1044 classifier[UDPDst] = uint32(67)
1045 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301046
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001047 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001048 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301049 log.Fields{
1050 "device-id": f.deviceHandler.device.Id,
1051 "intf-id": intfID,
1052 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001053 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301054 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301055
Neha Sharma96b7bf22020-06-15 10:37:32 +00001056 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301057 log.Fields{
1058 "ul_classifier": classifier,
1059 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001060 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301061 "intf-id": intfID,
1062 "onu-id": onuID,
1063 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301064
David K. Bainbridge794735f2020-02-11 21:01:37 -08001065 classifierProto, err := makeOpenOltClassifierField(classifier)
1066 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301067 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301068 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001069 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001070 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001071 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301072 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301073 }
1074
David K. Bainbridge794735f2020-02-11 21:01:37 -08001075 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001076 OnuId: int32(onuID),
1077 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001078 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001079 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001080 AllocId: int32(flowContext.allocID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001081 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001082 GemportId: int32(flowContext.gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301083 Classifier: classifierProto,
1084 Action: actionProto,
1085 Priority: int32(logicalFlow.Priority),
1086 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001087 PortNo: flowContext.portNo,
1088 TechProfileId: flowContext.tpID,
1089 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1090 PbitToGemport: flowContext.pbitToGem,
1091 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001092 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001093 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001094 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001095 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001096 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301097 log.Fields{
1098 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001099 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301100 "intf-id": intfID,
1101 "onu-id": onuID})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301102
David K. Bainbridge794735f2020-02-11 21:01:37 -08001103 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301104}
1105
Esin Karamanae41e2b2019-12-17 18:13:13 +00001106//addIGMPTrapFlow creates IGMP trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001107func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1108 delete(flowContext.classifier, VlanVid)
1109 return f.addUpstreamTrapFlow(ctx, flowContext)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001110}
1111
1112//addUpstreamTrapFlow creates a trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001113func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, flowContext *flowContext) error {
1114
1115 intfID := flowContext.intfID
1116 onuID := flowContext.onuID
1117 uniID := flowContext.uniID
1118 logicalFlow := flowContext.logicalFlow
1119 classifier := flowContext.classifier
1120 action := flowContext.action
Esin Karamanae41e2b2019-12-17 18:13:13 +00001121
Neha Sharma96b7bf22020-06-15 10:37:32 +00001122 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001123 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301124 return olterrors.NewErrNotFound("nni-interface-id",
1125 log.Fields{
1126 "classifier": classifier,
1127 "action": action,
1128 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001129 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001130 }
1131
1132 // Clear the action map
1133 for k := range action {
1134 delete(action, k)
1135 }
1136
1137 action[TrapToHost] = true
1138 classifier[PacketTagType] = SingleTag
Esin Karamanae41e2b2019-12-17 18:13:13 +00001139
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001140 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001141 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001142 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001143 }
1144
Neha Sharma96b7bf22020-06-15 10:37:32 +00001145 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301146 log.Fields{
1147 "ul_classifier": classifier,
1148 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001149 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301150 "device-id": f.deviceHandler.device.Id,
1151 "intf-id": intfID,
1152 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001153
David K. Bainbridge794735f2020-02-11 21:01:37 -08001154 classifierProto, err := makeOpenOltClassifierField(classifier)
1155 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301156 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001157 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001158 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301159 log.Fields{
1160 "classifier": *classifierProto,
1161 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001162 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001163 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301164 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001165 }
1166
David K. Bainbridge794735f2020-02-11 21:01:37 -08001167 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001168 OnuId: int32(onuID),
1169 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001170 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001171 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001172 AllocId: int32(flowContext.allocID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001173 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001174 GemportId: int32(flowContext.gemPortID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001175 Classifier: classifierProto,
1176 Action: actionProto,
1177 Priority: int32(logicalFlow.Priority),
1178 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001179 PortNo: flowContext.portNo,
1180 TechProfileId: flowContext.tpID,
1181 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1182 PbitToGemport: flowContext.pbitToGem,
1183 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001184 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001185
David K. Bainbridge794735f2020-02-11 21:01:37 -08001186 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001187 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 -08001188 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001189
David K. Bainbridge794735f2020-02-11 21:01:37 -08001190 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001191}
1192
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001193// Add EthType flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka7650be62021-02-26 10:50:36 +00001194func (f *OpenOltFlowMgr) addEthTypeBasedFlow(ctx context.Context, flowContext *flowContext, vlanID uint32, ethType uint32) error {
1195 intfID := flowContext.intfID
1196 onuID := flowContext.onuID
1197 uniID := flowContext.uniID
1198 portNo := flowContext.portNo
1199 allocID := flowContext.allocID
1200 gemPortID := flowContext.gemPortID
1201 logicalFlow := flowContext.logicalFlow
1202 classifier := flowContext.classifier
1203 action := flowContext.action
1204
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001205 logger.Infow(ctx, "adding-ethType-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301206 log.Fields{
1207 "intf-id": intfID,
1208 "onu-id": onuID,
1209 "port-no": portNo,
1210 "alloc-id": allocID,
1211 "gemport-id": gemPortID,
1212 "vlan-id": vlanID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001213 "flow": logicalFlow,
1214 "ethType": ethType})
manikkaraj kbf256be2019-03-25 00:13:48 +05301215
1216 uplinkClassifier := make(map[string]interface{})
1217 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301218
manikkaraj kbf256be2019-03-25 00:13:48 +05301219 // Fill Classfier
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001220 uplinkClassifier[EthType] = ethType
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001221 uplinkClassifier[PacketTagType] = SingleTag
1222 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001223 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301224 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001225 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001226 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001227 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301228 "device-id": f.deviceHandler.device.Id,
1229 "onu-id": onuID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001230 "intf-id": intfID,
1231 "ethType": ethType})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001232 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301233 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001234 //Add Uplink EthType Flow
1235 logger.Debugw(ctx, "creating-ul-ethType-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301236 log.Fields{
1237 "ul_classifier": uplinkClassifier,
1238 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001239 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301240 "device-id": f.deviceHandler.device.Id,
1241 "intf-id": intfID,
1242 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301243
David K. Bainbridge794735f2020-02-11 21:01:37 -08001244 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1245 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301246 return olterrors.NewErrInvalidValue(log.Fields{
1247 "classifier": uplinkClassifier,
1248 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301249 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001250 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301251 log.Fields{
1252 "classifier": *classifierProto,
1253 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001254 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001255 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301256 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301257 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001258 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301259 log.Fields{
1260 "action": *actionProto,
1261 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001262 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301263 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301264 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001265 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301266 "action": action,
1267 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001268 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301269 }
1270
David K. Bainbridge794735f2020-02-11 21:01:37 -08001271 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001272 OnuId: int32(onuID),
1273 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001274 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001275 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001276 AllocId: int32(allocID),
1277 NetworkIntfId: int32(networkIntfID),
1278 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301279 Classifier: classifierProto,
1280 Action: actionProto,
1281 Priority: int32(logicalFlow.Priority),
1282 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001283 PortNo: portNo,
Gamze Abaka7650be62021-02-26 10:50:36 +00001284 TechProfileId: flowContext.tpID,
1285 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1286 PbitToGemport: flowContext.pbitToGem,
1287 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001288 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001289 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001290 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001291 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001292 logger.Infow(ctx, "ethType-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301293 log.Fields{
1294 "device-id": f.deviceHandler.device.Id,
1295 "onu-id": onuID,
1296 "intf-id": intfID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001297 "ethType": ethType,
Shrey Baid26912972020-04-16 21:02:31 +05301298 })
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001299
David K. Bainbridge794735f2020-02-11 21:01:37 -08001300 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301301}
1302
David K. Bainbridge794735f2020-02-11 21:01:37 -08001303func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001304 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001305
1306 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1307 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1308 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001309 if vlanID != ReservedVlan {
1310 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001311 classifier.OVid = vid
1312 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301313 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001314 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1315 vid := uint32(metadata)
1316 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001317 classifier.IVid = vid
1318 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301319 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301320 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001321 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301322 classifier.OPbits = vlanPcp
1323 } else {
1324 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301325 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001326 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1327 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1328 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1329 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001330 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001331 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1332 classifier.PktTagType = pktTagType
1333
1334 switch pktTagType {
1335 case SingleTag:
1336 case DoubleTag:
1337 case Untagged:
1338 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001339 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301340 }
1341 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001342 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301343}
1344
Gamze Abaka724d0852020-03-18 12:10:24 +00001345func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001346 var actionCmd openoltpb2.ActionCmd
1347 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301348 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001349 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301350 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001351 if _, ok := actionInfo[VlanPcp]; ok {
1352 action.Cmd.RemarkInnerPbits = true
1353 action.IPbits = actionInfo[VlanPcp].(uint32)
1354 if _, ok := actionInfo[VlanVid]; ok {
1355 action.Cmd.TranslateInnerTag = true
1356 action.IVid = actionInfo[VlanVid].(uint32)
1357 }
1358 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001359 } else if _, ok := actionInfo[PushVlan]; ok {
1360 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301361 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001362 if _, ok := actionInfo[VlanPcp]; ok {
1363 action.OPbits = actionInfo[VlanPcp].(uint32)
1364 action.Cmd.RemarkOuterPbits = true
1365 if _, ok := classifierInfo[VlanVid]; ok {
1366 action.IVid = classifierInfo[VlanVid].(uint32)
1367 action.Cmd.TranslateInnerTag = true
1368 }
1369 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001370 } else if _, ok := actionInfo[TrapToHost]; ok {
1371 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301372 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001373 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301374 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001375 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301376}
1377
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001378// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001379func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001380 return f.techprofile.GetTechProfileInstanceKey(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301381}
1382
Gamze Abakafee36392019-10-03 11:17:24 +00001383// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001384func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301385 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001386 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1387
Gamze Abakafee36392019-10-03 11:17:24 +00001388 for _, tpID := range tpIDList {
npujarec5762e2020-01-01 14:08:48 +05301389 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001390 logger.Errorw(ctx, "delete-tech-profile-failed", log.Fields{"err": err, "device-id": f.deviceHandler.device.Id})
Girish Gowdra54934262019-11-13 14:19:55 +05301391 // return err
1392 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001393 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001394 logger.Debugw(ctx, "tech-profile-instance-deleted", log.Fields{"device-id": f.deviceHandler.device.Id, "uniPortName": uniPortName, "tp-id": tpID})
Gamze Abakafee36392019-10-03 11:17:24 +00001395 }
1396 return nil
1397}
1398
1399// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301400func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001401 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001402 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001403 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001404 if err := f.techprofile.DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301405 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1406 log.Fields{
1407 "tp-id": tpID,
1408 "uni-port-name": uniPortName,
1409 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001410 }
1411 return nil
1412}
1413
David K. Bainbridge794735f2020-02-11 21:01:37 -08001414func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001415
1416 var intfID uint32
1417 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1418 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1419 */
1420 if deviceFlow.AccessIntfId != -1 {
1421 intfID = uint32(deviceFlow.AccessIntfId)
1422 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001423 // We need to log the valid interface ID.
1424 // 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 +00001425 intfID = uint32(deviceFlow.NetworkIntfId)
1426 }
1427
Neha Sharma96b7bf22020-06-15 10:37:32 +00001428 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301429 "flow": *deviceFlow,
1430 "device-id": f.deviceHandler.device.Id,
1431 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001432 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001433
1434 st, _ := status.FromError(err)
1435 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001436 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001437 "err": err,
1438 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301439 "device-id": f.deviceHandler.device.Id,
1440 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001441 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301442 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001443
1444 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001445 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301446 log.Fields{"err": err,
1447 "device-flow": deviceFlow,
1448 "device-id": f.deviceHandler.device.Id,
1449 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001450 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001451 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001452 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301453 log.Fields{
1454 "flow": *deviceFlow,
1455 "device-id": f.deviceHandler.device.Id,
1456 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001457
1458 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1459 if deviceFlow.AccessIntfId != -1 {
1460 // No need to register the flow if it is a trap on nni flow.
1461 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1462 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1463 return err
1464 }
1465 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001466 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001467}
1468
Neha Sharma96b7bf22020-06-15 10:37:32 +00001469func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1470 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301471 log.Fields{
1472 "flow": *deviceFlow,
1473 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001474 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001475 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001476 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001477 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301478 log.Fields{
1479 "err": err,
1480 "deviceFlow": deviceFlow,
1481 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001482 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001483 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001484 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001485 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001486
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001487 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001488 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001489 "of-flow-id": ofFlowID,
1490 "flow": *deviceFlow,
1491 "device-id": f.deviceHandler.device.Id,
1492 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001493 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301494}
1495
David K. Bainbridge794735f2020-02-11 21:01:37 -08001496func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001497
1498 classifierInfo := make(map[string]interface{})
1499 actionInfo := make(map[string]interface{})
1500
1501 classifierInfo[EthType] = uint32(LldpEthType)
1502 classifierInfo[PacketTagType] = Untagged
1503 actionInfo[TrapToHost] = true
1504
1505 // LLDP flow is installed to trap LLDP packets on the NNI port.
1506 // We manage flow_id resource pool on per PON port basis.
1507 // Since this situation is tricky, as a hack, we pass the NNI port
1508 // index (network_intf_id) as PON port Index for the flow_id resource
1509 // pool. Also, there is no ONU Id available for trapping LLDP packets
1510 // on NNI port, use onu_id as -1 (invalid)
1511 // ****************** CAVEAT *******************
1512 // This logic works if the NNI Port Id falls within the same valid
1513 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1514 // we need to have a re-look at this.
1515 // *********************************************
1516
1517 var onuID = -1
1518 var uniID = -1
1519 var gemPortID = -1
1520
Neha Sharma96b7bf22020-06-15 10:37:32 +00001521 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001522 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301523 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001524 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001525 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001526 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001527 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001528 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001529
David K. Bainbridge794735f2020-02-11 21:01:37 -08001530 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1531 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301532 return olterrors.NewErrInvalidValue(
1533 log.Fields{
1534 "classifier": classifierInfo,
1535 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001536 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001537 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301538 log.Fields{
1539 "classifier": *classifierProto,
1540 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001541 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001542 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301543 return olterrors.NewErrInvalidValue(
1544 log.Fields{
1545 "action": actionInfo,
1546 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001547 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001548 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301549 log.Fields{
1550 "action": *actionProto,
1551 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001552
1553 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1554 OnuId: int32(onuID), // OnuId not required
1555 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001556 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001557 FlowType: Downstream,
1558 NetworkIntfId: int32(networkInterfaceID),
1559 GemportId: int32(gemPortID),
1560 Classifier: classifierProto,
1561 Action: actionProto,
1562 Priority: int32(flow.Priority),
1563 Cookie: flow.Cookie,
1564 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001565 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001566 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301567 log.Fields{
1568 "flow": downstreamflow,
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.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301572 log.Fields{
1573 "device-id": f.deviceHandler.device.Id,
1574 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001575 "flow-id": flow.Id})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001576
David K. Bainbridge794735f2020-02-11 21:01:37 -08001577 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301578}
1579
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001580func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1581 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001582}
1583
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001584//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001585func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001586 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1587 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1588 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001589 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301590 log.Fields{
1591 "intf-id": intfID,
1592 "onu-id": onuID,
1593 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001595 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301596 return nil, olterrors.NewErrNotFound("onu-child-device",
1597 log.Fields{
1598 "onu-id": onuID,
1599 "intf-id": intfID,
1600 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001601 }
1602 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1603 //better to ad the device to cache here.
1604 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1605 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001606 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301607 log.Fields{
1608 "intf-id": intfID,
1609 "onu-id": onuID,
1610 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001611 }
1612
1613 return onuDev.(*OnuDevice), nil
1614}
1615
1616//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001617func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1618 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301619 log.Fields{
1620 "pon-port": intfID,
1621 "onu-id": onuID,
1622 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001623 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001624 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001625 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301626 return nil, olterrors.NewErrNotFound("onu",
1627 log.Fields{
1628 "interface-id": parentPortNo,
1629 "onu-id": onuID,
1630 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001631 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301632 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001633 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301634 log.Fields{
1635 "device-id": f.deviceHandler.device.Id,
1636 "child_device_id": onuDevice.Id,
1637 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301638 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301639}
1640
Neha Sharma96b7bf22020-06-15 10:37:32 +00001641func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1642 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301643 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001644 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301645 log.Fields{
1646 "intf-id": intfID,
1647 "onu-id": onuID,
1648 "uni-id": uniID,
1649 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001650 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301651 }
1652
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001653 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpInstancePath: tpPath, GemPortId: gemPortID}
1654 logger.Infow(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301655 log.Fields{
1656 "msg": *delGemPortMsg,
1657 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001658 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301659 delGemPortMsg,
1660 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001661 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001662 onuDev.deviceType,
1663 onuDev.deviceID,
1664 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301665 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1666 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001667 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301668 "to-adapter": onuDev.deviceType,
1669 "onu-id": onuDev.deviceID,
1670 "proxyDeviceID": onuDev.proxyDeviceID,
1671 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301672 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001673 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301674 log.Fields{
1675 "msg": delGemPortMsg,
1676 "from-adapter": f.deviceHandler.device.Type,
1677 "to-adapter": onuDev.deviceType,
1678 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301679 return nil
1680}
1681
Neha Sharma96b7bf22020-06-15 10:37:32 +00001682func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1683 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301684 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001685 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301686 log.Fields{
1687 "intf-id": intfID,
1688 "onu-id": onuID,
1689 "uni-id": uniID,
1690 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001691 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301692 }
1693
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001694 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpInstancePath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001695 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301696 log.Fields{
1697 "msg": *delTcontMsg,
1698 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001699 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301700 delTcontMsg,
1701 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001702 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001703 onuDev.deviceType,
1704 onuDev.deviceID,
1705 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301706 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1707 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001708 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301709 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1710 "proxyDeviceID": onuDev.proxyDeviceID,
1711 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301712 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301714 log.Fields{
1715 "msg": delTcontMsg,
1716 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301717 return nil
1718}
1719
Girish Gowdrac3037402020-01-22 20:29:53 +05301720// Once the gemport is released for a given onu, it also has to be cleared from local cache
1721// which was used for deriving the gemport->logicalPortNo during packet-in.
1722// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1723// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001724func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301726 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001727 "gem-port-id": gemPortID,
1728 "intf-id": intfID,
1729 "onu-id": onuID,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001730 "device-id": f.deviceHandler.device.Id})
1731 f.onuGemInfoLock.RLock()
1732 onugem, ok := f.onuGemInfoMap[onuID]
1733 f.onuGemInfoLock.RUnlock()
1734 if !ok {
1735 logger.Warnw(ctx, "onu gem info already cleared from cache", log.Fields{
1736 "gem-port-id": gemPortID,
1737 "intf-id": intfID,
1738 "onu-id": onuID,
1739 "device-id": f.deviceHandler.device.Id})
1740 return
1741 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001742deleteLoop:
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001743 for j, gem := range onugem.GemPorts {
1744 // If the gemport is found, delete it from local cache.
1745 if gem == gemPortID {
1746 onugem.GemPorts = append(onugem.GemPorts[:j], onugem.GemPorts[j+1:]...)
1747 f.onuGemInfoLock.Lock()
1748 f.onuGemInfoMap[onuID] = onugem
1749 f.onuGemInfoLock.Unlock()
1750 logger.Infow(ctx, "removed-gemport-from-local-cache",
1751 log.Fields{
1752 "intf-id": intfID,
1753 "onu-id": onuID,
1754 "deletedgemport-id": gemPortID,
1755 "gemports": onugem.GemPorts,
1756 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001757 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301758 }
1759 }
1760}
1761
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301762//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001763// nolint: gocyclo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001764func (f *OpenOltFlowMgr) clearResources(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdra82c80982021-03-26 16:22:02 -07001765 gemPortID int32, flowID uint64, portNum uint32, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001766
Girish Gowdraa482f272021-03-24 23:04:19 -07001767 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, onuID, uniID)
1768 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001769 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1770 log.Fields{
1771 "tpPath": tpPath,
1772 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001773
1774 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1775
1776 if used {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001777 f.gemToFlowIDsKey.RLock()
1778 flowIDs := f.gemToFlowIDs[uint32(gemPortID)]
1779 f.gemToFlowIDsKey.RUnlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001780
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001781 for i, flowIDinMap := range flowIDs {
1782 if flowIDinMap == flowID {
1783 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001784 f.gemToFlowIDsKey.Lock()
1785 f.gemToFlowIDs[uint32(gemPortID)] = flowIDs
1786 f.gemToFlowIDsKey.Unlock()
1787 // everytime gemToFlowIDs cache is updated the same should be updated
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001788 // in kv store by calling UpdateFlowIDsForGem
Girish Gowdraa482f272021-03-24 23:04:19 -07001789 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, intfID, uint32(gemPortID), flowIDs); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001790 return err
1791 }
1792 break
1793 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001794 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001795 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1796 log.Fields{
1797 "gemport-id": gemPortID,
1798 "usedByFlows": flowIDs,
1799 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -07001800
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001801 return nil
1802 }
1803 logger.Debugf(ctx, "gem-port-id %d is-not-used-by-another-flow--releasing-the-gem-port", gemPortID)
Girish Gowdraa482f272021-03-24 23:04:19 -07001804 f.deleteGemPortFromLocalCache(ctx, intfID, uint32(onuID), uint32(gemPortID))
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001805 _ = f.resourceMgr.RemoveGemFromOnuGemInfo(ctx, intfID, uint32(onuID), uint32(gemPortID)) // ignore error and proceed.
1806 //everytime an entry is deleted from gemToFlowIDs cache, the same should be updated in kv as well
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001807 // by calling DeleteFlowIDsForGem
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001808 f.gemToFlowIDsKey.Lock()
1809 delete(f.gemToFlowIDs, uint32(gemPortID))
1810 f.gemToFlowIDsKey.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001811
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001812 f.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, uint32(gemPortID))
1813
1814 f.resourceMgr.FreeGemPortID(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001815
1816 // Delete the gem port on the ONU.
Girish Gowdraa482f272021-03-24 23:04:19 -07001817 if err := f.sendDeleteGemPortToChild(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID), tpPath); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001818 logger.Errorw(ctx, "error-processing-delete-gem-port-towards-onu",
1819 log.Fields{
1820 "err": err,
Girish Gowdraa482f272021-03-24 23:04:19 -07001821 "intfID": intfID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001822 "onu-id": onuID,
1823 "uni-id": uniID,
1824 "device-id": f.deviceHandler.device.Id,
1825 "gemport-id": gemPortID})
1826 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001827 techprofileInst, err := f.techprofile.GetTPInstance(ctx, tpPath)
1828 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1829 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1830 log.Fields{
1831 "tp-id": tpID,
1832 "path": tpPath}, err)
1833 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001834 switch techprofileInst := techprofileInst.(type) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001835 case *tp_pb.TechProfileInstance:
Gamze Abakacb0e6772021-06-10 08:32:12 +00001836 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, intfID, uint32(onuID), uint32(uniID), techprofileInst, uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001837 if !ok {
Girish Gowdraa482f272021-03-24 23:04:19 -07001838 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, intfID, uint32(onuID), uint32(uniID), tpID); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001839 logger.Warn(ctx, err)
1840 }
Girish Gowdraa482f272021-03-24 23:04:19 -07001841 if err := f.DeleteTechProfileInstance(ctx, intfID, uint32(onuID), uint32(uniID), "", tpID); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001842 logger.Warn(ctx, err)
1843 }
Girish Gowdraa482f272021-03-24 23:04:19 -07001844 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001845 logger.Warn(ctx, err)
1846 }
Girish Gowdraa482f272021-03-24 23:04:19 -07001847 if err := f.RemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: uint32(onuID), uniID: uint32(uniID), tpID: tpID, uniPort: portNum, tpInst: techprofileInst}); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001848 logger.Warn(ctx, err)
1849 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001850 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001851 case *tp_pb.EponTechProfileInstance:
Girish Gowdraa482f272021-03-24 23:04:19 -07001852 if err := f.resourceMgr.RemoveTechProfileIDForOnu(ctx, intfID, uint32(onuID), uint32(uniID), tpID); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001853 logger.Warn(ctx, err)
1854 }
Girish Gowdraa482f272021-03-24 23:04:19 -07001855 if err := f.DeleteTechProfileInstance(ctx, intfID, uint32(onuID), uint32(uniID), "", tpID); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001856 logger.Warn(ctx, err)
1857 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001858 f.resourceMgr.FreeAllocID(ctx, intfID, uint32(onuID), uint32(uniID), techprofileInst.AllocId)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001859 // Delete the TCONT on the ONU.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001860 if err := f.sendDeleteTcontToChild(ctx, intfID, uint32(onuID), uint32(uniID), techprofileInst.AllocId, tpPath); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001861 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
Shrey Baid26912972020-04-16 21:02:31 +05301862 log.Fields{
Girish Gowdraa482f272021-03-24 23:04:19 -07001863 "intf": intfID,
Shrey Baid26912972020-04-16 21:02:31 +05301864 "onu-id": onuID,
1865 "uni-id": uniID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001866 "device-id": f.deviceHandler.device.Id,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001867 "alloc-id": techprofileInst.AllocId})
Gamze Abakafee36392019-10-03 11:17:24 +00001868 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001869 default:
1870 logger.Errorw(ctx, "error-unknown-tech",
1871 log.Fields{
1872 "techprofileInst": techprofileInst})
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001873 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001874
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301875 return nil
1876}
1877
David K. Bainbridge794735f2020-02-11 21:01:37 -08001878// nolint: gocyclo
Girish Gowdrae8f473b2020-10-16 11:07:21 -07001879func (f *OpenOltFlowMgr) clearFlowFromDeviceAndResourceManager(ctx context.Context, flow *ofp.OfpFlowStats, flowDirection string) error {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001880 logger.Infow(ctx, "clear-flow-from-resource-manager",
Shrey Baid26912972020-04-16 21:02:31 +05301881 log.Fields{
1882 "flowDirection": flowDirection,
1883 "flow": *flow,
1884 "device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +00001885
1886 if flowDirection == Multicast {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001887