blob: 61367984f0fd032b7205111f3d5664c98d9aa717 [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 Gunyel199570a2021-07-04 15:39:36 -070030 "github.com/opencord/voltha-lib-go/v6/pkg/meters"
31
Girish Gowdra4c3d4602021-07-22 16:33:37 -070032 "github.com/opencord/voltha-lib-go/v6/pkg/flows"
33 "github.com/opencord/voltha-lib-go/v6/pkg/log"
34 tp "github.com/opencord/voltha-lib-go/v6/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.
259 onugem, err := rMgr.GetOnuGemInfo(ctx, onuID, ponPortIdx)
260 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 Gowdra197acc12021-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 Gowdra4c3d4602021-07-22 16:33:37 -0700944 var err error
945 f.techprofile, err = tp.NewTechProfile(ctx, f.resourceMgr.PonRsrMgr, f.resourceMgr.PonRsrMgr.Backend,
946 f.resourceMgr.PonRsrMgr.Address, f.deviceHandler.cm.Backend.PathPrefix)
947 if err != nil || f.techprofile == nil {
948 logger.Errorw(ctx, "failed-to-allocate-to-techprofile-for-pon-port", log.Fields{"intfID": intfID, "err": err})
949 return fmt.Errorf("failed-to-allocate-tech-profile-for-pon-port--pon-%v-err-%v", intfID, err)
950 }
Manikkaraj kb1d51442019-07-23 10:41:02 -0400951 tpCount++
Neha Sharma96b7bf22020-06-15 10:37:32 +0000952 logger.Debugw(ctx, "init-tech-profile-done",
Shrey Baid26912972020-04-16 21:02:31 +0530953 log.Fields{
954 "intf-id": intfID,
955 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530956 }
957 }
958 //Make sure we have as many tech_profiles as there are pon ports on the device
Manikkaraj kb1d51442019-07-23 10:41:02 -0400959 if tpCount != int(f.resourceMgr.DevInfo.GetPonPorts()) {
Thomas Lee S94109f12020-03-03 16:39:29 +0530960 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +0530961 "reason": "tP-count-does-not-match-number-of-pon-ports",
David K. Bainbridge794735f2020-02-11 21:01:37 -0800962 "tech-profile-count": tpCount,
Shrey Baid26912972020-04-16 21:02:31 +0530963 "pon-port-count": f.resourceMgr.DevInfo.GetPonPorts(),
964 "device-id": f.deviceHandler.device.Id}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +0530965 }
Neha Sharma96b7bf22020-06-15 10:37:32 +0000966 logger.Infow(ctx, "populated-techprofile-for-ponports-successfully",
Shrey Baid26912972020-04-16 21:02:31 +0530967 log.Fields{
968 "numofTech": tpCount,
969 "numPonPorts": f.resourceMgr.DevInfo.GetPonPorts(),
970 "device-id": f.deviceHandler.device.Id})
manikkaraj kbf256be2019-03-25 00:13:48 +0530971 return nil
972}
973
Gamze Abaka7650be62021-02-26 10:50:36 +0000974func (f *OpenOltFlowMgr) addUpstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
975 flowContext.classifier[PacketTagType] = SingleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000976 logger.Debugw(ctx, "adding-upstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530977 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +0000978 "uplinkClassifier": flowContext.classifier,
979 "uplinkAction": flowContext.action})
980 return f.addSymmetricDataPathFlow(ctx, flowContext, Upstream)
Manikkaraj k884c1242019-04-11 16:26:42 +0530981 /* TODO: Install Secondary EAP on the subscriber vlan */
manikkaraj kbf256be2019-03-25 00:13:48 +0530982}
983
Gamze Abaka7650be62021-02-26 10:50:36 +0000984func (f *OpenOltFlowMgr) addDownstreamDataPathFlow(ctx context.Context, flowContext *flowContext) error {
985 downlinkClassifier := flowContext.classifier
986 downlinkAction := flowContext.action
987
Girish Gowdru6a80bbd2019-07-02 07:36:09 -0700988 downlinkClassifier[PacketTagType] = DoubleTag
Neha Sharma96b7bf22020-06-15 10:37:32 +0000989 logger.Debugw(ctx, "adding-downstream-data-flow",
Shrey Baid26912972020-04-16 21:02:31 +0530990 log.Fields{
991 "downlinkClassifier": downlinkClassifier,
992 "downlinkAction": downlinkAction})
Manikkaraj kb1d51442019-07-23 10:41:02 -0400993 // Ignore Downlink trap flow given by core, cannot do anything with this flow */
994 if vlan, exists := downlinkClassifier[VlanVid]; exists {
995 if vlan.(uint32) == (uint32(ofp.OfpVlanId_OFPVID_PRESENT) | 4000) { //private VLAN given by core
David K. Bainbridge82efc492019-09-04 09:57:11 -0700996 if metadata, exists := downlinkClassifier[Metadata]; exists { // inport is filled in metadata by core
Gamze Abaka7650be62021-02-26 10:50:36 +0000997 if uint32(metadata.(uint64)) == MkUniPortNum(ctx, flowContext.intfID, flowContext.onuID, flowContext.uniID) {
Neha Sharma96b7bf22020-06-15 10:37:32 +0000998 logger.Infow(ctx, "ignoring-dl-trap-device-flow-from-core",
Shrey Baid26912972020-04-16 21:02:31 +0530999 log.Fields{
Gamze Abaka7650be62021-02-26 10:50:36 +00001000 "flow": flowContext.logicalFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301001 "device-id": f.deviceHandler.device.Id,
Gamze Abaka7650be62021-02-26 10:50:36 +00001002 "onu-id": flowContext.onuID,
1003 "intf-id": flowContext.intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001004 return nil
Manikkaraj kb1d51442019-07-23 10:41:02 -04001005 }
1006 }
1007 }
Manikkaraj k884c1242019-04-11 16:26:42 +05301008 }
Manikkaraj kb1d51442019-07-23 10:41:02 -04001009
Manikkaraj k884c1242019-04-11 16:26:42 +05301010 /* Already this info available classifier? */
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001011 downlinkAction[PopVlan] = true
Matt Jeannereted16b7c2019-11-01 13:31:35 -04001012 // vlan_vid is a uint32. must be type asserted as such or conversion fails
1013 dlClVid, ok := downlinkClassifier[VlanVid].(uint32)
Girish Gowdra26f344b2019-10-23 14:39:13 +05301014 if ok {
1015 downlinkAction[VlanVid] = dlClVid & 0xfff
1016 } else {
Thomas Lee S94109f12020-03-03 16:39:29 +05301017 return olterrors.NewErrInvalidValue(log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301018 "reason": "failed-to-convert-vlanid-classifier",
1019 "vlan-id": VlanVid,
1020 "device-id": f.deviceHandler.device.Id}, nil).Log()
Girish Gowdra26f344b2019-10-23 14:39:13 +05301021 }
1022
Gamze Abaka7650be62021-02-26 10:50:36 +00001023 return f.addSymmetricDataPathFlow(ctx, flowContext, Downstream)
manikkaraj kbf256be2019-03-25 00:13:48 +05301024}
1025
Gamze Abaka7650be62021-02-26 10:50:36 +00001026func (f *OpenOltFlowMgr) addSymmetricDataPathFlow(ctx context.Context, flowContext *flowContext, direction string) error {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001027
Gamze Abaka7650be62021-02-26 10:50:36 +00001028 intfID := flowContext.intfID
1029 onuID := flowContext.onuID
1030 uniID := flowContext.uniID
1031 classifier := flowContext.classifier
1032 action := flowContext.action
1033 allocID := flowContext.allocID
1034 gemPortID := flowContext.gemPortID
1035 tpID := flowContext.tpID
1036 logicalFlow := flowContext.logicalFlow
Neha Sharma96b7bf22020-06-15 10:37:32 +00001037 logger.Infow(ctx, "adding-hsia-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301038 log.Fields{
1039 "intf-id": intfID,
1040 "onu-id": onuID,
1041 "uni-id": uniID,
1042 "device-id": f.deviceHandler.device.Id,
1043 "classifier": classifier,
1044 "action": action,
1045 "direction": direction,
1046 "alloc-id": allocID,
1047 "gemport-id": gemPortID,
1048 "logicalflow": *logicalFlow})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001049
1050 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001051 logger.Infow(ctx, "flow-already-exists",
Shrey Baid26912972020-04-16 21:02:31 +05301052 log.Fields{
1053 "device-id": f.deviceHandler.device.Id,
1054 "intf-id": intfID,
1055 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001056 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301057 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001058 classifierProto, err := makeOpenOltClassifierField(classifier)
1059 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301060 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301061 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001062 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301063 log.Fields{
1064 "classifier": *classifierProto,
1065 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001066 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001067 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301068 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301069 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001070 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301071 log.Fields{
1072 "action": *actionProto,
1073 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001074 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301075 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301076 return olterrors.NewErrNotFound("nni-interface-id",
David K. Bainbridge794735f2020-02-11 21:01:37 -08001077 log.Fields{
1078 "classifier": classifier,
1079 "action": action,
Shrey Baid26912972020-04-16 21:02:31 +05301080 "device-id": f.deviceHandler.device.Id,
David K. Bainbridge794735f2020-02-11 21:01:37 -08001081 }, err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301082 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001083
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001084 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001085 OnuId: int32(onuID),
1086 UniId: int32(uniID),
1087 FlowId: logicalFlow.Id,
1088 FlowType: direction,
1089 AllocId: int32(allocID),
1090 NetworkIntfId: int32(networkIntfID),
1091 GemportId: int32(gemPortID),
1092 Classifier: classifierProto,
1093 Action: actionProto,
1094 Priority: int32(logicalFlow.Priority),
1095 Cookie: logicalFlow.Cookie,
1096 PortNo: flowContext.portNo,
1097 TechProfileId: tpID,
1098 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1099 PbitToGemport: flowContext.pbitToGem,
1100 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001101 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001102 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001103 return olterrors.NewErrFlowOp("add", logicalFlow.Id, nil, err).Log()
Manikkaraj k884c1242019-04-11 16:26:42 +05301104 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001105 logger.Infow(ctx, "hsia-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301106 log.Fields{"direction": direction,
1107 "device-id": f.deviceHandler.device.Id,
1108 "flow": flow,
1109 "intf-id": intfID,
1110 "onu-id": onuID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001111
David K. Bainbridge794735f2020-02-11 21:01:37 -08001112 return nil
Manikkaraj k884c1242019-04-11 16:26:42 +05301113}
Esin Karamanae41e2b2019-12-17 18:13:13 +00001114
Gamze Abaka7650be62021-02-26 10:50:36 +00001115func (f *OpenOltFlowMgr) addDHCPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1116
1117 intfID := flowContext.intfID
1118 onuID := flowContext.onuID
1119 uniID := flowContext.uniID
1120 logicalFlow := flowContext.logicalFlow
1121 classifier := flowContext.classifier
1122 action := flowContext.action
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301123
Neha Sharma96b7bf22020-06-15 10:37:32 +00001124 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301125 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301126 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001127 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301128 "action": action,
1129 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001130 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301131 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301132
1133 // Clear the action map
1134 for k := range action {
1135 delete(action, k)
1136 }
1137
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001138 action[TrapToHost] = true
1139 classifier[UDPSrc] = uint32(68)
1140 classifier[UDPDst] = uint32(67)
1141 classifier[PacketTagType] = SingleTag
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301142
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001143 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001144 logger.Infow(ctx, "flow-exists--not-re-adding",
Shrey Baid26912972020-04-16 21:02:31 +05301145 log.Fields{
1146 "device-id": f.deviceHandler.device.Id,
1147 "intf-id": intfID,
1148 "onu-id": onuID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001149 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301150 }
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301151
Neha Sharma96b7bf22020-06-15 10:37:32 +00001152 logger.Debugw(ctx, "creating-ul-dhcp-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301153 log.Fields{
1154 "ul_classifier": classifier,
1155 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001156 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301157 "intf-id": intfID,
1158 "onu-id": onuID,
1159 "device-id": f.deviceHandler.device.Id})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301160
David K. Bainbridge794735f2020-02-11 21:01:37 -08001161 classifierProto, err := makeOpenOltClassifierField(classifier)
1162 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301163 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301164 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001165 logger.Debugw(ctx, "created-classifier-proto", log.Fields{"classifier": *classifierProto})
Gamze Abaka724d0852020-03-18 12:10:24 +00001166 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001167 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301168 return olterrors.NewErrInvalidValue(log.Fields{"action": action}, err).Log()
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301169 }
1170
David K. Bainbridge794735f2020-02-11 21:01:37 -08001171 dhcpFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001172 OnuId: int32(onuID),
1173 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001174 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001175 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001176 AllocId: int32(flowContext.allocID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001177 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001178 GemportId: int32(flowContext.gemPortID),
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301179 Classifier: classifierProto,
1180 Action: actionProto,
1181 Priority: int32(logicalFlow.Priority),
1182 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001183 PortNo: flowContext.portNo,
1184 TechProfileId: flowContext.tpID,
1185 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1186 PbitToGemport: flowContext.pbitToGem,
1187 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001188 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001189 if err := f.addFlowToDevice(ctx, logicalFlow, &dhcpFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001190 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"dhcp-flow": dhcpFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001191 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001192 logger.Infow(ctx, "dhcp-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301193 log.Fields{
1194 "device-id": f.deviceHandler.device.Id,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001195 "flow-id": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301196 "intf-id": intfID,
1197 "onu-id": onuID})
Manjunath Vanarajuluadc57d12019-04-23 11:07:21 +05301198
David K. Bainbridge794735f2020-02-11 21:01:37 -08001199 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301200}
1201
Esin Karamanae41e2b2019-12-17 18:13:13 +00001202//addIGMPTrapFlow creates IGMP trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001203func (f *OpenOltFlowMgr) addIGMPTrapFlow(ctx context.Context, flowContext *flowContext) error {
1204 delete(flowContext.classifier, VlanVid)
1205 return f.addUpstreamTrapFlow(ctx, flowContext)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001206}
1207
1208//addUpstreamTrapFlow creates a trap-to-host flow
Gamze Abaka7650be62021-02-26 10:50:36 +00001209func (f *OpenOltFlowMgr) addUpstreamTrapFlow(ctx context.Context, flowContext *flowContext) error {
1210
1211 intfID := flowContext.intfID
1212 onuID := flowContext.onuID
1213 uniID := flowContext.uniID
1214 logicalFlow := flowContext.logicalFlow
1215 classifier := flowContext.classifier
1216 action := flowContext.action
Esin Karamanae41e2b2019-12-17 18:13:13 +00001217
Neha Sharma96b7bf22020-06-15 10:37:32 +00001218 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Esin Karamanae41e2b2019-12-17 18:13:13 +00001219 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301220 return olterrors.NewErrNotFound("nni-interface-id",
1221 log.Fields{
1222 "classifier": classifier,
1223 "action": action,
1224 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001225 err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001226 }
1227
1228 // Clear the action map
1229 for k := range action {
1230 delete(action, k)
1231 }
1232
1233 action[TrapToHost] = true
1234 classifier[PacketTagType] = SingleTag
Esin Karamanae41e2b2019-12-17 18:13:13 +00001235
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001236 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkIntfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001237 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001238 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001239 }
1240
Neha Sharma96b7bf22020-06-15 10:37:32 +00001241 logger.Debugw(ctx, "creating-upstream-trap-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301242 log.Fields{
1243 "ul_classifier": classifier,
1244 "ul_action": action,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001245 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301246 "device-id": f.deviceHandler.device.Id,
1247 "intf-id": intfID,
1248 "onu-id": onuID})
Esin Karamanae41e2b2019-12-17 18:13:13 +00001249
David K. Bainbridge794735f2020-02-11 21:01:37 -08001250 classifierProto, err := makeOpenOltClassifierField(classifier)
1251 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301252 return olterrors.NewErrInvalidValue(log.Fields{"classifier": classifier, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001253 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001254 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301255 log.Fields{
1256 "classifier": *classifierProto,
1257 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001258 actionProto, err := makeOpenOltActionField(action, classifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001259 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301260 return olterrors.NewErrInvalidValue(log.Fields{"action": action, "device-id": f.deviceHandler.device.Id}, err).Log()
Esin Karamanae41e2b2019-12-17 18:13:13 +00001261 }
1262
David K. Bainbridge794735f2020-02-11 21:01:37 -08001263 flow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001264 OnuId: int32(onuID),
1265 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001266 FlowId: logicalFlow.Id,
Esin Karamanae41e2b2019-12-17 18:13:13 +00001267 FlowType: Upstream,
Gamze Abaka7650be62021-02-26 10:50:36 +00001268 AllocId: int32(flowContext.allocID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001269 NetworkIntfId: int32(networkIntfID),
Gamze Abaka7650be62021-02-26 10:50:36 +00001270 GemportId: int32(flowContext.gemPortID),
Esin Karamanae41e2b2019-12-17 18:13:13 +00001271 Classifier: classifierProto,
1272 Action: actionProto,
1273 Priority: int32(logicalFlow.Priority),
1274 Cookie: logicalFlow.Cookie,
Gamze Abaka7650be62021-02-26 10:50:36 +00001275 PortNo: flowContext.portNo,
1276 TechProfileId: flowContext.tpID,
1277 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1278 PbitToGemport: flowContext.pbitToGem,
1279 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001280 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001281
David K. Bainbridge794735f2020-02-11 21:01:37 -08001282 if err := f.addFlowToDevice(ctx, logicalFlow, &flow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001283 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 -08001284 }
Esin Karamanae41e2b2019-12-17 18:13:13 +00001285
David K. Bainbridge794735f2020-02-11 21:01:37 -08001286 return nil
Esin Karamanae41e2b2019-12-17 18:13:13 +00001287}
1288
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001289// Add EthType flow to device with mac, vlanId as classifier for upstream and downstream
Gamze Abaka7650be62021-02-26 10:50:36 +00001290func (f *OpenOltFlowMgr) addEthTypeBasedFlow(ctx context.Context, flowContext *flowContext, vlanID uint32, ethType uint32) error {
1291 intfID := flowContext.intfID
1292 onuID := flowContext.onuID
1293 uniID := flowContext.uniID
1294 portNo := flowContext.portNo
1295 allocID := flowContext.allocID
1296 gemPortID := flowContext.gemPortID
1297 logicalFlow := flowContext.logicalFlow
1298 classifier := flowContext.classifier
1299 action := flowContext.action
1300
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001301 logger.Infow(ctx, "adding-ethType-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301302 log.Fields{
1303 "intf-id": intfID,
1304 "onu-id": onuID,
1305 "port-no": portNo,
1306 "alloc-id": allocID,
1307 "gemport-id": gemPortID,
1308 "vlan-id": vlanID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001309 "flow": logicalFlow,
1310 "ethType": ethType})
manikkaraj kbf256be2019-03-25 00:13:48 +05301311
1312 uplinkClassifier := make(map[string]interface{})
1313 uplinkAction := make(map[string]interface{})
Girish Gowdra3d633032019-12-10 16:37:05 +05301314
manikkaraj kbf256be2019-03-25 00:13:48 +05301315 // Fill Classfier
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001316 uplinkClassifier[EthType] = ethType
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001317 uplinkClassifier[PacketTagType] = SingleTag
1318 uplinkClassifier[VlanVid] = vlanID
Gamze Abaka724d0852020-03-18 12:10:24 +00001319 uplinkClassifier[VlanPcp] = classifier[VlanPcp]
manikkaraj kbf256be2019-03-25 00:13:48 +05301320 // Fill action
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001321 uplinkAction[TrapToHost] = true
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001322 if present := f.resourceMgr.IsFlowOnKvStore(ctx, intfID, int32(onuID), int32(uniID), logicalFlow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001323 logger.Infow(ctx, "flow-exists-not-re-adding", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301324 "device-id": f.deviceHandler.device.Id,
1325 "onu-id": onuID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001326 "intf-id": intfID,
1327 "ethType": ethType})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001328 return nil
Girish Gowdra3d633032019-12-10 16:37:05 +05301329 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001330 //Add Uplink EthType Flow
1331 logger.Debugw(ctx, "creating-ul-ethType-flow",
Shrey Baid26912972020-04-16 21:02:31 +05301332 log.Fields{
1333 "ul_classifier": uplinkClassifier,
1334 "ul_action": uplinkAction,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001335 "uplinkFlowId": logicalFlow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301336 "device-id": f.deviceHandler.device.Id,
1337 "intf-id": intfID,
1338 "onu-id": onuID})
manikkaraj kbf256be2019-03-25 00:13:48 +05301339
David K. Bainbridge794735f2020-02-11 21:01:37 -08001340 classifierProto, err := makeOpenOltClassifierField(uplinkClassifier)
1341 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301342 return olterrors.NewErrInvalidValue(log.Fields{
1343 "classifier": uplinkClassifier,
1344 "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301345 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001346 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301347 log.Fields{
1348 "classifier": *classifierProto,
1349 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001350 actionProto, err := makeOpenOltActionField(uplinkAction, uplinkClassifier)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001351 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301352 return olterrors.NewErrInvalidValue(log.Fields{"action": uplinkAction, "device-id": f.deviceHandler.device.Id}, err).Log()
manikkaraj kbf256be2019-03-25 00:13:48 +05301353 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001354 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301355 log.Fields{
1356 "action": *actionProto,
1357 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001358 networkIntfID, err := getNniIntfID(ctx, classifier, action)
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301359 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301360 return olterrors.NewErrNotFound("nni-interface-id", log.Fields{
David K. Bainbridge794735f2020-02-11 21:01:37 -08001361 "classifier": classifier,
Shrey Baid26912972020-04-16 21:02:31 +05301362 "action": action,
1363 "device-id": f.deviceHandler.device.Id},
David K. Bainbridge794735f2020-02-11 21:01:37 -08001364 err).Log()
Abhilash Laxmeshwarab0bd522019-10-21 15:05:15 +05301365 }
1366
David K. Bainbridge794735f2020-02-11 21:01:37 -08001367 upstreamFlow := openoltpb2.Flow{AccessIntfId: int32(intfID),
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001368 OnuId: int32(onuID),
1369 UniId: int32(uniID),
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001370 FlowId: logicalFlow.Id,
David K. Bainbridge82efc492019-09-04 09:57:11 -07001371 FlowType: Upstream,
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001372 AllocId: int32(allocID),
1373 NetworkIntfId: int32(networkIntfID),
1374 GemportId: int32(gemPortID),
manikkaraj kbf256be2019-03-25 00:13:48 +05301375 Classifier: classifierProto,
1376 Action: actionProto,
1377 Priority: int32(logicalFlow.Priority),
1378 Cookie: logicalFlow.Cookie,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001379 PortNo: portNo,
Gamze Abaka7650be62021-02-26 10:50:36 +00001380 TechProfileId: flowContext.tpID,
1381 ReplicateFlow: len(flowContext.pbitToGem) > 0,
1382 PbitToGemport: flowContext.pbitToGem,
1383 GemportToAes: flowContext.gemToAes,
Gamze Abaka78a1d2a2020-04-27 10:17:27 +00001384 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001385 if err := f.addFlowToDevice(ctx, logicalFlow, &upstreamFlow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001386 return olterrors.NewErrFlowOp("add", logicalFlow.Id, log.Fields{"flow": upstreamFlow}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001387 }
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001388 logger.Infow(ctx, "ethType-ul-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301389 log.Fields{
1390 "device-id": f.deviceHandler.device.Id,
1391 "onu-id": onuID,
1392 "intf-id": intfID,
Marcos Aurelio Carrero (Furukawa)388fb0a2021-02-04 18:05:11 -03001393 "ethType": ethType,
Shrey Baid26912972020-04-16 21:02:31 +05301394 })
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001395
David K. Bainbridge794735f2020-02-11 21:01:37 -08001396 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301397}
1398
David K. Bainbridge794735f2020-02-11 21:01:37 -08001399func makeOpenOltClassifierField(classifierInfo map[string]interface{}) (*openoltpb2.Classifier, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001400 var classifier openoltpb2.Classifier
David K. Bainbridge82efc492019-09-04 09:57:11 -07001401
1402 classifier.EthType, _ = classifierInfo[EthType].(uint32)
1403 classifier.IpProto, _ = classifierInfo[IPProto].(uint32)
1404 if vlanID, ok := classifierInfo[VlanVid].(uint32); ok {
Andrea Campanella7acc0b92020-02-14 09:20:49 +01001405 if vlanID != ReservedVlan {
1406 vid := vlanID & VlanvIDMask
Harsh Awasthiea45af72019-08-26 02:39:00 -04001407 classifier.OVid = vid
1408 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301409 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001410 if metadata, ok := classifierInfo[Metadata].(uint64); ok {
1411 vid := uint32(metadata)
1412 if vid != ReservedVlan {
Harsh Awasthiea45af72019-08-26 02:39:00 -04001413 classifier.IVid = vid
1414 }
manikkaraj kbf256be2019-03-25 00:13:48 +05301415 }
Girish Gowdrafae935c2020-02-17 19:21:44 +05301416 // Use VlanPCPMask (0xff) to signify NO PCP. Else use valid PCP (0 to 7)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001417 if vlanPcp, ok := classifierInfo[VlanPcp].(uint32); ok {
Girish Gowdrafae935c2020-02-17 19:21:44 +05301418 classifier.OPbits = vlanPcp
1419 } else {
1420 classifier.OPbits = VlanPCPMask
manikkaraj kbf256be2019-03-25 00:13:48 +05301421 }
David K. Bainbridge82efc492019-09-04 09:57:11 -07001422 classifier.SrcPort, _ = classifierInfo[UDPSrc].(uint32)
1423 classifier.DstPort, _ = classifierInfo[UDPDst].(uint32)
1424 classifier.DstIp, _ = classifierInfo[Ipv4Dst].(uint32)
1425 classifier.SrcIp, _ = classifierInfo[Ipv4Src].(uint32)
Esin Karamanccb714b2019-11-29 15:02:06 +00001426 classifier.DstMac, _ = classifierInfo[EthDst].([]uint8)
David K. Bainbridge82efc492019-09-04 09:57:11 -07001427 if pktTagType, ok := classifierInfo[PacketTagType].(string); ok {
1428 classifier.PktTagType = pktTagType
1429
1430 switch pktTagType {
1431 case SingleTag:
1432 case DoubleTag:
1433 case Untagged:
1434 default:
Girish Kumarf26e4882020-03-05 06:49:10 +00001435 return nil, olterrors.NewErrInvalidValue(log.Fields{"packet-tag-type": pktTagType}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301436 }
1437 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001438 return &classifier, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301439}
1440
Gamze Abaka724d0852020-03-18 12:10:24 +00001441func makeOpenOltActionField(actionInfo map[string]interface{}, classifierInfo map[string]interface{}) (*openoltpb2.Action, error) {
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001442 var actionCmd openoltpb2.ActionCmd
1443 var action openoltpb2.Action
manikkaraj kbf256be2019-03-25 00:13:48 +05301444 action.Cmd = &actionCmd
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001445 if _, ok := actionInfo[PopVlan]; ok {
manikkaraj kbf256be2019-03-25 00:13:48 +05301446 action.Cmd.RemoveOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001447 if _, ok := actionInfo[VlanPcp]; ok {
1448 action.Cmd.RemarkInnerPbits = true
1449 action.IPbits = actionInfo[VlanPcp].(uint32)
1450 if _, ok := actionInfo[VlanVid]; ok {
1451 action.Cmd.TranslateInnerTag = true
1452 action.IVid = actionInfo[VlanVid].(uint32)
1453 }
1454 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001455 } else if _, ok := actionInfo[PushVlan]; ok {
1456 action.OVid = actionInfo[VlanVid].(uint32)
manikkaraj kbf256be2019-03-25 00:13:48 +05301457 action.Cmd.AddOuterTag = true
Gamze Abaka724d0852020-03-18 12:10:24 +00001458 if _, ok := actionInfo[VlanPcp]; ok {
1459 action.OPbits = actionInfo[VlanPcp].(uint32)
1460 action.Cmd.RemarkOuterPbits = true
1461 if _, ok := classifierInfo[VlanVid]; ok {
1462 action.IVid = classifierInfo[VlanVid].(uint32)
1463 action.Cmd.TranslateInnerTag = true
1464 }
1465 }
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001466 } else if _, ok := actionInfo[TrapToHost]; ok {
1467 action.Cmd.TrapToHost = actionInfo[TrapToHost].(bool)
manikkaraj kbf256be2019-03-25 00:13:48 +05301468 } else {
Girish Kumarf26e4882020-03-05 06:49:10 +00001469 return nil, olterrors.NewErrInvalidValue(log.Fields{"action-command": actionInfo}, nil)
manikkaraj kbf256be2019-03-25 00:13:48 +05301470 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001471 return &action, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301472}
1473
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001474// getTPpath return the ETCD path for a given UNI port
Neha Sharma96b7bf22020-06-15 10:37:32 +00001475func (f *OpenOltFlowMgr) getTPpath(ctx context.Context, intfID uint32, uniPath string, TpID uint32) string {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001476 return f.techprofile.GetTechProfileInstanceKey(ctx, TpID, uniPath)
manikkaraj kbf256be2019-03-25 00:13:48 +05301477}
1478
Gamze Abakafee36392019-10-03 11:17:24 +00001479// DeleteTechProfileInstances removes the tech profile instances from persistent storage
Girish Gowdra197acc12021-08-16 10:59:45 -07001480// We also force release scheduler and queues associated with the tp instance. Theoretically there could be
1481// an issue if the upstream scheduler (DBA) is shared across multiple UNI and we force release it, given that
1482// this function is only meant to clean up TP instances of a given UNI. But in practicality this routine
1483// is only meant to be called when the clean up of resource for the whole ONU is taking place.
1484// The reason for introducing the force cleanup of scheduler and queues (on the OLT) was introduced here
1485// because it was observed that if the ONU device was deleted too soon after the flows were
1486// unprovisioned on that ONU, the scheduler and queue removal pertinent to that ONU would remain
1487// uncleaned on the OLT. So we force clean up here and ignore any error that OLT returns during the
1488// force cleanup (possible if the OLT has already cleared those resources).
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001489func (f *OpenOltFlowMgr) DeleteTechProfileInstances(ctx context.Context, intfID uint32, onuID uint32, uniID uint32) error {
npujarec5762e2020-01-01 14:08:48 +05301490 tpIDList := f.resourceMgr.GetTechProfileIDForOnu(ctx, intfID, onuID, uniID)
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001491 uniPortName := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1492
Gamze Abakafee36392019-10-03 11:17:24 +00001493 for _, tpID := range tpIDList {
Girish Gowdra197acc12021-08-16 10:59:45 -07001494
1495 // Force cleanup scheduler/queues -- start
1496 uniPortNum := MkUniPortNum(ctx, intfID, onuID, uniID)
1497 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
1498 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
1499 tpInst, err := f.techprofile.GetTPInstance(ctx, tpPath)
1500 if err != nil || tpInst == nil { // This should not happen, something wrong in KV backend transaction
1501 logger.Warnw(ctx, "tech-profile-not-in-kv-store",
1502 log.Fields{
1503 "tp-id": tpID,
1504 "path": tpPath})
1505 }
1506 switch tpInstance := tpInst.(type) {
1507 case *tp_pb.TechProfileInstance:
1508 f.forceRemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_UPSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: tpID, uniPort: uniPortNum, tpInst: tpInstance})
1509 f.forceRemoveSchedulerQueues(ctx, schedQueue{direction: tp_pb.Direction_DOWNSTREAM, intfID: intfID, onuID: onuID, uniID: uniID, tpID: tpID, uniPort: uniPortNum, tpInst: tpInstance})
1510 }
1511 // Force cleanup scheduler/queues -- end
1512
1513 // Now remove the tp instance
npujarec5762e2020-01-01 14:08:48 +05301514 if err := f.DeleteTechProfileInstance(ctx, intfID, onuID, uniID, uniPortName, tpID); err != nil {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001515 logger.Errorw(ctx, "delete-tech-profile-failed", log.Fields{"err": err, "device-id": f.deviceHandler.device.Id})
Girish Gowdra54934262019-11-13 14:19:55 +05301516 // return err
1517 // We should continue to delete tech-profile instances for other TP IDs
Gamze Abakafee36392019-10-03 11:17:24 +00001518 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001519 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 +00001520 }
1521 return nil
1522}
1523
1524// DeleteTechProfileInstance removes the tech profile instance from persistent storage
npujarec5762e2020-01-01 14:08:48 +05301525func (f *OpenOltFlowMgr) DeleteTechProfileInstance(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, uniPortName string, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001526 if uniPortName == "" {
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001527 uniPortName = getUniPortPath(f.deviceHandler.device.Id, intfID, int32(onuID), int32(uniID))
Gamze Abakafee36392019-10-03 11:17:24 +00001528 }
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001529 if err := f.techprofile.DeleteTechProfileInstance(ctx, tpID, uniPortName); err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301530 return olterrors.NewErrAdapter("failed-to-delete-tp-instance-from-kv-store",
1531 log.Fields{
1532 "tp-id": tpID,
1533 "uni-port-name": uniPortName,
1534 "device-id": f.deviceHandler.device.Id}, err)
Devmalya Paul495b94a2019-08-27 19:42:00 -04001535 }
1536 return nil
1537}
1538
David K. Bainbridge794735f2020-02-11 21:01:37 -08001539func (f *OpenOltFlowMgr) addFlowToDevice(ctx context.Context, logicalFlow *ofp.OfpFlowStats, deviceFlow *openoltpb2.Flow) error {
Daniele Rossi22db98e2019-07-11 11:50:00 +00001540
1541 var intfID uint32
1542 /* For flows which trap out of the NNI, the AccessIntfId is invalid
1543 (set to -1). In such cases, we need to refer to the NetworkIntfId .
1544 */
1545 if deviceFlow.AccessIntfId != -1 {
1546 intfID = uint32(deviceFlow.AccessIntfId)
1547 } else {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001548 // We need to log the valid interface ID.
1549 // 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 +00001550 intfID = uint32(deviceFlow.NetworkIntfId)
1551 }
1552
Neha Sharma96b7bf22020-06-15 10:37:32 +00001553 logger.Debugw(ctx, "sending-flow-to-device-via-grpc", log.Fields{
Shrey Baid26912972020-04-16 21:02:31 +05301554 "flow": *deviceFlow,
1555 "device-id": f.deviceHandler.device.Id,
1556 "intf-id": intfID})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001557 _, err := f.deviceHandler.Client.FlowAdd(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Daniele Rossi22db98e2019-07-11 11:50:00 +00001558
1559 st, _ := status.FromError(err)
1560 if st.Code() == codes.AlreadyExists {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001561 logger.Debug(ctx, "flow-already-exists", log.Fields{
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001562 "err": err,
1563 "deviceFlow": deviceFlow,
Shrey Baid26912972020-04-16 21:02:31 +05301564 "device-id": f.deviceHandler.device.Id,
1565 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001566 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301567 }
Daniele Rossi22db98e2019-07-11 11:50:00 +00001568
1569 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001570 logger.Errorw(ctx, "failed-to-add-flow-to-device",
Shrey Baid26912972020-04-16 21:02:31 +05301571 log.Fields{"err": err,
1572 "device-flow": deviceFlow,
1573 "device-id": f.deviceHandler.device.Id,
1574 "intf-id": intfID})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001575 return err
Daniele Rossi22db98e2019-07-11 11:50:00 +00001576 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001577 logger.Infow(ctx, "flow-added-to-device-successfully ",
Shrey Baid26912972020-04-16 21:02:31 +05301578 log.Fields{
1579 "flow": *deviceFlow,
1580 "device-id": f.deviceHandler.device.Id,
1581 "intf-id": intfID})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001582
1583 // Case of trap-on-nni flow when deviceFlow.AccessIntfId is invalid (-1)
1584 if deviceFlow.AccessIntfId != -1 {
1585 // No need to register the flow if it is a trap on nni flow.
1586 if err := f.registerFlow(ctx, logicalFlow, deviceFlow); err != nil {
1587 logger.Errorw(ctx, "failed-to-register-flow", log.Fields{"err": err})
1588 return err
1589 }
1590 }
David K. Bainbridge794735f2020-02-11 21:01:37 -08001591 return nil
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001592}
1593
Neha Sharma96b7bf22020-06-15 10:37:32 +00001594func (f *OpenOltFlowMgr) removeFlowFromDevice(ctx context.Context, deviceFlow *openoltpb2.Flow, ofFlowID uint64) error {
1595 logger.Debugw(ctx, "sending-flow-to-device-via-grpc",
Shrey Baid26912972020-04-16 21:02:31 +05301596 log.Fields{
1597 "flow": *deviceFlow,
1598 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001599 _, err := f.deviceHandler.Client.FlowRemove(log.WithSpanFromContext(context.Background(), ctx), deviceFlow)
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001600 if err != nil {
serkant.uluderya245caba2019-09-24 23:15:29 -07001601 if f.deviceHandler.device.ConnectStatus == common.ConnectStatus_UNREACHABLE {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001602 logger.Warnw(ctx, "can-not-remove-flow-from-device--unreachable",
Shrey Baid26912972020-04-16 21:02:31 +05301603 log.Fields{
1604 "err": err,
1605 "deviceFlow": deviceFlow,
1606 "device-id": f.deviceHandler.device.Id})
serkant.uluderya245caba2019-09-24 23:15:29 -07001607 //Assume the flow is removed
David K. Bainbridge794735f2020-02-11 21:01:37 -08001608 return nil
serkant.uluderya245caba2019-09-24 23:15:29 -07001609 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001610 return olterrors.NewErrFlowOp("remove", deviceFlow.FlowId, log.Fields{"deviceFlow": deviceFlow}, err)
serkant.uluderya245caba2019-09-24 23:15:29 -07001611
Manjunath Vanarajulu28c3e822019-05-16 11:14:28 -04001612 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001613 logger.Infow(ctx, "flow-removed-from-device-successfully", log.Fields{
Matteo Scandolo92186242020-06-12 10:54:18 -07001614 "of-flow-id": ofFlowID,
1615 "flow": *deviceFlow,
1616 "device-id": f.deviceHandler.device.Id,
1617 })
David K. Bainbridge794735f2020-02-11 21:01:37 -08001618 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301619}
1620
David K. Bainbridge794735f2020-02-11 21:01:37 -08001621func (f *OpenOltFlowMgr) addLLDPFlow(ctx context.Context, flow *ofp.OfpFlowStats, portNo uint32) error {
Humera Kouser94d7a842019-08-25 19:04:32 -04001622
1623 classifierInfo := make(map[string]interface{})
1624 actionInfo := make(map[string]interface{})
1625
1626 classifierInfo[EthType] = uint32(LldpEthType)
1627 classifierInfo[PacketTagType] = Untagged
1628 actionInfo[TrapToHost] = true
1629
1630 // LLDP flow is installed to trap LLDP packets on the NNI port.
1631 // We manage flow_id resource pool on per PON port basis.
1632 // Since this situation is tricky, as a hack, we pass the NNI port
1633 // index (network_intf_id) as PON port Index for the flow_id resource
1634 // pool. Also, there is no ONU Id available for trapping LLDP packets
1635 // on NNI port, use onu_id as -1 (invalid)
1636 // ****************** CAVEAT *******************
1637 // This logic works if the NNI Port Id falls within the same valid
1638 // range of PON Port Ids. If this doesn't work for some OLT Vendor
1639 // we need to have a re-look at this.
1640 // *********************************************
1641
1642 var onuID = -1
1643 var uniID = -1
1644 var gemPortID = -1
1645
Neha Sharma96b7bf22020-06-15 10:37:32 +00001646 networkInterfaceID, err := IntfIDFromNniPortNum(ctx, portNo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001647 if err != nil {
Thomas Lee S94109f12020-03-03 16:39:29 +05301648 return olterrors.NewErrInvalidValue(log.Fields{"nni-port-number": portNo}, err).Log()
David K. Bainbridge794735f2020-02-11 21:01:37 -08001649 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001650 if present := f.resourceMgr.IsFlowOnKvStore(ctx, networkInterfaceID, int32(onuID), int32(uniID), flow.Id); present {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001651 logger.Infow(ctx, "flow-exists--not-re-adding", log.Fields{"device-id": f.deviceHandler.device.Id})
David K. Bainbridge794735f2020-02-11 21:01:37 -08001652 return nil
Humera Kouser94d7a842019-08-25 19:04:32 -04001653 }
Humera Kouser94d7a842019-08-25 19:04:32 -04001654
David K. Bainbridge794735f2020-02-11 21:01:37 -08001655 classifierProto, err := makeOpenOltClassifierField(classifierInfo)
1656 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301657 return olterrors.NewErrInvalidValue(
1658 log.Fields{
1659 "classifier": classifierInfo,
1660 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001661 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001662 logger.Debugw(ctx, "created-classifier-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301663 log.Fields{
1664 "classifier": *classifierProto,
1665 "device-id": f.deviceHandler.device.Id})
Gamze Abaka724d0852020-03-18 12:10:24 +00001666 actionProto, err := makeOpenOltActionField(actionInfo, classifierInfo)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001667 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301668 return olterrors.NewErrInvalidValue(
1669 log.Fields{
1670 "action": actionInfo,
1671 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001672 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001673 logger.Debugw(ctx, "created-action-proto",
Shrey Baid26912972020-04-16 21:02:31 +05301674 log.Fields{
1675 "action": *actionProto,
1676 "device-id": f.deviceHandler.device.Id})
Humera Kouser94d7a842019-08-25 19:04:32 -04001677
1678 downstreamflow := openoltpb2.Flow{AccessIntfId: int32(-1), // AccessIntfId not required
1679 OnuId: int32(onuID), // OnuId not required
1680 UniId: int32(uniID), // UniId not used
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001681 FlowId: flow.Id,
Humera Kouser94d7a842019-08-25 19:04:32 -04001682 FlowType: Downstream,
1683 NetworkIntfId: int32(networkInterfaceID),
1684 GemportId: int32(gemPortID),
1685 Classifier: classifierProto,
1686 Action: actionProto,
1687 Priority: int32(flow.Priority),
1688 Cookie: flow.Cookie,
1689 PortNo: portNo}
David K. Bainbridge794735f2020-02-11 21:01:37 -08001690 if err := f.addFlowToDevice(ctx, flow, &downstreamflow); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001691 return olterrors.NewErrFlowOp("add", flow.Id,
Shrey Baid26912972020-04-16 21:02:31 +05301692 log.Fields{
1693 "flow": downstreamflow,
1694 "device-id": f.deviceHandler.device.Id}, err)
Humera Kouser94d7a842019-08-25 19:04:32 -04001695 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001696 logger.Infow(ctx, "lldp-trap-on-nni-flow-added-to-device-successfully",
Shrey Baid26912972020-04-16 21:02:31 +05301697 log.Fields{
1698 "device-id": f.deviceHandler.device.Id,
1699 "onu-id": onuID,
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001700 "flow-id": flow.Id})
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001701
David K. Bainbridge794735f2020-02-11 21:01:37 -08001702 return nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301703}
1704
Matteo Scandolod625b4c2020-04-02 16:16:01 -07001705func getUniPortPath(oltID string, intfID uint32, onuID int32, uniID int32) string {
1706 return fmt.Sprintf("olt-{%s}/pon-{%d}/onu-{%d}/uni-{%d}", oltID, intfID, onuID, uniID)
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001707}
1708
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001709//getOnuDevice to fetch onu from cache or core.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001710func (f *OpenOltFlowMgr) getOnuDevice(ctx context.Context, intfID uint32, onuID uint32) (*OnuDevice, error) {
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001711 onuKey := f.deviceHandler.formOnuKey(intfID, onuID)
1712 onuDev, ok := f.deviceHandler.onus.Load(onuKey)
1713 if !ok {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001714 logger.Debugw(ctx, "couldnt-find-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301715 log.Fields{
1716 "intf-id": intfID,
1717 "onu-id": onuID,
1718 "device-id": f.deviceHandler.device.Id})
Neha Sharma96b7bf22020-06-15 10:37:32 +00001719 onuDevice, err := f.getChildDevice(ctx, intfID, onuID)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001720 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301721 return nil, olterrors.NewErrNotFound("onu-child-device",
1722 log.Fields{
1723 "onu-id": onuID,
1724 "intf-id": intfID,
1725 "device-id": f.deviceHandler.device.Id}, err)
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001726 }
1727 onuDev = NewOnuDevice(onuDevice.Id, onuDevice.Type, onuDevice.SerialNumber, onuDevice.ProxyAddress.OnuId, onuDevice.ProxyAddress.ChannelId, onuDevice.ProxyAddress.DeviceId, false)
1728 //better to ad the device to cache here.
1729 f.deviceHandler.StoreOnuDevice(onuDev.(*OnuDevice))
1730 } else {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001731 logger.Debugw(ctx, "found-onu-in-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301732 log.Fields{
1733 "intf-id": intfID,
1734 "onu-id": onuID,
1735 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001736 }
1737
1738 return onuDev.(*OnuDevice), nil
1739}
1740
1741//getChildDevice to fetch onu
Neha Sharma96b7bf22020-06-15 10:37:32 +00001742func (f *OpenOltFlowMgr) getChildDevice(ctx context.Context, intfID uint32, onuID uint32) (*voltha.Device, error) {
1743 logger.Infow(ctx, "GetChildDevice",
Shrey Baid26912972020-04-16 21:02:31 +05301744 log.Fields{
1745 "pon-port": intfID,
1746 "onu-id": onuID,
1747 "device-id": f.deviceHandler.device.Id})
Girish Gowdru6a80bbd2019-07-02 07:36:09 -07001748 parentPortNo := IntfIDToPortNo(intfID, voltha.Port_PON_OLT)
Neha Sharma96b7bf22020-06-15 10:37:32 +00001749 onuDevice, err := f.deviceHandler.GetChildDevice(ctx, parentPortNo, onuID)
David K. Bainbridge794735f2020-02-11 21:01:37 -08001750 if err != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301751 return nil, olterrors.NewErrNotFound("onu",
1752 log.Fields{
1753 "interface-id": parentPortNo,
1754 "onu-id": onuID,
1755 "device-id": f.deviceHandler.device.Id},
Girish Kumarf26e4882020-03-05 06:49:10 +00001756 err)
manikkaraj kbf256be2019-03-25 00:13:48 +05301757 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001758 logger.Infow(ctx, "successfully-received-child-device-from-core",
Shrey Baid26912972020-04-16 21:02:31 +05301759 log.Fields{
1760 "device-id": f.deviceHandler.device.Id,
1761 "child_device_id": onuDevice.Id,
1762 "child_device_sn": onuDevice.SerialNumber})
Manikkaraj k884c1242019-04-11 16:26:42 +05301763 return onuDevice, nil
manikkaraj kbf256be2019-03-25 00:13:48 +05301764}
1765
Neha Sharma96b7bf22020-06-15 10:37:32 +00001766func (f *OpenOltFlowMgr) sendDeleteGemPortToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, gemPortID uint32, tpPath string) error {
1767 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301768 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001769 logger.Debugw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301770 log.Fields{
1771 "intf-id": intfID,
1772 "onu-id": onuID,
1773 "uni-id": uniID,
1774 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001775 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301776 }
1777
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001778 delGemPortMsg := &ic.InterAdapterDeleteGemPortMessage{UniId: uniID, TpInstancePath: tpPath, GemPortId: gemPortID}
1779 logger.Infow(ctx, "sending-gem-port-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301780 log.Fields{
1781 "msg": *delGemPortMsg,
1782 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001783 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301784 delGemPortMsg,
1785 ic.InterAdapterMessageType_DELETE_GEM_PORT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001786 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001787 onuDev.deviceType,
1788 onuDev.deviceID,
1789 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301790 return olterrors.NewErrCommunication("send-delete-gem-port-to-onu-adapter",
1791 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001792 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301793 "to-adapter": onuDev.deviceType,
1794 "onu-id": onuDev.deviceID,
1795 "proxyDeviceID": onuDev.proxyDeviceID,
1796 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301797 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001798 logger.Infow(ctx, "success-sending-del-gem-port-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301799 log.Fields{
1800 "msg": delGemPortMsg,
1801 "from-adapter": f.deviceHandler.device.Type,
1802 "to-adapter": onuDev.deviceType,
1803 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301804 return nil
1805}
1806
Neha Sharma96b7bf22020-06-15 10:37:32 +00001807func (f *OpenOltFlowMgr) sendDeleteTcontToChild(ctx context.Context, intfID uint32, onuID uint32, uniID uint32, allocID uint32, tpPath string) error {
1808 onuDev, err := f.getOnuDevice(ctx, intfID, onuID)
Girish Gowdra6b130582019-11-20 16:45:20 +05301809 if err != nil {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001810 logger.Warnw(ctx, "couldnt-find-onu-child-device",
Shrey Baid26912972020-04-16 21:02:31 +05301811 log.Fields{
1812 "intf-id": intfID,
1813 "onu-id": onuID,
1814 "uni-id": uniID,
1815 "device-id": f.deviceHandler.device.Id})
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001816 return err
Girish Gowdra6b130582019-11-20 16:45:20 +05301817 }
1818
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001819 delTcontMsg := &ic.InterAdapterDeleteTcontMessage{UniId: uniID, TpInstancePath: tpPath, AllocId: allocID}
Neha Sharma96b7bf22020-06-15 10:37:32 +00001820 logger.Debugw(ctx, "sending-tcont-delete-to-openonu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301821 log.Fields{
1822 "msg": *delTcontMsg,
1823 "device-id": f.deviceHandler.device.Id})
Neha Sharma8f4e4322020-08-06 10:51:53 +00001824 if sendErr := f.deviceHandler.AdapterProxy.SendInterAdapterMessage(log.WithSpanFromContext(context.Background(), ctx),
Girish Gowdra6b130582019-11-20 16:45:20 +05301825 delTcontMsg,
1826 ic.InterAdapterMessageType_DELETE_TCONT_REQUEST,
serkant.uluderya4aff1862020-09-17 23:35:26 +03001827 f.deviceHandler.openOLT.config.Topic,
Mahir Gunyel0f89fd22020-04-11 18:24:42 -07001828 onuDev.deviceType,
1829 onuDev.deviceID,
1830 onuDev.proxyDeviceID, ""); sendErr != nil {
Shrey Baid26912972020-04-16 21:02:31 +05301831 return olterrors.NewErrCommunication("send-delete-tcont-to-onu-adapter",
1832 log.Fields{
serkant.uluderya4aff1862020-09-17 23:35:26 +03001833 "from-adapter": f.deviceHandler.openOLT.config.Topic,
Shrey Baid26912972020-04-16 21:02:31 +05301834 "to-adapter": onuDev.deviceType, "onu-id": onuDev.deviceID,
1835 "proxyDeviceID": onuDev.proxyDeviceID,
1836 "device-id": f.deviceHandler.device.Id}, sendErr)
Girish Gowdra6b130582019-11-20 16:45:20 +05301837 }
Neha Sharma96b7bf22020-06-15 10:37:32 +00001838 logger.Infow(ctx, "success-sending-del-tcont-to-onu-adapter",
Shrey Baid26912972020-04-16 21:02:31 +05301839 log.Fields{
1840 "msg": delTcontMsg,
1841 "device-id": f.deviceHandler.device.Id})
Girish Gowdra6b130582019-11-20 16:45:20 +05301842 return nil
1843}
1844
Girish Gowdrac3037402020-01-22 20:29:53 +05301845// Once the gemport is released for a given onu, it also has to be cleared from local cache
1846// which was used for deriving the gemport->logicalPortNo during packet-in.
1847// Otherwise stale info continues to exist after gemport is freed and wrong logicalPortNo
1848// is conveyed to ONOS during packet-in OF message.
Neha Sharma96b7bf22020-06-15 10:37:32 +00001849func (f *OpenOltFlowMgr) deleteGemPortFromLocalCache(ctx context.Context, intfID uint32, onuID uint32, gemPortID uint32) {
Neha Sharma96b7bf22020-06-15 10:37:32 +00001850 logger.Infow(ctx, "deleting-gem-from-local-cache",
Shrey Baid26912972020-04-16 21:02:31 +05301851 log.Fields{
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001852 "gem-port-id": gemPortID,
1853 "intf-id": intfID,
1854 "onu-id": onuID,
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001855 "device-id": f.deviceHandler.device.Id})
1856 f.onuGemInfoLock.RLock()
1857 onugem, ok := f.onuGemInfoMap[onuID]
1858 f.onuGemInfoLock.RUnlock()
1859 if !ok {
1860 logger.Warnw(ctx, "onu gem info already cleared from cache", log.Fields{
1861 "gem-port-id": gemPortID,
1862 "intf-id": intfID,
1863 "onu-id": onuID,
1864 "device-id": f.deviceHandler.device.Id})
1865 return
1866 }
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001867deleteLoop:
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001868 for j, gem := range onugem.GemPorts {
1869 // If the gemport is found, delete it from local cache.
1870 if gem == gemPortID {
1871 onugem.GemPorts = append(onugem.GemPorts[:j], onugem.GemPorts[j+1:]...)
1872 f.onuGemInfoLock.Lock()
1873 f.onuGemInfoMap[onuID] = onugem
1874 f.onuGemInfoLock.Unlock()
1875 logger.Infow(ctx, "removed-gemport-from-local-cache",
1876 log.Fields{
1877 "intf-id": intfID,
1878 "onu-id": onuID,
1879 "deletedgemport-id": gemPortID,
1880 "gemports": onugem.GemPorts,
1881 "device-id": f.deviceHandler.device.Id})
Matteo Scandoloabf9c512020-06-23 19:31:14 -07001882 break deleteLoop
Girish Gowdrac3037402020-01-22 20:29:53 +05301883 }
1884 }
1885}
1886
Abhilash Laxmeshwarb7300fe2019-11-13 03:38:33 +05301887//clearResources clears pon resources in kv store and the device
Takahiro Suzuki2ba0e0b2020-06-05 14:23:03 -07001888// nolint: gocyclo
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001889func (f *OpenOltFlowMgr) clearResources(ctx context.Context, intfID uint32, onuID int32, uniID int32,
Girish Gowdra82c80982021-03-26 16:22:02 -07001890 gemPortID int32, flowID uint64, portNum uint32, tpID uint32) error {
Gamze Abakafee36392019-10-03 11:17:24 +00001891
Girish Gowdraa482f272021-03-24 23:04:19 -07001892 uni := getUniPortPath(f.deviceHandler.device.Id, intfID, onuID, uniID)
1893 tpPath := f.getTPpath(ctx, intfID, uni, tpID)
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001894 logger.Debugw(ctx, "getting-techprofile-instance-for-subscriber",
1895 log.Fields{
1896 "tpPath": tpPath,
1897 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001898
1899 used := f.isGemPortUsedByAnotherFlow(uint32(gemPortID))
1900
1901 if used {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001902 f.gemToFlowIDsKey.RLock()
1903 flowIDs := f.gemToFlowIDs[uint32(gemPortID)]
1904 f.gemToFlowIDsKey.RUnlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001905
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001906 for i, flowIDinMap := range flowIDs {
1907 if flowIDinMap == flowID {
1908 flowIDs = append(flowIDs[:i], flowIDs[i+1:]...)
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001909 f.gemToFlowIDsKey.Lock()
1910 f.gemToFlowIDs[uint32(gemPortID)] = flowIDs
1911 f.gemToFlowIDsKey.Unlock()
1912 // everytime gemToFlowIDs cache is updated the same should be updated
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001913 // in kv store by calling UpdateFlowIDsForGem
Girish Gowdraa482f272021-03-24 23:04:19 -07001914 if err := f.resourceMgr.UpdateFlowIDsForGem(ctx, intfID, uint32(gemPortID), flowIDs); err != nil {
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001915 return err
1916 }
1917 break
1918 }
Girish Kumarf26e4882020-03-05 06:49:10 +00001919 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001920 logger.Debugw(ctx, "gem-port-id-is-still-used-by-other-flows",
1921 log.Fields{
1922 "gemport-id": gemPortID,
1923 "usedByFlows": flowIDs,
1924 "device-id": f.deviceHandler.device.Id})
Girish Gowdraa482f272021-03-24 23:04:19 -07001925
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001926 return nil
1927 }
1928 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 -07001929 f.deleteGemPortFromLocalCache(ctx, intfID, uint32(onuID), uint32(gemPortID))
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001930 _ = f.resourceMgr.RemoveGemFromOnuGemInfo(ctx, intfID, uint32(onuID), uint32(gemPortID)) // ignore error and proceed.
1931 //everytime an entry is deleted from gemToFlowIDs cache, the same should be updated in kv as well
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001932 // by calling DeleteFlowIDsForGem
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001933 f.gemToFlowIDsKey.Lock()
1934 delete(f.gemToFlowIDs, uint32(gemPortID))
1935 f.gemToFlowIDsKey.Unlock()
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001936
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001937 f.resourceMgr.DeleteFlowIDsForGem(ctx, intfID, uint32(gemPortID))
1938
1939 f.resourceMgr.FreeGemPortID(ctx, intfID, uint32(onuID), uint32(uniID), uint32(gemPortID))
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001940
Mahir Gunyel199570a2021-07-04 15:39:36 -07001941 //First remove TCONT from child if needed. Then remove the GEM.
1942 //It is expected from child to clean ani side conf if all GEMs of TP are deleted.
1943 //Before this, ensure that the related TCONT deletions are informed to child.
1944 //Refer to VOL-4215.
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001945 techprofileInst, err := f.techprofile.GetTPInstance(ctx, tpPath)
1946 if err != nil || techprofileInst == nil { // This should not happen, something wrong in KV backend transaction
1947 return olterrors.NewErrNotFound("tech-profile-in-kv-store",
1948 log.Fields{
1949 "tp-id": tpID,
1950 "path": tpPath}, err)
1951 }
Girish Gowdraa09aeab2020-09-14 16:30:52 -07001952 switch techprofileInst := techprofileInst.(type) {
Girish Gowdra8a0bdcd2021-05-13 12:31:04 -07001953 case *tp_pb.TechProfileInstance:
Gamze Abakacb0e6772021-06-10 08:32:12 +00001954 ok, _ := f.isTechProfileUsedByAnotherGem(ctx, intfID, uint32(on