blob: 8c855a024ae9df7b201f09e05b18ffb492484e5c [file] [log] [blame]
manikkaraj kbf256be2019-03-25 00:13:48 +05301/*
2 * Copyright 2018-present Open Networking Foundation
3
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7
8 * http://www.apache.org/licenses/LICENSE-2.0
9
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Scott Bakerdbd960e2020-02-28 08:57:51 -080017//Package core provides the utility for olt devices, flows and statistics
18package core
manikkaraj kbf256be2019-03-25 00:13:48 +053019
20import (
21 "context"
Matteo Scandolo6056e822019-11-13 14:05:29 -080022 "encoding/hex"
Girish Gowdracefae192020-03-19 18:14:10 -070023 "errors"
manikkaraj kbf256be2019-03-25 00:13:48 +053024 "fmt"
Gamze Abaka7650be62021-02-26 10:50:36 +000025 "strconv"
serkant.uluderya4aff1862020-09-17 23:35:26 +030026 "strings"
27 "sync"
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070028 "time"
serkant.uluderya4aff1862020-09-17 23:35:26 +030029
Mahir Gunyel1d20eff2021-07-04 15:39:36 -070030 "github.com/opencord/voltha-lib-go/v5/pkg/meters"
31
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -070032 "github.com/opencord/voltha-lib-go/v5/pkg/flows"
33 "github.com/opencord/voltha-lib-go/v5/pkg/log"
34 tp "github.com/opencord/voltha-lib-go/v5/pkg/techprofile"
Scott Bakerdbd960e2020-02-28 08:57:51 -080035 rsrcMgr "github.com/opencord/voltha-openolt-adapter/internal/pkg/resourcemanager"
Girish Gowdraa09aeab2020-09-14 16:30:52 -070036 "github.com/opencord/voltha-protos/v4/go/common"
37 ic "github.com/opencord/voltha-protos/v4/go/inter_container"
38 ofp "github.com/opencord/voltha-protos/v4/go/openflow_13"
39 openoltpb2 "github.com/opencord/voltha-protos/v4/go/openolt"
40 tp_pb "github.com/opencord/voltha-protos/v4/go/tech_profile"
41 "github.com/opencord/voltha-protos/v4/go/voltha"
Chaitrashree G S579fe732019-08-20 20:50:47 -040042
Thomas Lee S94109f12020-03-03 16:39:29 +053043 "github.com/opencord/voltha-openolt-adapter/internal/pkg/olterrors"
Daniele Rossi22db98e2019-07-11 11:50:00 +000044 "google.golang.org/grpc/codes"
45 "google.golang.org/grpc/status"
manikkaraj kbf256be2019-03-25 00:13:48 +053046)
47
48const (
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070049 //IPProtoDhcp flow category
50 IPProtoDhcp = 17
manikkaraj kbf256be2019-03-25 00:13:48 +053051
Girish Gowdraa09aeab2020-09-14 16:30:52 -070052 //IgmpProto proto value
53 IgmpProto = 2
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070054
55 //EapEthType eapethtype value
56 EapEthType = 0x888e
57 //LldpEthType lldp ethtype value
58 LldpEthType = 0x88cc
Esin Karamanae41e2b2019-12-17 18:13:13 +000059 //IPv4EthType IPv4 ethernet type value
60 IPv4EthType = 0x800
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -030061 //PPPoEDEthType PPPoE discovery ethernet type value
62 PPPoEDEthType = 0x8863
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070063
Andrea Campanella7acc0b92020-02-14 09:20:49 +010064 //ReservedVlan Transparent Vlan (Masked Vlan, VLAN_ANY in ONOS Flows)
65 ReservedVlan = 4096
Harsh Awasthiea45af72019-08-26 02:39:00 -040066
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070067 //DefaultMgmtVlan default vlan value
68 DefaultMgmtVlan = 4091
manikkaraj kbf256be2019-03-25 00:13:48 +053069
manikkaraj kbf256be2019-03-25 00:13:48 +053070 // Openolt Flow
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070071
David K. Bainbridge82efc492019-09-04 09:57:11 -070072 //Upstream constant
73 Upstream = "upstream"
74 //Downstream constant
75 Downstream = "downstream"
Esin Karamanccb714b2019-11-29 15:02:06 +000076 //Multicast constant
77 Multicast = "multicast"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070078 //PacketTagType constant
79 PacketTagType = "pkt_tag_type"
David K. Bainbridge82efc492019-09-04 09:57:11 -070080 //Untagged constant
81 Untagged = "untagged"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070082 //SingleTag constant
83 SingleTag = "single_tag"
84 //DoubleTag constant
85 DoubleTag = "double_tag"
manikkaraj kbf256be2019-03-25 00:13:48 +053086
87 // classifierInfo
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070088
89 //EthType constant
90 EthType = "eth_type"
Esin Karamanccb714b2019-11-29 15:02:06 +000091 //EthDst constant
92 EthDst = "eth_dst"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -070093 //TPID constant
94 TPID = "tpid"
95 //IPProto constant
96 IPProto = "ip_proto"
97 //InPort constant
98 InPort = "in_port"
99 //VlanVid constant
100 VlanVid = "vlan_vid"
101 //VlanPcp constant
102 VlanPcp = "vlan_pcp"
103
104 //UDPDst constant
105 UDPDst = "udp_dst"
106 //UDPSrc constant
107 UDPSrc = "udp_src"
108 //Ipv4Dst constant
109 Ipv4Dst = "ipv4_dst"
110 //Ipv4Src constant
111 Ipv4Src = "ipv4_src"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700112 //Metadata constant
113 Metadata = "metadata"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700114 //TunnelID constant
115 TunnelID = "tunnel_id"
David K. Bainbridge82efc492019-09-04 09:57:11 -0700116 //Output constant
117 Output = "output"
Esin Karamanccb714b2019-11-29 15:02:06 +0000118 //GroupID constant
119 GroupID = "group_id"
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700120 // Actions
121
122 //PopVlan constant
123 PopVlan = "pop_vlan"
124 //PushVlan constant
125 PushVlan = "push_vlan"
126 //TrapToHost constant
127 TrapToHost = "trap_to_host"
Manikkaraj kb1d51442019-07-23 10:41:02 -0400128 //MaxMeterBand constant
129 MaxMeterBand = 2
130 //VlanPCPMask contant
131 VlanPCPMask = 0xFF
132 //VlanvIDMask constant
133 VlanvIDMask = 0xFFF
Gamze Abakafee36392019-10-03 11:17:24 +0000134 //IntfID constant
135 IntfID = "intfId"
136 //OnuID constant
137 OnuID = "onuId"
138 //UniID constant
139 UniID = "uniId"
140 //PortNo constant
141 PortNo = "portNo"
142 //AllocID constant
143 AllocID = "allocId"
Gamze Abakafcbd6e72020-12-17 13:25:16 +0000144 //GemID constant
145 GemID = "gemId"
Esin Karamanccb714b2019-11-29 15:02:06 +0000146
147 //NoneOnuID constant
148 NoneOnuID = -1
149 //NoneUniID constant
150 NoneUniID = -1
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700151
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700152 // Max number of flows that can be queued per ONU
153 maxConcurrentFlowsPerOnu = 20
manikkaraj kbf256be2019-03-25 00:13:48 +0530154
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700155 bitMapPrefix = "0b"
156 pbit1 = '1'
157)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400158
Gamze Abakafee36392019-10-03 11:17:24 +0000159type schedQueue struct {
160 direction tp_pb.Direction
161 intfID uint32
162 onuID uint32
163 uniID uint32
164 tpID uint32
165 uniPort uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700166 tpInst interface{}
Gamze Abakafee36392019-10-03 11:17:24 +0000167 meterID uint32
168 flowMetadata *voltha.FlowMetadata
169}
170
Gamze Abaka7650be62021-02-26 10:50:36 +0000171type flowContext struct {
172 intfID uint32
173 onuID uint32
174 uniID uint32
175 portNo uint32
176 classifier map[string]interface{}
177 action map[string]interface{}
178 logicalFlow *ofp.OfpFlowStats
179 allocID uint32
180 gemPortID uint32
181 tpID uint32
182 pbitToGem map[uint32]uint32
183 gemToAes map[uint32]bool
184}
185
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700186// This control block is created per flow add/remove and pushed on the incomingFlows channel slice
187// The flowControlBlock is then picked by the perOnuFlowHandlerRoutine for further processing.
188// There is on perOnuFlowHandlerRoutine routine per ONU that constantly monitors for any incoming
189// flow and processes it serially
190type flowControlBlock struct {
191 ctx context.Context // Flow handler context
192 addFlow bool // if true flow to be added, else removed
193 flow *voltha.OfpFlowStats // Flow message
194 flowMetadata *voltha.FlowMetadata // FlowMetadata that contains flow meter information. This can be nil for Flow remove
195 errChan *chan error // channel to report the Flow handling error
Esin Karamanccb714b2019-11-29 15:02:06 +0000196}
197
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700198//OpenOltFlowMgr creates the Structure of OpenOltFlowMgr obj
manikkaraj kbf256be2019-03-25 00:13:48 +0530199type OpenOltFlowMgr struct {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700200 ponPortIdx uint32 // Pon Port this FlowManager is responsible for
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700201 techprofile tp.TechProfileIf
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700202 deviceHandler *DeviceHandler
203 grpMgr *OpenOltGroupMgr
204 resourceMgr *rsrcMgr.OpenOltResourceMgr
205
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700206 gemToFlowIDs map[uint32][]uint64 // gem port id to flow ids
207 gemToFlowIDsKey sync.RWMutex // lock to be used to access the gemToFlowIDs map
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700208
209 packetInGemPort map[rsrcMgr.PacketInInfoKey]uint32 //packet in gem port local cache
210 packetInGemPortLock sync.RWMutex
211
Matteo Scandolo2c0d2742020-06-10 11:28:42 -0700212 // TODO create a type rsrcMgr.OnuGemInfos to be used instead of []rsrcMgr.OnuGemInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700213 onuGemInfoMap map[uint32]*rsrcMgr.OnuGemInfo //onu, gem and uni info local cache -> map of onuID to OnuGemInfo
Matteo Scandoloabf9c512020-06-23 19:31:14 -0700214 // We need to have a global lock on the onuGemInfo map
Girish Gowdra9602eb42020-09-09 15:50:39 -0700215 onuGemInfoLock sync.RWMutex
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700216
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700217 flowIDToGems map[uint64][]uint32
218 flowIDToGemsLock sync.RWMutex
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700219
220 // Slice of channels. Each channel in slice, index by ONU ID, queues flows per ONU.
221 // A go routine per ONU, waits on the unique channel (indexed by ONU ID) for incoming flows (add/remove)
222 incomingFlows []chan flowControlBlock
manikkaraj kbf256be2019-03-25 00:13:48 +0530223}
224
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700225//NewFlowManager creates OpenOltFlowMgr object and initializes the parameters
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700226func NewFlowManager(ctx context.Context, dh *DeviceHandler, rMgr *rsrcMgr.OpenOltResourceMgr, grpMgr *OpenOltGroupMgr, ponPortIdx uint32) *OpenOltFlowMgr {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000227 logger.Infow(ctx, "initializing-flow-manager", log.Fields{"device-id": dh.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530228 var flowMgr OpenOltFlowMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530229 var err error
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530230
manikkaraj kbf256be2019-03-25 00:13:48 +0530231 flowMgr.deviceHandler = dh
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700232 flowMgr.ponPortIdx = ponPortIdx
Girish Gowdra9602eb42020-09-09 15:50:39 -0700233 flowMgr.grpMgr = grpMgr
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530234 flowMgr.resourceMgr = rMgr
Neha Sharma96b7bf22020-06-15 10:37:32 +0000235 if err = flowMgr.populateTechProfilePerPonPort(ctx); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700236 logger.Errorw(ctx, "error-while-populating-tech-profile-mgr", log.Fields{"err": err})
manikkaraj kbf256be2019-03-25 00:13:48 +0530237 return nil
238 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700239 flowMgr.gemToFlowIDs = make(map[uint32][]uint64)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530240 flowMgr.packetInGemPort = make(map[rsrcMgr.PacketInInfoKey]uint32)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700241 flowMgr.flowIDToGems = make(map[uint64][]uint32)
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700242
243 // Create a slice of buffered channels for handling concurrent flows per ONU.
244 // The additional entry (+1) is to handle the NNI trap flows on a separate channel from individual ONUs channel
245 flowMgr.incomingFlows = make([]chan flowControlBlock, MaxOnusPerPon+1)
246 for i := range flowMgr.incomingFlows {
247 flowMgr.incomingFlows[i] = make(chan flowControlBlock, maxConcurrentFlowsPerOnu)
248 // Spin up a go routine to handling incoming flows (add/remove).
249 // There will be on go routine per ONU.
250 // This routine will be blocked on the flowMgr.incomingFlows[onu-id] channel for incoming flows.
251 go flowMgr.perOnuFlowHandlerRoutine(flowMgr.incomingFlows[i])
252 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700253 flowMgr.onuGemInfoMap = make(map[uint32]*rsrcMgr.OnuGemInfo)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530254 //Load the onugem info cache from kv store on flowmanager start
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700255 onuIDStart := flowMgr.deviceHandler.deviceInfo.OnuIdStart
256 onuIDEnd := flowMgr.deviceHandler.deviceInfo.OnuIdEnd
257 for onuID := onuIDStart; onuID <= onuIDEnd; onuID++ {
258 // check for a valid serial number in onuGem as GetOnuGemInfo can return nil error in case of nothing found in the path.
Gamze Abaka3e268512021-09-08 01:14:33 +0000259 onugem, err := rMgr.GetOnuGemInfo(ctx, ponPortIdx, onuID)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700260 if err == nil && onugem != nil && onugem.SerialNumber != "" {
261 flowMgr.onuGemInfoMap[onuID] = onugem
262 }
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +0530263 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700264
265 //Load flowID list per gem map And gemIDs per flow per interface from the kvstore.
266 flowMgr.loadFlowIDsForGemAndGemIDsForFlow(ctx)
267
Esin Karamanccb714b2019-11-29 15:02:06 +0000268 //load interface to multicast queue map from kv store
Girish Gowdra9602eb42020-09-09 15:50:39 -0700269 flowMgr.grpMgr.LoadInterfaceToMulticastQueueMap(ctx)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000270 logger.Info(ctx, "initialization-of-flow-manager-success")
manikkaraj kbf256be2019-03-25 00:13:48 +0530271 return &flowMgr
272}
273
Kent Hagermane6ff1012020-07-14 15:07:53 -0400274func (f *OpenOltFlowMgr) registerFlow(ctx context.Context, flowFromCore *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700275 if !deviceFlow.ReplicateFlow && deviceFlow.GemportId > 0 {
276 // 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 -0700277 return f.registerFlowIDForGemAndGemIDForFlow(ctx, uint32(deviceFlow.AccessIntfId), uint32(deviceFlow.GemportId), flowFromCore)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700278 } else if deviceFlow.ReplicateFlow && len(deviceFlow.PbitToGemport) > 0 {
279 // Flow is replicated in this case. We need to register the flow for all the gem-ports it is replicated to.
280 for _, gemPort := range deviceFlow.PbitToGemport {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700281 if err := f.registerFlowIDForGemAndGemIDForFlow(ctx, uint32(deviceFlow.AccessIntfId), gemPort, flowFromCore); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700282 return err
283 }
Matteo Scandolo738c52a2020-08-03 11:14:22 -0700284 }
Gamze Abakafee36392019-10-03 11:17:24 +0000285 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700286 return nil
287}
288
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700289func (f *OpenOltFlowMgr) registerFlowIDForGemAndGemIDForFlow(ctx context.Context, accessIntfID uint32, gemPortID uint32, flowFromCore *ofp.OfpFlowStats) error {
290 // update gem->flows map
291 f.gemToFlowIDsKey.Lock()
292 flowIDList, ok := f.gemToFlowIDs[gemPortID]
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700293 if !ok {
294 flowIDList = []uint64{flowFromCore.Id}
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700295 } else {
296 flowIDList = appendUnique64bit(flowIDList, flowFromCore.Id)
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700297 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700298 f.gemToFlowIDs[gemPortID] = flowIDList
299 f.gemToFlowIDsKey.Unlock()
300
301 // update flow->gems map
302 f.flowIDToGemsLock.Lock()
303 if _, ok := f.flowIDToGems[flowFromCore.Id]; !ok {
304 f.flowIDToGems[flowFromCore.Id] = []uint32{gemPortID}
305 } else {
306 f.flowIDToGems[flowFromCore.Id] = appendUnique32bit(f.flowIDToGems[flowFromCore.Id], gemPortID)
307 }
308 f.flowIDToGemsLock.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700309
310 // update the flowids for a gem to the KVstore
311 return f.resourceMgr.UpdateFlowIDsForGem(ctx, accessIntfID, gemPortID, flowIDList)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -0400312}
313
Girish Gowdra9602eb42020-09-09 15:50:39 -0700314func (f *OpenOltFlowMgr) processAddFlow(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, portNo uint32,
salmansiddiqui7ac62132019-08-22 03:58:50 +0000315 classifierInfo map[string]interface{}, actionInfo map[string]interface{}, flow *ofp.OfpFlowStats, TpID uint32,
Andrea Campanellabfe08432020-09-11 17:07:03 +0200316 UsMeterID uint32, DsMeterID uint32, flowMetadata *voltha.FlowMetadata) error {
Gamze Abakafee36392019-10-03 11:17:24 +0000317 var allocID uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530318 var gemPorts []uint32
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700319 var TpInst interface{}
manikkaraj kbf256be2019-03-25 00:13:48 +0530320
Neha Sharma96b7bf22020-06-15 10:37:32 +0000321 logger.Infow(ctx, "dividing-flow", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530322 "device-id": f.deviceHandler.device.Id,
323 "intf-id": intfID,
324 "onu-id": onuID,
325 "uni-id": uniID,
326 "port-no": portNo,
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700327 "classifier": classifierInfo,
Shrey Baid26912972020-04-16 21:02:31 +0530328 "action": actionInfo,
329 "usmeter-iD": UsMeterID,
330 "dsmeter-iD": DsMeterID,
331 "tp-id": TpID})
Matt Jeanneret77199612019-07-26 18:08:35 -0400332 // only create tcont/gemports if there is actually an onu id. otherwise BAL throws an error. Usually this
333 // is because the flow is an NNI flow and there would be no onu resources associated with it
334 // TODO: properly deal with NNI flows
Kent Hagermane6ff1012020-07-14 15:07:53 -0400335 if onuID == 0 {
Andrea Campanellabfe08432020-09-11 17:07:03 +0200336 cause := "no-onu-id-for-flow"
337 fields := log.Fields{
338 "onu": onuID,
339 "port-no": portNo,
340 "classifer": classifierInfo,
341 "action": actionInfo,
342 "device-id": f.deviceHandler.device.Id}
343 logger.Errorw(ctx, cause, fields)
344 return olterrors.NewErrNotFound(cause, fields, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530345 }
346
Matteo Scandolod625b4c2020-04-02 16:16:01 -0700347 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Neha Sharma96b7bf22020-06-15 10:37:32 +0000348 logger.Debugw(ctx, "uni-port-path", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530349 "uni": uni,
350 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530351
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700352 logger.Debugw(ctx, "dividing-flow-create-tcont-gem-ports", log.Fields{
353 "device-id": f.deviceHandler.device.Id,
354 "intf-id": intfID,
355 "onu-id": onuID,
356 "uni-id": uniID,
357 "port-no": portNo,
358 "classifier": classifierInfo,
359 "action": actionInfo,
360 "usmeter-id": UsMeterID,
361 "dsmeter-id": DsMeterID,
362 "tp-id": TpID})
363 allocID, gemPorts, TpInst = f.createTcontGemports(ctx, intfID, onuID, uniID, uni, portNo, TpID, UsMeterID, DsMeterID, flowMetadata)
364 if allocID == 0 || gemPorts == nil || TpInst == nil {
365 logger.Error(ctx, "alloc-id-gem-ports-tp-unavailable")
366 return olterrors.NewErrNotFound(
367 "alloc-id-gem-ports-tp-unavailable",
368 nil, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400369 }
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700370 args := make(map[string]uint32)
371 args[IntfID] = intfID
372 args[OnuID] = onuID
373 args[UniID] = uniID
374 args[PortNo] = portNo
375 args[AllocID] = allocID
376
377 /* Flows can be added specific to gemport if p-bits are received.
378 * If no pbit mentioned then adding flows for all gemports
379 */
380 f.checkAndAddFlow(ctx, args, classifierInfo, actionInfo, flow, TpInst, gemPorts, TpID, uni)
381
Andrea Campanellabfe08432020-09-11 17:07:03 +0200382 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530383}
384
salmansiddiqui7ac62132019-08-22 03:58:50 +0000385// CreateSchedulerQueues creates traffic schedulers on the device with the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530386func (f *OpenOltFlowMgr) CreateSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400387
Neha Sharma96b7bf22020-06-15 10:37:32 +0000388 logger.Debugw(ctx, "CreateSchedulerQueues",
Shrey Baid26912972020-04-16 21:02:31 +0530389 log.Fields{"dir": sq.direction,
390 "intf-id": sq.intfID,
391 "onu-id": sq.onuID,
392 "uni-id": sq.uniID,
393 "tp-id": sq.tpID,
394 "meter-id": sq.meterID,
395 "tp-inst": sq.tpInst,
396 "flowmetadata": sq.flowMetadata,
397 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400398
Gamze Abakafee36392019-10-03 11:17:24 +0000399 Direction, err := verifyMeterIDAndGetDirection(sq.meterID, sq.direction)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000400 if err != nil {
401 return err
Manikkaraj kb1d51442019-07-23 10:41:02 -0400402 }
403
404 /* Lets make a simple assumption that if the meter-id is present on the KV store,
405 * then the scheduler and queues configuration is applied on the OLT device
406 * in the given direction.
407 */
salmansiddiqui7ac62132019-08-22 03:58:50 +0000408
Manikkaraj kb1d51442019-07-23 10:41:02 -0400409 var SchedCfg *tp_pb.SchedulerConfig
Girish Gowdraa482f272021-03-24 23:04:19 -0700410 meterInfo, err := f.resourceMgr.GetMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400411 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530412 return olterrors.NewErrNotFound("meter",
413 log.Fields{"intf-id": sq.intfID,
414 "onu-id": sq.onuID,
415 "uni-id": sq.uniID,
416 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400417 }
Girish Kumarf26e4882020-03-05 06:49:10 +0000418
Girish Gowdraa482f272021-03-24 23:04:19 -0700419 if meterInfo != nil {
420 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 -0700421 if meterInfo.MeterID == sq.meterID {
Girish Gowdraa482f272021-03-24 23:04:19 -0700422 if err := f.resourceMgr.HandleMeterInfoRefCntUpdate(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID, true); err != nil {
423 return err
424 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400425 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400426 }
Thomas Lee S94109f12020-03-03 16:39:29 +0530427 return olterrors.NewErrInvalidValue(log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800428 "unsupported": "meter-id",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700429 "kv-store-meter-id": meterInfo.MeterID,
Shrey Baid26912972020-04-16 21:02:31 +0530430 "meter-id-in-flow": sq.meterID,
431 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400432 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000433
Neha Sharma96b7bf22020-06-15 10:37:32 +0000434 logger.Debugw(ctx, "meter-does-not-exist-creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530435 log.Fields{
436 "meter-id": sq.meterID,
437 "direction": Direction,
438 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000439
Gamze Abakafee36392019-10-03 11:17:24 +0000440 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700441 SchedCfg = f.techprofile.GetUsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Gamze Abakafee36392019-10-03 11:17:24 +0000442 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700443 SchedCfg = f.techprofile.GetDsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Girish Kumar8f73fe02019-12-09 13:19:37 +0000444 }
445
Girish Gowdraa482f272021-03-24 23:04:19 -0700446 found := false
447 meterInfo = &rsrcMgr.MeterInfo{}
Gamze Abakafee36392019-10-03 11:17:24 +0000448 if sq.flowMetadata != nil {
449 for _, meter := range sq.flowMetadata.Meters {
450 if sq.meterID == meter.MeterId {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700451 meterInfo.MeterID = meter.MeterId
Girish Gowdraa482f272021-03-24 23:04:19 -0700452 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 +0000453 logger.Debugw(ctx, "found-meter-config-from-flowmetadata",
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700454 log.Fields{"meter": meter,
Shrey Baid26912972020-04-16 21:02:31 +0530455 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -0700456 found = true
Manikkaraj kb1d51442019-07-23 10:41:02 -0400457 break
458 }
459 }
460 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000461 logger.Errorw(ctx, "flow-metadata-not-present-in-flow", log.Fields{"device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400462 }
Girish Gowdraa482f272021-03-24 23:04:19 -0700463 if !found {
Thomas Lee S94109f12020-03-03 16:39:29 +0530464 return olterrors.NewErrNotFound("meterbands", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -0800465 "reason": "Could-not-get-meterbands-from-flowMetadata",
466 "flow-metadata": sq.flowMetadata,
Shrey Baid26912972020-04-16 21:02:31 +0530467 "meter-id": sq.meterID,
468 "device-id": f.deviceHandler.device.Id}, nil)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400469 }
Gamze Abaka01174422021-03-10 06:55:27 +0000470
471 var TrafficShaping *tp_pb.TrafficShapingInfo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700472 if TrafficShaping, err = meters.GetTrafficShapingInfo(ctx, sq.flowMetadata.Meters[0]); err != nil {
Gamze Abaka01174422021-03-10 06:55:27 +0000473 return olterrors.NewErrInvalidValue(log.Fields{
474 "reason": "invalid-meter-config",
475 "meter-id": sq.meterID,
476 "device-id": f.deviceHandler.device.Id}, nil)
477 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400478
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700479 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile.GetTrafficScheduler(sq.tpInst.(*tp_pb.TechProfileInstance), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000480 TrafficSched[0].TechProfileId = sq.tpID
Manikkaraj kb1d51442019-07-23 10:41:02 -0400481
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700482 if err := f.pushSchedulerQueuesToDevice(ctx, sq, TrafficSched); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530483 return olterrors.NewErrAdapter("failure-pushing-traffic-scheduler-and-queues-to-device",
484 log.Fields{"intf-id": sq.intfID,
485 "direction": sq.direction,
486 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400487 }
488
salmansiddiqui7ac62132019-08-22 03:58:50 +0000489 /* After we successfully applied the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400490 * store the meter id on the KV store, for further reference.
491 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700492 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 +0530493 return olterrors.NewErrAdapter("failed-updating-meter-id",
494 log.Fields{"onu-id": sq.onuID,
495 "meter-id": sq.meterID,
496 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400497 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000498 logger.Infow(ctx, "updated-meter-info-into-kv-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530499 log.Fields{"direction": Direction,
Girish Gowdraa482f272021-03-24 23:04:19 -0700500 "meter-info": meterInfo,
501 "device-id": f.deviceHandler.device.Id})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400502 return nil
503}
504
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700505func (f *OpenOltFlowMgr) pushSchedulerQueuesToDevice(ctx context.Context, sq schedQueue, TrafficSched []*tp_pb.TrafficScheduler) error {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700506 trafficQueues, err := f.techprofile.GetTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000507
508 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530509 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
510 log.Fields{"intf-id": sq.intfID,
511 "direction": sq.direction,
512 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000513 }
514
Gamze Abakacb0e6772021-06-10 08:32:12 +0000515 if allocExists := f.isAllocUsedByAnotherUNI(ctx, sq); !allocExists {
516 logger.Debugw(ctx, "sending-traffic-scheduler-create-to-device",
517 log.Fields{
518 "direction": sq.direction,
519 "TrafficScheds": TrafficSched,
520 "device-id": f.deviceHandler.device.Id,
521 "intfID": sq.intfID,
522 "onuID": sq.onuID,
523 "uniID": sq.uniID})
524 if _, err := f.deviceHandler.Client.CreateTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
525 IntfId: sq.intfID, OnuId: sq.onuID,
526 UniId: sq.uniID, PortNo: sq.uniPort,
527 TrafficScheds: TrafficSched}); err != nil {
528 return olterrors.NewErrAdapter("failed-to-create-traffic-schedulers-in-device", log.Fields{"TrafficScheds": TrafficSched}, err)
529 }
530 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
531 "direction": sq.direction,
532 "traffic-queues": trafficQueues,
533 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000534 }
535
536 // On receiving the CreateTrafficQueues request, the driver should create corresponding
537 // downstream queues.
Neha Sharma96b7bf22020-06-15 10:37:32 +0000538 logger.Debugw(ctx, "sending-traffic-queues-create-to-device",
Shrey Baid26912972020-04-16 21:02:31 +0530539 log.Fields{"direction": sq.direction,
540 "traffic-queues": trafficQueues,
541 "device-id": f.deviceHandler.device.Id})
npujarec5762e2020-01-01 14:08:48 +0530542 if _, err := f.deviceHandler.Client.CreateTrafficQueues(ctx,
Girish Kumar8f73fe02019-12-09 13:19:37 +0000543 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
544 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000545 TrafficQueues: trafficQueues,
546 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530547 return olterrors.NewErrAdapter("failed-to-create-traffic-queues-in-device", log.Fields{"traffic-queues": trafficQueues}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000548 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000549 logger.Infow(ctx, "successfully-created-traffic-schedulers", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530550 "direction": sq.direction,
551 "traffic-queues": trafficQueues,
552 "device-id": f.deviceHandler.device.Id})
Girish Kumar8f73fe02019-12-09 13:19:37 +0000553
Esin Karamanccb714b2019-11-29 15:02:06 +0000554 if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700555 multicastTrafficQueues := f.techprofile.GetMulticastTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance))
Esin Karamanccb714b2019-11-29 15:02:06 +0000556 if len(multicastTrafficQueues) > 0 {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700557 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 +0000558 //the default queue with multicastQueuePerPonPort.Priority per a pon interface is used for multicast service
559 //just put it in interfaceToMcastQueueMap to use for building group members
Neha Sharma96b7bf22020-06-15 10:37:32 +0000560 logger.Debugw(ctx, "multicast-traffic-queues", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000561 multicastQueuePerPonPort := multicastTrafficQueues[0]
Girish Gowdra9602eb42020-09-09 15:50:39 -0700562 val := &QueueInfoBrief{
Esin Karamanccb714b2019-11-29 15:02:06 +0000563 gemPortID: multicastQueuePerPonPort.GemportId,
564 servicePriority: multicastQueuePerPonPort.Priority,
565 }
Girish Gowdra9602eb42020-09-09 15:50:39 -0700566 f.grpMgr.UpdateInterfaceToMcastQueueMap(sq.intfID, val)
Esin Karamanccb714b2019-11-29 15:02:06 +0000567 //also store the queue info in kv store
Kent Hagermane6ff1012020-07-14 15:07:53 -0400568 if err := f.resourceMgr.AddMcastQueueForIntf(ctx, sq.intfID, multicastQueuePerPonPort.GemportId, multicastQueuePerPonPort.Priority); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700569 logger.Errorw(ctx, "failed-to-add-mcast-queue", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -0400570 return err
571 }
Shrey Baid26912972020-04-16 21:02:31 +0530572
Neha Sharma96b7bf22020-06-15 10:37:32 +0000573 logger.Infow(ctx, "multicast-queues-successfully-updated", log.Fields{"device-id": f.deviceHandler.device.Id})
Esin Karamanccb714b2019-11-29 15:02:06 +0000574 }
575 }
576 }
Girish Kumar8f73fe02019-12-09 13:19:37 +0000577 return nil
578}
579
salmansiddiqui7ac62132019-08-22 03:58:50 +0000580// RemoveSchedulerQueues removes the traffic schedulers from the device based on the given scheduler configuration and traffic shaping info
npujarec5762e2020-01-01 14:08:48 +0530581func (f *OpenOltFlowMgr) RemoveSchedulerQueues(ctx context.Context, sq schedQueue) error {
Manikkaraj kb1d51442019-07-23 10:41:02 -0400582
583 var Direction string
584 var SchedCfg *tp_pb.SchedulerConfig
585 var err error
Neha Sharma96b7bf22020-06-15 10:37:32 +0000586 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
Shrey Baid26912972020-04-16 21:02:31 +0530587 log.Fields{
588 "direction": sq.direction,
589 "intf-id": sq.intfID,
590 "onu-id": sq.onuID,
591 "uni-id": sq.uniID,
592 "uni-port": sq.uniPort,
593 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000594 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700595 SchedCfg = f.techprofile.GetUsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400596 Direction = "upstream"
Gamze Abakafee36392019-10-03 11:17:24 +0000597 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700598 SchedCfg = f.techprofile.GetDsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
Manikkaraj kb1d51442019-07-23 10:41:02 -0400599 Direction = "downstream"
600 }
601
Girish Gowdraa482f272021-03-24 23:04:19 -0700602 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 -0400603
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700604 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile.GetTrafficScheduler(sq.tpInst.(*tp_pb.TechProfileInstance), SchedCfg, TrafficShaping)}
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000605 TrafficSched[0].TechProfileId = sq.tpID
Girish Kumar8f73fe02019-12-09 13:19:37 +0000606
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700607 TrafficQueues, err := f.techprofile.GetTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance), sq.direction)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000608 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530609 return olterrors.NewErrAdapter("unable-to-construct-traffic-queue-configuration",
610 log.Fields{
611 "intf-id": sq.intfID,
612 "direction": sq.direction,
613 "device-id": f.deviceHandler.device.Id}, err)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000614 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400615
npujarec5762e2020-01-01 14:08:48 +0530616 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
Gamze Abakafee36392019-10-03 11:17:24 +0000617 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
618 UniId: sq.uniID, PortNo: sq.uniPort,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +0000619 TrafficQueues: TrafficQueues,
620 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
Girish Kumarf26e4882020-03-05 06:49:10 +0000621 return olterrors.NewErrAdapter("unable-to-remove-traffic-queues-from-device",
Shrey Baid26912972020-04-16 21:02:31 +0530622 log.Fields{
623 "intf-id": sq.intfID,
624 "traffic-queues": TrafficQueues,
625 "device-id": f.deviceHandler.device.Id}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400626 }
Gamze Abakacb0e6772021-06-10 08:32:12 +0000627 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id, "trafficQueues": TrafficQueues})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400628
Gamze Abakacb0e6772021-06-10 08:32:12 +0000629 if allocExists := f.isAllocUsedByAnotherUNI(ctx, sq); !allocExists {
630 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
631 IntfId: sq.intfID, OnuId: sq.onuID,
632 UniId: sq.uniID, PortNo: sq.uniPort,
633 TrafficScheds: TrafficSched}); err != nil {
634 return olterrors.NewErrAdapter("unable-to-remove-traffic-schedulers-from-device",
635 log.Fields{
636 "intf-id": sq.intfID,
637 "traffic-schedulers": TrafficSched,
638 "onu-id": sq.onuID,
639 "uni-id": sq.uniID,
640 "uni-port": sq.uniPort}, err)
641 }
642
643 logger.Infow(ctx, "removed-traffic-schedulers-successfully",
644 log.Fields{"device-id": f.deviceHandler.device.Id,
645 "intf-id": sq.intfID,
646 "onu-id": sq.onuID,
647 "uni-id": sq.uniID,
648 "uni-port": sq.uniPort})
649
650 if sq.direction == tp_pb.Direction_UPSTREAM {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700651 allocID := sq.tpInst.(*tp_pb.TechProfileInstance).UsScheduler.AllocId
Gamze Abakacb0e6772021-06-10 08:32:12 +0000652 f.resourceMgr.FreeAllocID(ctx, sq.intfID, sq.onuID, sq.uniID, allocID)
653 // Delete the TCONT on the ONU.
654 uni := getUniPortPath(f.deviceHandler.device.Id, sq.intfID, int32(sq.onuID), int32(sq.uniID))
655 tpPath := f.getTPpath(ctx, sq.intfID, uni, sq.tpID)
656 if err := f.sendDeleteTcontToChild(ctx, sq.intfID, sq.onuID, sq.uniID, allocID, tpPath); err != nil {
657 logger.Errorw(ctx, "error-processing-delete-tcont-towards-onu",
658 log.Fields{
659 "intf": sq.intfID,
660 "onu-id": sq.onuID,
661 "uni-id": sq.uniID,
662 "device-id": f.deviceHandler.device.Id,
663 "alloc-id": allocID})
664 }
665 }
666 }
salmansiddiqui7ac62132019-08-22 03:58:50 +0000667
668 /* After we successfully remove the scheduler configuration on the OLT device,
Manikkaraj kb1d51442019-07-23 10:41:02 -0400669 * delete the meter id on the KV store.
670 */
Girish Gowdraa482f272021-03-24 23:04:19 -0700671 err = f.resourceMgr.RemoveMeterInfoForOnu(ctx, Direction, sq.intfID, sq.onuID, sq.uniID, sq.tpID)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400672 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +0530673 return olterrors.NewErrAdapter("unable-to-remove-meter",
674 log.Fields{
675 "onu": sq.onuID,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700676 "device-id": f.deviceHandler.device.Id,
677 "intf-id": sq.intfID,
678 "onu-id": sq.onuID,
679 "uni-id": sq.uniID,
680 "uni-port": sq.uniPort}, err)
Manikkaraj kb1d51442019-07-23 10:41:02 -0400681 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000682 logger.Infow(ctx, "removed-meter-from-KV-store-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530683 log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530684 "dir": Direction,
Girish Gowdrafb3d6102020-10-16 16:32:36 -0700685 "device-id": f.deviceHandler.device.Id,
686 "intf-id": sq.intfID,
687 "onu-id": sq.onuID,
688 "uni-id": sq.uniID,
689 "uni-port": sq.uniPort})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400690 return err
691}
692
Girish Gowdra37f13fa2021-08-16 10:59:45 -0700693// We are trying to force remove the schedulers and queues here if one exists for the given key.
694// We ignore any errors encountered in the process. The errors most likely are encountered when
695// the schedulers and queues are already cleared for the given key.
696func (f *OpenOltFlowMgr) forceRemoveSchedulerQueues(ctx context.Context, sq schedQueue) {
697
698 var schedCfg *tp_pb.SchedulerConfig
699 var err error
700 logger.Infow(ctx, "removing-schedulers-and-queues-in-olt",
701 log.Fields{
702 "direction": sq.direction,
703 "intf-id": sq.intfID,
704 "onu-id": sq.onuID,
705 "uni-id": sq.uniID,
706 "uni-port": sq.uniPort,
707 "tp-id": sq.tpID,
708 "device-id": f.deviceHandler.device.Id})
709 if sq.direction == tp_pb.Direction_UPSTREAM {
710 schedCfg = f.techprofile.GetUsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
711 } else if sq.direction == tp_pb.Direction_DOWNSTREAM {
712 schedCfg = f.techprofile.GetDsScheduler(sq.tpInst.(*tp_pb.TechProfileInstance))
713 }
714
715 TrafficShaping := &tp_pb.TrafficShapingInfo{} // this info is not really useful for the agent during flow removal. Just use default values.
716 TrafficSched := []*tp_pb.TrafficScheduler{f.techprofile.GetTrafficScheduler(sq.tpInst.(*tp_pb.TechProfileInstance), schedCfg, TrafficShaping)}
717 TrafficSched[0].TechProfileId = sq.tpID
718
719 // Remove traffic queues. Ignore any errors, just log them.
720 if TrafficQueues, err := f.techprofile.GetTrafficQueues(ctx, sq.tpInst.(*tp_pb.TechProfileInstance), sq.direction); err != nil {
721 logger.Errorw(ctx, "error retrieving traffic queue", log.Fields{
722 "direction": sq.direction,
723 "intf-id": sq.intfID,
724 "onu-id": sq.onuID,
725 "uni-id": sq.uniID,
726 "uni-port": sq.uniPort,
727 "tp-id": sq.tpID,
728 "device-id": f.deviceHandler.device.Id,
729 "err": err})
730 } else {
731 if _, err = f.deviceHandler.Client.RemoveTrafficQueues(ctx,
732 &tp_pb.TrafficQueues{IntfId: sq.intfID, OnuId: sq.onuID,
733 UniId: sq.uniID, PortNo: sq.uniPort,
734 TrafficQueues: TrafficQueues,
735 TechProfileId: TrafficSched[0].TechProfileId}); err != nil {
736 logger.Warnw(ctx, "error removing traffic queue", log.Fields{
737 "direction": sq.direction,
738 "intf-id": sq.intfID,
739 "onu-id": sq.onuID,
740 "uni-id": sq.uniID,
741 "uni-port": sq.uniPort,
742 "tp-id": sq.tpID,
743 "device-id": f.deviceHandler.device.Id,
744 "err": err})
745
746 } else {
747 logger.Infow(ctx, "removed-traffic-queues-successfully", log.Fields{"device-id": f.deviceHandler.device.Id,
748 "direction": sq.direction,
749 "intf-id": sq.intfID,
750 "onu-id": sq.onuID,
751 "uni-id": sq.uniID,
752 "uni-port": sq.uniPort,
753 "tp-id": sq.tpID})
754 }
755 }
756
757 // Remove traffic schedulers. Ignore any errors, just log them.
758 if _, err = f.deviceHandler.Client.RemoveTrafficSchedulers(ctx, &tp_pb.TrafficSchedulers{
759 IntfId: sq.intfID, OnuId: sq.onuID,
760 UniId: sq.uniID, PortNo: sq.uniPort,
761 TrafficScheds: TrafficSched}); err != nil {
762 logger.Warnw(ctx, "error removing traffic scheduler", log.Fields{
763 "direction": sq.direction,
764 "intf-id": sq.intfID,
765 "onu-id": sq.onuID,
766 "uni-id": sq.uniID,
767 "uni-port": sq.uniPort,
768 "tp-id": sq.tpID,
769 "device-id": f.deviceHandler.device.Id,
770 "err": err})
771 } else {
772 logger.Infow(ctx, "removed-traffic-schedulers-successfully", log.Fields{"device-id": f.deviceHandler.device.Id,
773 "direction": sq.direction,
774 "intf-id": sq.intfID,
775 "onu-id": sq.onuID,
776 "uni-id": sq.uniID,
777 "uni-port": sq.uniPort,
778 "tp-id": sq.tpID})
779 }
780}
781
Gamze Abakafee36392019-10-03 11:17:24 +0000782// This function allocates tconts and GEM ports for an ONU
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700783func (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 +0000784 var allocIDs []uint32
785 var allgemPortIDs []uint32
manikkaraj kbf256be2019-03-25 00:13:48 +0530786 var gemPortIDs []uint32
Girish Gowdra3d633032019-12-10 16:37:05 +0530787 tpInstanceExists := false
Girish Kumar8f73fe02019-12-09 13:19:37 +0000788 var err error
npujarec5762e2020-01-01 14:08:48 +0530789 allocIDs = f.resourceMgr.GetCurrentAllocIDsForOnu(ctx, intfID, onuID, uniID)
790 allgemPortIDs = f.resourceMgr.GetCurrentGEMPortIDsForOnu(ctx, intfID, onuID, uniID)
Neha Sharma96b7bf22020-06-15 10:37:32 +0000791 tpPath := f.getTPpath(ctx, intfID, uni, TpID)
Girish Gowdra54934262019-11-13 14:19:55 +0530792
Neha Sharma96b7bf22020-06-15 10:37:32 +0000793 logger.Debugw(ctx, "creating-new-tcont-and-gem", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530794 "intf-id": intfID,
795 "onu-id": onuID,
796 "uni-id": uniID,
797 "device-id": f.deviceHandler.device.Id,
798 "tp-id": TpID})
Girish Gowdra54934262019-11-13 14:19:55 +0530799
Manikkaraj kb1d51442019-07-23 10:41:02 -0400800 // Check tech profile instance already exists for derived port name
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700801 techProfileInstance, _ := f.techprofile.GetTPInstance(ctx, tpPath)
salmansiddiqui7ac62132019-08-22 03:58:50 +0000802 if techProfileInstance == nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000803 logger.Infow(ctx, "tp-instance-not-found--creating-new",
Shrey Baid26912972020-04-16 21:02:31 +0530804 log.Fields{
805 "path": tpPath,
806 "device-id": f.deviceHandler.device.Id})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700807 techProfileInstance, err = f.techprofile.CreateTechProfileInstance(ctx, TpID, uni, intfID)
Girish Kumar8f73fe02019-12-09 13:19:37 +0000808 if err != nil {
Girish Gowdra54934262019-11-13 14:19:55 +0530809 // This should not happen, something wrong in KV backend transaction
Neha Sharma96b7bf22020-06-15 10:37:32 +0000810 logger.Errorw(ctx, "tp-instance-create-failed",
Shrey Baid26912972020-04-16 21:02:31 +0530811 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700812 "err": err,
Shrey Baid26912972020-04-16 21:02:31 +0530813 "tp-id": TpID,
814 "device-id": f.deviceHandler.device.Id})
Gamze Abakafee36392019-10-03 11:17:24 +0000815 return 0, nil, nil
manikkaraj kbf256be2019-03-25 00:13:48 +0530816 }
Kent Hagermane6ff1012020-07-14 15:07:53 -0400817 if err := f.resourceMgr.UpdateTechProfileIDForOnu(ctx, intfID, onuID, uniID, TpID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700818 logger.Warnw(ctx, "failed-to-update-tech-profile-id", log.Fields{"err": err})
Kent Hagermane6ff1012020-07-14 15:07:53 -0400819 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530820 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000821 logger.Debugw(ctx, "tech-profile-instance-already-exist-for-given port-name",
Shrey Baid26912972020-04-16 21:02:31 +0530822 log.Fields{
823 "uni": uni,
824 "device-id": f.deviceHandler.device.Id})
Girish Gowdra3d633032019-12-10 16:37:05 +0530825 tpInstanceExists = true
manikkaraj kbf256be2019-03-25 00:13:48 +0530826 }
Gamze Abakafee36392019-10-03 11:17:24 +0000827
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700828 switch tpInst := techProfileInstance.(type) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700829 case *tp_pb.TechProfileInstance:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700830 if UsMeterID != 0 {
831 sq := schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
832 uniPort: uniPort, tpInst: techProfileInstance, meterID: UsMeterID, flowMetadata: flowMetadata}
833 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000834 logger.Errorw(ctx, "CreateSchedulerQueues-failed-upstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700835 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700836 "err": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700837 "onu-id": onuID,
838 "uni-id": uniID,
839 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700840 "meter-id": UsMeterID,
841 "device-id": f.deviceHandler.device.Id})
842 return 0, nil, nil
843 }
844 }
845 if DsMeterID != 0 {
846 sq := schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: TpID,
847 uniPort: uniPort, tpInst: techProfileInstance, meterID: DsMeterID, flowMetadata: flowMetadata}
848 if err := f.CreateSchedulerQueues(ctx, sq); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000849 logger.Errorw(ctx, "CreateSchedulerQueues-failed-downstream",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700850 log.Fields{
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700851 "err": err,
Matteo Scandolo2f6b5bc2020-09-17 13:58:10 -0700852 "onu-id": onuID,
853 "uni-id": uniID,
854 "intf-id": intfID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700855 "meter-id": DsMeterID,
856 "device-id": f.deviceHandler.device.Id})
857 return 0, nil, nil
858 }
859 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700860 allocID := tpInst.UsScheduler.AllocId
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700861 for _, gem := range tpInst.UpstreamGemPortAttributeList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700862 gemPortIDs = append(gemPortIDs, gem.GemportId)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700863 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700864 allocIDs = appendUnique32bit(allocIDs, allocID)
Gamze Abakafee36392019-10-03 11:17:24 +0000865
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700866 if tpInstanceExists {
867 return allocID, gemPortIDs, techProfileInstance
868 }
869
870 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700871 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700872 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000873 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700874 log.Fields{
Matteo Scandolo84585372021-03-18 14:21:22 -0700875 "intf-id": intfID,
876 "onu-id": onuID,
877 "uni-id": uniID,
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700878 "alloc-ids": allocIDs,
879 "gemports": allgemPortIDs,
880 "device-id": f.deviceHandler.device.Id})
881 // Send Tconts and GEM ports to KV store
882 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
Girish Gowdra3d633032019-12-10 16:37:05 +0530883 return allocID, gemPortIDs, techProfileInstance
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700884 case *openoltpb2.EponTechProfileInstance:
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700885 // CreateSchedulerQueues for EPON needs to be implemented here
886 // when voltha-protos for EPON is completed.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700887 allocID := tpInst.AllocId
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700888 for _, gem := range tpInst.UpstreamQueueAttributeList {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700889 gemPortIDs = append(gemPortIDs, gem.GemportId)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700890 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700891 allocIDs = appendUnique32bit(allocIDs, allocID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700892
893 if tpInstanceExists {
894 return allocID, gemPortIDs, techProfileInstance
895 }
896
897 for _, gemPortID := range gemPortIDs {
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700898 allgemPortIDs = appendUnique32bit(allgemPortIDs, gemPortID)
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700899 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000900 logger.Infow(ctx, "allocated-tcont-and-gem-ports",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700901 log.Fields{
902 "alloc-ids": allocIDs,
903 "gemports": allgemPortIDs,
904 "device-id": f.deviceHandler.device.Id})
905 // Send Tconts and GEM ports to KV store
906 f.storeTcontsGEMPortsIntoKVStore(ctx, intfID, onuID, uniID, allocIDs, allgemPortIDs)
907 return allocID, gemPortIDs, techProfileInstance
908 default:
Neha Sharma96b7bf22020-06-15 10:37:32 +0000909 logger.Errorw(ctx, "unknown-tech",
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -0700910 log.Fields{
911 "tpInst": tpInst})
912 return 0, nil, nil
Girish Gowdra3d633032019-12-10 16:37:05 +0530913 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530914}
915
npujarec5762e2020-01-01 14:08:48 +0530916func (f *OpenOltFlowMgr) storeTcontsGEMPortsIntoKVStore(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID []uint32, gemPortIDs []uint32) {
manikkaraj kbf256be2019-03-25 00:13:48 +0530917
Neha Sharma96b7bf22020-06-15 10:37:32 +0000918 logger.Debugw(ctx, "storing-allocated-tconts-and-gem-ports-into-KV-store",
Shrey Baid26912972020-04-16 21:02:31 +0530919 log.Fields{
920 "intf-id": intfID,
921 "onu-id": onuID,
922 "uni-id": uniID,
923 "alloc-id": allocID,
924 "gemport-ids": gemPortIDs,
925 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530926 /* Update the allocated alloc_id and gem_port_id for the ONU/UNI to KV store */
npujarec5762e2020-01-01 14:08:48 +0530927 if err := f.resourceMgr.UpdateAllocIdsForOnu(ctx, intfID, onuID, uniID, allocID); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000928 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 +0530929 }
npujarec5762e2020-01-01 14:08:48 +0530930 if err := f.resourceMgr.UpdateGEMPortIDsForOnu(ctx, intfID, onuID, uniID, gemPortIDs); err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000931 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 +0530932 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700933
Neha Sharma96b7bf22020-06-15 10:37:32 +0000934 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 -0400935 for _, gemPort := range gemPortIDs {
npujarec5762e2020-01-01 14:08:48 +0530936 f.addGemPortToOnuInfoMap(ctx, intfID, onuID, gemPort)
manikkaraj k9eb6cac2019-05-09 12:32:03 -0400937 }
manikkaraj kbf256be2019-03-25 00:13:48 +0530938}
939
Neha Sharma96b7bf22020-06-15 10:37:32 +0000940func (f *OpenOltFlowMgr) populateTechProfilePerPonPort(ctx context.Context) error {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000941 var tpCount int
manikkaraj kbf256be2019-03-25 00:13:48 +0530942 for _, techRange := range f.resourceMgr.DevInfo.Ranges {
salmansiddiqui7ac62132019-08-22 03:58:50 +0000943 for _, intfID := range techRange.IntfIds {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -0700944 f.techprofile = f.resourceMgr.PonRsrMgr.TechProfileMgr
Manikkaraj kb1d51442019-07-23 10:41:02 -0400945 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000946 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530947 log.Fields{
948 "intf-id": intfID,
949 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530950 }
951 }
952 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400953 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530954 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530955 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800956 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530957 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
958 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530959 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000960 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530961 log.Fields{
962 "numofTech": tpCount,
963 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
964 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530965 return nil
966}
967
Gamze Abaka7650be62021-02-26 10:50:36 +0000968func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
969 flowContext.classifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000970 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530971 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000972 "uplinkClassifier": flowContext.classifier,
973 "uplinkAction": flowContext.action})
974 return f.addSymmetricDataPathFlow(ctx, flowContext, Upstream)
Manikkaraj k884c1242019-04-11 16:26:42 +0530975 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530976}
977
Gamze Abaka7650be62021-02-26 10:50:36 +0000978func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
979 downlinkClassifier := flowContext.classifier
980 downlinkAction := flowContext.action
981
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700982 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000983 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530984 log.Fields{
985 "downlinkClassifier": downlinkClassifier,
986 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400987 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
988 if vlan, exists := downlinkClassifier[VlanVid]; exists {
989 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700990 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Gamze Abaka7650be62021-02-26 10:50:36 +0000991 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, flowContext.intfID, flowContext.onuID, flowContext.uniID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000992 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530993 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000994 "flow": flowContext.logicalFlow,
Shrey Baid26912972020-04-16 21:02:31 +0530995 "device-id": f.deviceHandler.device.Id,
Gamze Abaka7650be62021-02-26 10:50:36 +0000996 "onu-id": flowContext.onuID,
997 "intf-id": flowContext.intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -0800998 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -0400999 }
1000 }
1001 }
Manikkaraj k884c1242019-04-11 16:26:42 +05301002 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001003
Manikkaraj k884c1242019-04-11 16:26:42 +05301004 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001005 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -04001006 // vlan_vid is a uint32. must be type asserted as such or conversion fails
1007 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +05301008 if ok {
1009 downlinkAction[VlanVid] = dlClVid & 0xfff
1010 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +05301011 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301012 "reason": "failed-to-convert-vlanid-classifier",
1013 "vlan-id": VlanVid,
1014 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +05301015 }
1016
Gamze Abaka7650be62021-02-26 10:50:36 +00001017 return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
manikkaraj kbf256be2019-03-25 00:13:48 +05301018}
1019
Gamze Abaka7650be62021-02-26 10:50:36 +00001020func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, flowContext *flowContext, direction string) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001021
Gamze Abaka7650be62021-02-26 10:50:36 +00001022 intfID := flowContext.intfID
1023 onuID := flowContext.onuID
1024 uniID := flowContext.uniID
1025 classifier := flowContext.classifier
1026 action := flowContext.action
1027 allocID := flowContext.allocID
1028 gemPortID := flowContext.gemPortID
1029 tpID := flowContext.tpID
1030 logicalFlow := flowContext.logicalFlow
Neha Sharma96b7bf22020-06-15 10:37:32 +00001031 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301032 log.Fields{
1033 "intf-id": intfID,
1034 "onu-id": onuID,
1035 "uni-id": uniID,
1036 "device-id": f.deviceHandler.device.Id,
1037 "classifier": classifier,
1038 "action": action,
1039 "direction": direction,
1040 "alloc-id": allocID,
1041 "gemport-id": gemPortID,
1042 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001043
1044 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001045 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +05301046 log.Fields{
1047 "device-id": f.deviceHandler.device.Id,
1048 "intf-id": intfID,
1049 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001050 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301051 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001052 classifierProto, err := makeOpenOltClassifierField(classifier)
1053 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301054 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301055 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001056 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301057 log.Fields{
1058 "classifier": *classifierProto,
1059 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001060 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001061 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301062 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301063 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001064 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301065 log.Fields{
1066 "action": *actionProto,
1067 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001068 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301069 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301070 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -08001071 log.Fields{
1072 "classifier": classifier,
1073 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301074 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001075 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301076 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001077
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001078 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001079 OnuId: int32(onuID),
1080 UniId: int32(uniID),
1081 FlowId: logicalFlow.Id,
1082 FlowType: direction,
1083 AllocId: int32(allocID),
1084 NetworkIntfId: int32(networkIntfID),
1085 GemportId: int32(gemPortID),
1086 Classifier: classifierProto,
1087 Action: actionProto,
1088 Priority: int32(logicalFlow.Priority),
1089 Cookie: logicalFlow.Cookie,
1090 PortNo: flowContext.portNo,
1091 TechProfileId: tpID,
1092 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1093 PbitToGemport: flowContext.pbitToGem,
1094 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001095 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001096 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001097 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301098 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001099 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301100 log.Fields{"direction": direction,
1101 "device-id": f.deviceHandler.device.Id,
1102 "flow": flow,
1103 "intf-id": intfID,
1104 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001105
David K. Bainbridge794735f2020-02-11 21:01:37 -08001106 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301107}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001108
Gamze Abaka7650be62021-02-26 10:50:36 +00001109func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1110
1111 intfID := flowContext.intfID
1112 onuID := flowContext.onuID
1113 uniID := flowContext.uniID
1114 logicalFlow := flowContext.logicalFlow
1115 classifier := flowContext.classifier
1116 action := flowContext.action
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301117
Neha Sharma96b7bf22020-06-15 10:37:32 +00001118 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301119 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301120 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001121 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301122 "action": action,
1123 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001124 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301125 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301126
1127 // Clear the action map
1128 for k := range action {
1129 delete(action, k)
1130 }
1131
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001132 action[TrapToHost] = true
1133 classifier[UDPSrc] = uint32(68)
1134 classifier[UDPDst] = uint32(67)
1135 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301136
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001137 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001138 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301139 log.Fields{
1140 "device-id": f.deviceHandler.device.Id,
1141 "intf-id": intfID,
1142 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001143 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301144 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301145
Neha Sharma96b7bf22020-06-15 10:37:32 +00001146 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301147 log.Fields{
1148 "ul_classifier": classifier,
1149 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001150 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301151 "intf-id": intfID,
1152 "onu-id": onuID,
1153 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301154
David K. Bainbridge794735f2020-02-11 21:01:37 -08001155 classifierProto, err := makeOpenOltClassifierField(classifier)
1156 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301157 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301158 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001159 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001160 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001161 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301162 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301163 }
1164
David K. Bainbridge794735f2020-02-11 21:01:37 -08001165 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001166 OnuId: int32(onuID),
1167 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001168 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001169 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001170 AllocId: int32(flowContext.allocID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001171 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001172 GemportId: int32(flowContext.gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301173 Classifier: classifierProto,
1174 Action: actionProto,
1175 Priority: int32(logicalFlow.Priority),
1176 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001177 PortNo: flowContext.portNo,
1178 TechProfileId: flowContext.tpID,
1179 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1180 PbitToGemport: flowContext.pbitToGem,
1181 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001182 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001183 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001184 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001185 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001186 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301187 log.Fields{
1188 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001189 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301190 "intf-id": intfID,
1191 "onu-id": onuID})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301192
David K. Bainbridge794735f2020-02-11 21:01:37 -08001193 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301194}
1195
Esin Karamanae41e2b2019-12-17 18:13:13 +00001196//addIGMPTrapFlow creates IGMP trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001197func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1198 delete(flowContext.classifier, VlanVid)
1199 return f.addUpstreamTrapFlow(ctx, flowContext)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001200}
1201
1202//addUpstreamTrapFlow creates a trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001203func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, flowContext *flowContext) error {
1204
1205 intfID := flowContext.intfID
1206 onuID := flowContext.onuID
1207 uniID := flowContext.uniID
1208 logicalFlow := flowContext.logicalFlow
1209 classifier := flowContext.classifier
1210 action := flowContext.action
Esin Karamanae41e2b2019-12-17 18:13:13 +00001211
Neha Sharma96b7bf22020-06-15 10:37:32 +00001212 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001213 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301214 return olterrors.NewErrNotFound("nni-interface-id",
1215 log.Fields{
1216 "classifier": classifier,
1217 "action": action,
1218 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001219 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001220 }
1221
1222 // Clear the action map
1223 for k := range action {
1224 delete(action, k)
1225 }
1226
1227 action[TrapToHost] = true
1228 classifier[PacketTagType] = SingleTag
Esin Karamanae41e2b2019-12-17 18:13:13 +00001229
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001230 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001231 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001232 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001233 }
1234
Neha Sharma96b7bf22020-06-15 10:37:32 +00001235 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301236 log.Fields{
1237 "ul_classifier": classifier,
1238 "ul_action": action,
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})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001243
David K. Bainbridge794735f2020-02-11 21:01:37 -08001244 classifierProto, err := makeOpenOltClassifierField(classifier)
1245 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301246 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001247 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001248 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301249 log.Fields{
1250 "classifier": *classifierProto,
1251 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001252 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001253 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301254 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001255 }
1256
David K. Bainbridge794735f2020-02-11 21:01:37 -08001257 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001258 OnuId: int32(onuID),
1259 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001260 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001261 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001262 AllocId: int32(flowContext.allocID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001263 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001264 GemportId: int32(flowContext.gemPortID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001265 Classifier: classifierProto,
1266 Action: actionProto,
1267 Priority: int32(logicalFlow.Priority),
1268 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001269 PortNo: flowContext.portNo,
1270 TechProfileId: flowContext.tpID,
1271 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1272 PbitToGemport: flowContext.pbitToGem,
1273 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001274 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001275
David K. Bainbridge794735f2020-02-11 21:01:37 -08001276 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001277 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 -08001278 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001279
David K. Bainbridge794735f2020-02-11 21:01:37 -08001280 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001281}
1282
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001283// Add EthType flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka7650be62021-02-26 10:50:36 +00001284func (f *OpenOltFlowMgr) addEthTypeBasedFlow(ctx context.Context, flowContext *flowContext, vlanID uint32, ethType uint32) error {
1285 intfID := flowContext.intfID
1286 onuID := flowContext.onuID
1287 uniID := flowContext.uniID
1288 portNo := flowContext.portNo
1289 allocID := flowContext.allocID
1290 gemPortID := flowContext.gemPortID
1291 logicalFlow := flowContext.logicalFlow
1292 classifier := flowContext.classifier
1293 action := flowContext.action
1294
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001295 logger.Infow(ctx, "adding-ethType-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301296 log.Fields{
1297 "intf-id": intfID,
1298 "onu-id": onuID,
1299 "port-no": portNo,
1300 "alloc-id": allocID,
1301 "gemport-id": gemPortID,
1302 "vlan-id": vlanID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001303 "flow": logicalFlow,
1304 "ethType": ethType})
manikkaraj kbf256be2019-03-25 00:13:48 +05301305
1306 uplinkClassifier := make(map[string]interface{})
1307 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301308
manikkaraj kbf256be2019-03-25 00:13:48 +05301309 // Fill Classfier
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001310 uplinkClassifier[EthType] = ethType
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001311 uplinkClassifier[PacketTagType] = SingleTag
1312 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001313 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301314 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001315 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001316 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001317 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301318 "device-id": f.deviceHandler.device.Id,
1319 "onu-id": onuID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001320 "intf-id": intfID,
1321 "ethType": ethType})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001322 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301323 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001324 //Add Uplink EthType Flow
1325 logger.Debugw(ctx, "creating-ul-ethType-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301326 log.Fields{
1327 "ul_classifier": uplinkClassifier,
1328 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001329 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301330 "device-id": f.deviceHandler.device.Id,
1331 "intf-id": intfID,
1332 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301333
David K. Bainbridge794735f2020-02-11 21:01:37 -08001334 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1335 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301336 return olterrors.NewErrInvalidValue(log.Fields{
1337 "classifier": uplinkClassifier,
1338 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301339 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001340 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301341 log.Fields{
1342 "classifier": *classifierProto,
1343 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001344 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001345 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301346 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301347 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001348 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301349 log.Fields{
1350 "action": *actionProto,
1351 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001352 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301353 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301354 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001355 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301356 "action": action,
1357 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001358 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301359 }
1360
David K. Bainbridge794735f2020-02-11 21:01:37 -08001361 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001362 OnuId: int32(onuID),
1363 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001364 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001365 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001366 AllocId: int32(allocID),
1367 NetworkIntfId: int32(networkIntfID),
1368 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301369 Classifier: classifierProto,
1370 Action: actionProto,
1371 Priority: int32(logicalFlow.Priority),
1372 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001373 PortNo: portNo,
Gamze Abaka7650be62021-02-26 10:50:36 +00001374 TechProfileId: flowContext.tpID,
1375 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1376 PbitToGemport: flowContext.pbitToGem,
1377 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001378 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001379 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001380 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001381 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001382 logger.Infow(ctx, "ethType-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301383 log.Fields{
1384 "device-id": f.deviceHandler.device.Id,
1385 "onu-id": onuID,
1386 "intf-id": intfID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001387 "ethType": ethType,
Shrey Baid26912972020-04-16 21:02:31 +05301388 })
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001389
David K. Bainbridge794735f2020-02-11 21:01:37 -08001390 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301391}
1392
David K. Bainbridge794735f2020-02-11 21:01:37 -08001393func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001394 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001395
1396 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1397 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1398 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001399 if vlanID != ReservedVlan {
1400 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001401 classifier.OVid = vid
1402 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301403 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001404 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1405 vid := uint32(metadata)
1406 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001407 classifier.IVid = vid
1408 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301409 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301410 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001411 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301412 classifier.OPbits = vlanPcp
1413 } else {
1414 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301415 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001416 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1417 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1418 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1419 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001420 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001421 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1422 classifier.PktTagType = pktTagType
1423
1424 switch pktTagType {
1425 case SingleTag:
1426 case DoubleTag:
1427 case Untagged:
1428 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001429 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301430 }
1431 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001432 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301433}
1434
Gamze Abaka724d0852020-03-18 12:10:24 +00001435func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001436 var actionCmd openoltpb2.ActionCmd
1437 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301438 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001439 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301440 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001441 if _, ok := actionInfo[VlanPcp]; ok {
1442 action.Cmd.RemarkInnerPbits = true
1443 action.IPbits = actionInfo[VlanPcp].(uint32)
1444 if _, ok := actionInfo[VlanVid]; ok {
1445 action.Cmd.TranslateInnerTag = true
1446 action.IVid = actionInfo[VlanVid].(uint32)
1447 }
1448 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001449 } else if _, ok := actionInfo[PushVlan]; ok {
1450 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301451 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001452 if _, ok := actionInfo[VlanPcp]; ok {
1453 action.OPbits = actionInfo[VlanPcp].(uint32)
1454 action.Cmd.RemarkOuterPbits = true
1455 if _, ok := classifierInfo[VlanVid]; ok {
1456 action.IVid = classifierInfo[VlanVid].(uint32)
1457 action.Cmd.TranslateInnerTag = true
1458 }
1459 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001460 } else if _, ok := actionInfo[TrapToHost]; ok {
1461 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301462 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001463 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301464 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001465 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301466}
1467
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001468// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001469func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001470 return f.techprofile.GetTechProfileInstanceKey(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301471}
1472
Gamze Abakafee36392019-10-03 11:17:24 +00001473// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdra37f13fa2021-08-16 10:59:45 -07001474// We also force release scheduler and queues associated with the tp instance. Theoretically there could be
1475// an issue if the upstream scheduler (DBA) is shared across multiple UNI and we force release it, given that
1476// this function is only meant to clean up TP instances of a given UNI. But in practicality this routine
1477// is only meant to be called when the clean up of resource for the whole ONU is taking place.
1478// The reason for introducing the force cleanup of scheduler and queues (on the OLT) was introduced here
1479// because it was observed that if the ONU device was deleted too soon after the flows were
1480// unprovisioned on that ONU, the scheduler and queue removal pertinent to that ONU would remain
1481// uncleaned on the OLT. So we force clean up here and ignore any error that OLT returns during the
1482// force cleanup (possible if the OLT has already cleared those resources).
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001483func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301484 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001485 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1486
Gamze Abakafee36392019-10-03 11:17:24 +00001487 for _, tpID := range tpIDList {
Girish Gowdra37f13fa2021-08-16 10:59:45 -07001488
1489 // Force cleanup scheduler/queues -- start
1490 uniPortNum := MkUniPortNum(ctx, intfID, onuID, uniID)
1491 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1492 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
1493 tpInst, err := f.techprofile.GetTPInstance(ctx, tpPath)
1494 if err != nil || tpInst == nil { // This should not happen, something wrong in KV backend transaction
1495 logger.Warnw(ctx, "tech-profile-not-in-kv-store",
1496 log.Fields{
1497 "tp-id": tpID,
1498 "path": tpPath})
1499 }
1500 switch tpInstance := tpInst.(type) {
1501 case *tp_pb.TechProfileInstance:
1502 f.forceRemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: tpID, uniPort: uniPortNum, tpInst: tpInstance})
1503 f.forceRemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: tpID, uniPort: uniPortNum, tpInst: tpInstance})
1504 }
1505 // Force cleanup scheduler/queues -- end
1506
1507 // Now remove the tp instance
npujarec5762e2020-01-01 14:08:48 +05301508 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001509 logger.Errorw(ctx, "delete-tech-profile-failed", log.Fields{"err": err, "device-id": f.deviceHandler.device.Id})
Girish Gowdra54934262019-11-13 14:19:55 +05301510 // return err
1511 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001512 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001513 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 +00001514 }
1515 return nil
1516}
1517
1518// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301519func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001520 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001521 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001522 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001523 if err := f.techprofile.DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301524 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1525 log.Fields{
1526 "tp-id": tpID,
1527 "uni-port-name": uniPortName,
1528 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001529 }
1530 return nil
1531}
1532
David K. Bainbridge794735f2020-02-11 21:01:37 -08001533func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001534
1535 var intfID uint32
1536 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1537 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1538 */
1539 if deviceFlow.AccessIntfId != -1 {
1540 intfID = uint32(deviceFlow.AccessIntfId)
1541 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001542 // We need to log the valid interface ID.
1543 // 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 +00001544 intfID = uint32(deviceFlow.NetworkIntfId)
1545 }
1546
Neha Sharma96b7bf22020-06-15 10:37:32 +00001547 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301548 "flow": *deviceFlow,
1549 "device-id": f.deviceHandler.device.Id,
1550 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001551 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001552
1553 st, _ := status.FromError(err)
1554 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001555 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001556 "err": err,
1557 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301558 "device-id": f.deviceHandler.device.Id,
1559 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001560 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301561 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001562
1563 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001564 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301565 log.Fields{"err": err,
1566 "device-flow": deviceFlow,
1567 "device-id": f.deviceHandler.device.Id,
1568 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001569 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001570 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001571 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301572 log.Fields{
1573 "flow": *deviceFlow,
1574 "device-id": f.deviceHandler.device.Id,
1575 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001576
1577 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1578 if deviceFlow.AccessIntfId != -1 {
1579 // No need to register the flow if it is a trap on nni flow.
1580 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1581 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1582 return err
1583 }
1584 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001585 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001586}
1587
Neha Sharma96b7bf22020-06-15 10:37:32 +00001588func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1589 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301590 log.Fields{
1591 "flow": *deviceFlow,
1592 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001593 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001594 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001595 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001596 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301597 log.Fields{
1598 "err": err,
1599 "deviceFlow": deviceFlow,
1600 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001601 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001602 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001603 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001604 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001605
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001606 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001607 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001608 "of-flow-id": ofFlowID,
1609 "flow": *deviceFlow,
1610 "device-id": f.deviceHandler.device.Id,
1611 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001612 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301613}
1614
David K. Bainbridge794735f2020-02-11 21:01:37 -08001615func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001616
1617 classifierInfo := make(map[string]interface{})
1618 actionInfo := make(map[string]interface{})
1619
1620 classifierInfo[EthType] = uint32(LldpEthType)
1621 classifierInfo[PacketTagType] = Untagged
1622 actionInfo[TrapToHost] = true
1623
1624 // LLDP flow is installed to trap LLDP packets on the NNI port.
1625 // We manage flow_id resource pool on per PON port basis.
1626 // Since this situation is tricky, as a hack, we pass the NNI port
1627 // index (network_intf_id) as PON port Index for the flow_id resource
1628 // pool. Also, there is no ONU Id available for trapping LLDP packets
1629 // on NNI port, use onu_id as -1 (invalid)
1630 // ****************** CAVEAT *******************
1631 // This logic works if the NNI Port Id falls within the same valid
1632 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1633 // we need to have a re-look at this.
1634 // *********************************************
1635
1636 var onuID = -1
1637 var uniID = -1
1638 var gemPortID = -1
1639
Neha Sharma96b7bf22020-06-15 10:37:32 +00001640 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001641 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301642 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001643 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001644 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001645 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001646 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001647 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001648
David K. Bainbridge794735f2020-02-11 21:01:37 -08001649 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1650 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301651 return olterrors.NewErrInvalidValue(
1652 log.Fields{
1653 "classifier": classifierInfo,
1654 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001655 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001656 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301657 log.Fields{
1658 "classifier": *classifierProto,
1659 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001660 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001661 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301662 return olterrors.NewErrInvalidValue(
1663 log.Fields{
1664 "action": actionInfo,
1665 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001666 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001667 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301668 log.Fields{
1669 "action": *actionProto,
1670 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001671
1672 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1673 OnuId: int32(onuID), // OnuId not required
1674 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001675 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001676 FlowType: Downstream,
1677 NetworkIntfId: int32(networkInterfaceID),
1678 GemportId: int32(gemPortID),
1679 Classifier: classifierProto,
1680 Action: actionProto,
1681 Priority: int32(flow.Priority),
1682 Cookie: flow.Cookie,
1683 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001684 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001685 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301686 log.Fields{
1687 "flow": downstreamflow,
1688 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001689 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001690 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301691 log.Fields{
1692 "device-id": f.deviceHandler.device.Id,
1693 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001694 "flow-id": flow.Id})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001695
David K. Bainbridge794735f2020-02-11 21:01:37 -08001696 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301697}
1698
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001699func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1700 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001701}
1702
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001703//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001704func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001705 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1706 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1707 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001708 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301709 log.Fields{
1710 "intf-id": intfID,
1711 "onu-id": onuID,
1712 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001713 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001714 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301715 return nil, olterrors.NewErrNotFound("onu-child-device",
1716 log.Fields{
1717 "onu-id": onuID,
1718 "intf-id": intfID,
1719 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001720 }
1721 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1722 //better to ad the device to cache here.
1723 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1724 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001725 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301726 log.Fields{
1727 "intf-id": intfID,
1728 "onu-id": onuID,
1729 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001730 }
1731
1732 return onuDev.(*OnuDevice), nil
1733}
1734
1735//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001736func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1737 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301738 log.Fields{
1739 "pon-port": intfID,
1740 "onu-id": onuID,
1741 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001742 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001743 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001744 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301745 return nil, olterrors.NewErrNotFound("onu",
1746 log.Fields{
1747 "interface-id": parentPortNo,
1748 "onu-id": onuID,
1749 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001750 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301751 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001752 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301753 log.Fields{
1754 "device-id": f.deviceHandler.device.Id,
1755 "child_device_id": onuDevice.Id,
1756 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301757 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301758}
1759
Neha Sharma96b7bf22020-06-15 10:37:32 +00001760func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1761 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301762 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001763 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301764 log.Fields{
1765 "intf-id": intfID,
1766 "onu-id": onuID,
1767 "uni-id": uniID,
1768 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001769 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301770 }
1771
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001772 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpInstancePath: tpPath, GemPortId: gemPortID}
1773 logger.Infow(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301774 log.Fields{
1775 "msg": *delGemPortMsg,
1776 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001777 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301778 delGemPortMsg,
1779 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001780 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001781 onuDev.deviceType,
1782 onuDev.deviceID,
1783 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301784 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1785 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001786 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301787 "to-adapter": onuDev.deviceType,
1788 "onu-id": onuDev.deviceID,
1789 "proxyDeviceID": onuDev.proxyDeviceID,
1790 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301791 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001792 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301793 log.Fields{
1794 "msg": delGemPortMsg,
1795 "from-adapter": f.deviceHandler.device.Type,
1796 "to-adapter": onuDev.deviceType,
1797 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301798 return nil
1799}
1800
Neha Sharma96b7bf22020-06-15 10:37:32 +00001801func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1802 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301803 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001804 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301805 log.Fields{
1806 "intf-id": intfID,
1807 "onu-id": onuID,
1808 "uni-id": uniID,
1809 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001810 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301811 }
1812
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001813 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpInstancePath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001814 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301815 log.Fields{
1816 "msg": *delTcontMsg,
1817 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001818 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301819 delTcontMsg,
1820 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001821 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001822 onuDev.deviceType,
1823 onuDev.deviceID,
1824 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301825 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1826 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001827 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301828 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1829 "proxyDeviceID": onuDev.proxyDeviceID,
1830 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301831 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001832 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301833 log.Fields{
1834 "msg": delTcontMsg,
1835 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301836 return nil
1837}
1838
Girish Gowdrac3037402020-01-22 20:29:53 +05301839// Once the gemport is released for a given onu, it also has to be cleared from local cache
1840// which was used for deriving the gemport->logicalPortNo during packet-in.
1841// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1842// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001843func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001844 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301845 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001846 "gem-port-id": gemPortID,
1847 "intf-id": intfID,
1848 "onu-id": onuID,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001849 "device-id": f.deviceHandler.device.Id})
1850 f.onuGemInfoLock.RLock()
1851 onugem, ok := f.onuGemInfoMap[onuID]
1852 f.onuGemInfoLock.RUnlock()
1853 if !ok {
1854 logger.Warnw(ctx, "onu gem info already cleared from cache", log.Fields{
1855 "gem-port-id": gemPortID,
1856 "intf-id": intfID,
1857 "onu-id": onuID,
1858 "device-id": f.deviceHandler.device.Id})
1859 return
1860 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001861deleteLoop:
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001862 for j, gem := range onugem.GemPorts {
1863 // If the gemport is found, delete it from local cache.
1864 if gem == gemPortID {
1865 onugem.GemPorts = append(onugem.GemPorts[:j], onugem.GemPorts[j+1:]...)
1866 f.onuGemInfoLock.Lock()
1867 f.onuGemInfoMap[onuID] = onugem
1868 f.onuGemInfoLock.Unlock()
1869 logger.Infow(ctx, "removed-gemport-from-local-cache",
1870 log.Fields{
1871 "intf-id": intfID,
1872 "onu-id": onuID,
1873 "deletedgemport-id": gemPortID,
1874 "gemports": onugem.GemPorts,
1875 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001876 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301877 }
1878 }
1879}
1880
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301881//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001882// nolint: gocyclo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001883func (f *OpenOltFlowMgr) clearResources(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdra82c80982021-03-26 16:22:02 -07001884 gemPortID int32, flowID uint64, portNum uint32, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001885
Girish Gowdraa482f272021-03-24 23:04:19 -07001886 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, onuID, uniID)
1887 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001888 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1889 log.Fields{
1890 "tpPath": tpPath,
1891 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001892
1893 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1894
1895 if used {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001896 f.gemToFlowIDsKey.RLock()
1897 flowIDs := f.gemToFlowIDs[uint32(gemPortID)]
1898 f.gemToFlowIDsKey.RUnlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001899
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001900 for i, flowIDinMap := range flowIDs {
1901 if flowIDinMap == flowID {
1902 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001903 f.gemToFlowIDsKey.Lock()
1904 f.gemToFlowIDs[uint32(gemPortID)] = flowIDs
1905 f.gemToFlowIDsKey.Unlock()
1906 // everytime gemToFlowIDs cache is updated the same should be updated
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001907 // in kv store by calling UpdateFlowIDsForGem
Girish Gowdraa482f272021-03-24 23:04:19 -07001908 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, intfID, uint32(gemPortID), flowIDs); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001909 return err
1910 }
1911 break
1912 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001913 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001914 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1915 log.Fields{
1916 "gemport-id": gemPortID,
1917 "usedByFlows": flowIDs,
1918 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -07001919
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001920 return nil
1921 }
1922 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 -07001923 f.deleteGemPortFromLocalCache(ctx, intfID, uint32(onuID), uint32(gemPortID))
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001924 _ = f.resourceMgr.RemoveGemFromOnuGemInfo(ctx, intfID, uint32(onuID), uint32(gemPortID)) // ignore error and proceed.
1925 //everytime an entry is deleted from gemToFlowIDs cache, the same should be updated in kv as well
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001926 // by calling DeleteFlowIDsForGem
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001927 f.gemToFlowIDsKey.Lock()
1928 delete(f.gemToFlowIDs, uint32(gemPortID))
1929 f.gemToFlowIDsKey.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001930
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001931 f.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, uint32(gemPortID))
1932
1933 f.resourceMgr.FreeGemPortID(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001934
Mahir Gunyel1d20eff2021-07-04 15:39:36 -07001935 //First remove TCONT from child if needed. Then remove the GEM.
1936 //It is expected from child to clean ani side conf if all GEMs of TP are deleted.
1937 //Before this, ensure that the related TCONT deletions are informed to child.
1938 //Refer to VOL-4215.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001939 techprofileInst, err := f.techprofile.GetTPInstance(ctx, tpPath)
1940 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1941 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1942 log.Fields{
1943 "tp-id": tpID,
1944 "path": tpPath}, err)
1945 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001946 switch techprofileInst := techprofileInst.(type) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001947 case *tp_pb.TechProfileInstance:
Gamze Abakacb0e6772021-06-10 08:32:12 +00001948 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, intfID, uint32(onuID), uint32(uniID), techprofileInst, uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -0700