blob: 1afc480ba88a076aa8a616723a9393b9dc87a46f [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
mpagenkodff5dda2020-08-28 11:52:01 +00003 *
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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +053017// Package avcfg provides anig and vlan configuration functionality
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package avcfg
mpagenkodff5dda2020-08-28 11:52:01 +000019
20import (
21 "context"
22 "encoding/binary"
mpagenkof582d6a2021-06-18 15:58:10 +000023 "errors"
Andrea Campanella6515c582020-10-05 11:25:00 +020024 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030025 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028 "time"
29
khenaidoo7d3c5582021-08-11 18:09:44 -040030 meters "github.com/opencord/voltha-lib-go/v7/pkg/meters"
ozgecanetsia82b91a62021-05-21 18:54:49 +030031
mpagenko01e726e2020-10-23 09:45:29 +000032 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000033 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000034 "github.com/opencord/omci-lib-go/v2"
35 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040036 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000037 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
38 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
khenaidoo7d3c5582021-08-11 18:09:44 -040039 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000040)
41
42const (
43 // internal predefined values
44 cDefaultDownstreamMode = 0
45 cDefaultTpid = 0x8100
Akash Soni840f8d62024-12-11 19:37:06 +053046 cVtfdTableSize = 64 //as per G.988
mpagenko01e726e2020-10-23 09:45:29 +000047 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000048)
49
50const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000051 // internal offsets for requestEvent according to definition in onu_device_entry::cmn.OnuDeviceEvent
mpagenkof1fc3862021-02-16 10:09:52 +000052 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000053 cDeviceEventOffsetAddNoKvStore = cmn.OmciVlanFilterAddDoneNoKvStore - cmn.OmciVlanFilterAddDone
54 cDeviceEventOffsetRemoveWithKvStore = cmn.OmciVlanFilterRemDone - cmn.OmciVlanFilterAddDone
55 cDeviceEventOffsetRemoveNoKvStore = cmn.OmciVlanFilterRemDoneNoKvStore - cmn.OmciVlanFilterAddDone
mpagenkof1fc3862021-02-16 10:09:52 +000056)
57
58const (
mpagenkodff5dda2020-08-28 11:52:01 +000059 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
60 cFilterPrioOffset = 28
61 cFilterVidOffset = 15
62 cFilterTpidOffset = 12
63 cFilterEtherTypeOffset = 0
64 cTreatTTROffset = 30
65 cTreatPrioOffset = 16
66 cTreatVidOffset = 3
67 cTreatTpidOffset = 0
68)
69const (
70 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
71 cFilterOuterOffset = 0
72 cFilterInnerOffset = 4
73 cTreatOuterOffset = 8
74 cTreatInnerOffset = 12
75)
76const (
77 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
78 cPrioIgnoreTag uint32 = 15
79 cPrioDefaultFilter uint32 = 14
80 cPrioDoNotFilter uint32 = 8
81 cDoNotFilterVid uint32 = 4096
82 cDoNotFilterTPID uint32 = 0
83 cDoNotFilterEtherType uint32 = 0
84 cDoNotAddPrio uint32 = 15
85 cCopyPrioFromInner uint32 = 8
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +053086 cCopyPrioFromOuter uint32 = 9
Himani Chawla4d908332020-08-31 12:30:20 +053087 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000088 cDontCareVid uint32 = 0
89 cDontCareTpid uint32 = 0
90 cSetOutputTpidCopyDei uint32 = 4
91)
92
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000093// events of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +000094const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000095 VlanEvStart = "VlanEvStart"
96 VlanEvPrepareDone = "VlanEvPrepareDone"
97 VlanEvWaitTechProf = "VlanEvWaitTechProf"
98 VlanEvCancelOutstandingConfig = "VlanEvCancelOutstandingConfig"
99 VlanEvContinueConfig = "VlanEvContinueConfig"
100 VlanEvStartConfig = "VlanEvStartConfig"
101 VlanEvRxConfigVtfd = "VlanEvRxConfigVtfd"
102 VlanEvRxConfigEvtocd = "VlanEvRxConfigEvtocd"
103 VlanEvWaitTPIncr = "VlanEvWaitTPIncr"
104 VlanEvIncrFlowConfig = "VlanEvIncrFlowConfig"
105 VlanEvRenew = "VlanEvRenew"
106 VlanEvRemFlowConfig = "VlanEvRemFlowConfig"
107 VlanEvRemFlowDone = "VlanEvRemFlowDone"
108 VlanEvFlowDataRemoved = "VlanEvFlowDataRemoved"
109 //VlanEvTimeoutSimple = "VlanEvTimeoutSimple"
110 //VlanEvTimeoutMids = "VlanEvTimeoutMids"
111 VlanEvReset = "VlanEvReset"
112 VlanEvRestart = "VlanEvRestart"
113 VlanEvSkipOmciConfig = "VlanEvSkipOmciConfig"
114 VlanEvSkipIncFlowConfig = "VlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000115)
mpagenko01e726e2020-10-23 09:45:29 +0000116
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117// states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000118const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 VlanStDisabled = "VlanStDisabled"
120 VlanStPreparing = "VlanStPreparing"
121 VlanStStarting = "VlanStStarting"
122 VlanStWaitingTechProf = "VlanStWaitingTechProf"
123 VlanStConfigVtfd = "VlanStConfigVtfd"
124 VlanStConfigEvtocd = "VlanStConfigEvtocd"
125 VlanStConfigDone = "VlanStConfigDone"
126 VlanStIncrFlowWaitTP = "VlanStIncrFlowWaitTP"
127 VlanStConfigIncrFlow = "VlanStConfigIncrFlow"
128 VlanStRemoveFlow = "VlanStRemoveFlow"
129 VlanStCleanupDone = "VlanStCleanupDone"
130 VlanStResetting = "VlanStResetting"
mpagenkodff5dda2020-08-28 11:52:01 +0000131)
132
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000133// CVlanFsmIdleState - TODO: add comment
134const CVlanFsmIdleState = VlanStConfigDone // state where no OMCI activity is done (for a longer time)
135// CVlanFsmConfiguredState - TODO: add comment
136const CVlanFsmConfiguredState = VlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenko01e726e2020-10-23 09:45:29 +0000137
138type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000139 removeChannel chan bool
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530140 respChan *chan error
mpagenkof1d21d12021-06-11 13:14:45 +0000141 cookie uint64 //just the last cookie valid for removal
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000142 vlanRuleParams cmn.UniVlanRuleParams
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530143 isSuspendedOnAdd bool
mpagenko01e726e2020-10-23 09:45:29 +0000144}
145
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530146// UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147//
148// builds upon 'VLAN rules' that are derived from multiple flows
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530149//
150//nolint:govet
mpagenkodff5dda2020-08-28 11:52:01 +0000151type UniVlanConfigFsm struct {
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530152 actualUniFlowParam cmn.UniVlanFlowParams
153 pDeviceHandler cmn.IdeviceHandler
154 pOnuDeviceEntry cmn.IonuDeviceEntry
155 pOmciCC *cmn.OmciCC
156 pOnuUniPort *cmn.OnuUniPort
157 pUniTechProf *OnuUniTechProf
158 pOnuDB *devdb.OnuDeviceDB
159 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
160 PAdaptFsm *cmn.AdapterFsm
161 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
162 pLastTxMeInstance *me.ManagedEntity
163 flowDeleteChannel chan<- bool
164 deviceID string
165 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
166 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
167 requestEvent cmn.OnuDeviceEvent
168 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
169 delayNewRuleCookie uint64
170 mutexIsAwaitingResponse sync.RWMutex
171 mutexFlowParams sync.RWMutex
172 mutexPLastTxMeInstance sync.RWMutex
173 vlanFilterList [cVtfdTableSize]uint16
174 evtocdID uint16
mpagenkodff5dda2020-08-28 11:52:01 +0000175 acceptIncrementalEvtoOption bool
mpagenkocf48e452021-04-23 09:23:00 +0000176 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000177 isAwaitingResponse bool
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000178 NumUniFlows uint8 // expected number of flows should be less than 12
179 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000180 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000181 numVlanFilterEntries uint8
mpagenkofc4f56e2020-11-04 17:17:49 +0000182 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000183 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000184 signalOnFlowDelete bool
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200185 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
186 // thus notification needs to be sent on chan.
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530187 lastFlowToReconcile bool
188 lastFlowToConfigOnReboot bool
mpagenkodff5dda2020-08-28 11:52:01 +0000189}
190
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530191// NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
192//
193// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000194func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
195 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
196 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530197 aCookieSlice []uint64, aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, lastFlowToRec bool, lastFlowToConfOnReboot bool, aMeter *of.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000198 instFsm := &UniVlanConfigFsm{
199 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000200 pOnuDeviceEntry: apOnuDeviceEntry,
201 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000202 pOmciCC: apDevOmciCC,
203 pOnuUniPort: apUniPort,
204 pUniTechProf: apUniTechProf,
205 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000206 requestEvent: aRequestEvent,
207 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000208 NumUniFlows: 0,
209 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000210 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200211 lastFlowToReconcile: lastFlowToRec,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530212 lastFlowToConfigOnReboot: lastFlowToConfOnReboot,
mpagenkodff5dda2020-08-28 11:52:01 +0000213 }
214
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000215 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
216 if instFsm.PAdaptFsm == nil {
217 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000218 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700219 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000220 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000221 return nil
222 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000223 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
224 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000225 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000226 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
227 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
228 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
229 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
230 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
231 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
232 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
233 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
234 Dst: VlanStConfigDone},
235 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
236 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
237 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
238 Dst: VlanStConfigIncrFlow},
239 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
240 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
241 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000242 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000243 {Name: VlanEvTimeoutSimple, Src: []string{
244 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
245 {Name: VlanEvTimeoutMids, Src: []string{
246 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000247 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 // exceptional treatment for all states except VlanStResetting
249 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
250 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +0530251 VlanStRemoveFlow, VlanStCleanupDone, VlanStPreparing},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000252 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000253 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000255 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000256 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
257 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
258 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000259 },
mpagenkodff5dda2020-08-28 11:52:01 +0000260 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000261 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
262 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
263 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
264 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
265 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
266 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
267 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
268 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
269 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
270 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
271 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000272 },
273 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000274 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000275 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000276 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700277 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000278 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return nil
280 }
281
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530282 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, aMeter, respChan)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000283 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000284 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000285 return instFsm
286}
287
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530288// initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000289func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530290 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000291 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530292 TpID: aTpID,
293 MatchVid: uint32(aMatchVlan),
294 MatchPcp: uint32(aMatchPcp),
295 SetVid: uint32(aSetVlan),
296 SetPcp: uint32(aSetPcp),
297 InnerCvlan: innerCvlan,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 }
299 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +0530300 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301
mpagenko01e726e2020-10-23 09:45:29 +0000302 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000304 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000305 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
306 } else {
307 if !oFsm.acceptIncrementalEvtoOption {
308 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 }
311 }
312
mpagenko01e726e2020-10-23 09:45:29 +0000313 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000314 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000315 loRuleParams.TagsToRemove = 0 //no tag pop action
316 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
317 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000318 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
319 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
320 // might collide with NoMatchVid/CopyPrio(/setVid) setting
321 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000322 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000323 }
324 }
mpagenko01e726e2020-10-23 09:45:29 +0000325
Girish Gowdrae95687a2021-09-08 16:30:58 -0700326 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000327 loFlowParams.CookieSlice = make([]uint64, 0)
328 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300329 if aMeter != nil {
330 loFlowParams.Meter = aMeter
331 }
mpagenko01e726e2020-10-23 09:45:29 +0000332
333 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000335 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000337 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
338 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
339 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
340 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000341 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000342
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000343 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000344 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
345 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000346 //cmp also usage in EVTOCDE create in omci_cc
347 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000349 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
350
351 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000352 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000353 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000355 return err
356 }
357
358 return nil
359}
360
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530361// CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000362func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000363 if oFsm == nil {
364 logger.Error(ctx, "no valid UniVlanConfigFsm!")
365 return
366 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530367 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +0000368 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000369 oFsm.mutexIsAwaitingResponse.Lock()
370 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000371 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000372 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
373 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
374 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000375 //use channel to indicate that the response waiting shall be aborted
376 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000377 } else {
378 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000379 }
mpagenkocf48e452021-04-23 09:23:00 +0000380
mpagenko7d6bb022021-03-11 15:07:55 +0000381 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 PAdaptFsm := oFsm.PAdaptFsm
383 if PAdaptFsm != nil {
384 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000385 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000386 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000387 }
mpagenko7d6bb022021-03-11 15:07:55 +0000388 }
389}
390
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530391// GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000392func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
393 if oFsm == nil {
394 logger.Error(ctx, "no valid UniVlanConfigFsm!")
395 return 0
396 }
mpagenko551a4d42020-12-08 18:09:20 +0000397 //mutex protection is required for possible concurrent access to FSM members
398 oFsm.mutexFlowParams.RLock()
399 defer oFsm.mutexFlowParams.RUnlock()
400 return oFsm.TpIDWaitingFor
401}
402
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530403// SetUniFlowParams verifies on existence of flow parameters to be configured,
mpagenko01e726e2020-10-23 09:45:29 +0000404// optionally udates the cookie list or appends a new flow if there is space
405// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000406// ignore complexity by now
407// nolint: gocyclo
408func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530409 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, aInnerCvlan uint16, lastFlowToReconcile bool, lastFlowToConfigOnReboot bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000410 if oFsm == nil {
411 logger.Error(ctx, "no valid UniVlanConfigFsm!")
412 return fmt.Errorf("no-valid-UniVlanConfigFsm")
413 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000414 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530415 TpID: aTpID,
416 MatchVid: uint32(aMatchVlan),
417 MatchPcp: uint32(aMatchPcp),
418 SetVid: uint32(aSetVlan),
419 SetPcp: uint32(aSetPcp),
420 InnerCvlan: aInnerCvlan,
mpagenko01e726e2020-10-23 09:45:29 +0000421 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700422 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000423 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530424 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
mpagenko01e726e2020-10-23 09:45:29 +0000425 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
426 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
427 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
428 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
429 } else {
430 if !oFsm.acceptIncrementalEvtoOption {
431 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
432 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
433 }
434 }
435
436 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
437 // no prio/vid filtering requested
438 loRuleParams.TagsToRemove = 0 //no tag pop action
439 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
440 if loRuleParams.SetPcp == cCopyPrioFromInner {
441 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
442 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
443 // might collide with NoMatchVid/CopyPrio(/setVid) setting
444 // this was some precondition setting taken over from py adapter ..
445 loRuleParams.SetPcp = 0
446 }
447 }
448
mpagenkof1d21d12021-06-11 13:14:45 +0000449 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
450 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
451 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
452 oFsm.mutexFlowParams.RLock()
453 if len(oFsm.uniRemoveFlowsSlice) > 0 {
454 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
455 if removeUniFlowParams.vlanRuleParams == loRuleParams {
456 // the flow to add is the same as the one already in progress of deleting
457 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000458 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
459 if flow >= len(oFsm.uniRemoveFlowsSlice) {
460 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
461 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
462 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700463 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000464 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700465 return err
466
mpagenkof582d6a2021-06-18 15:58:10 +0000467 }
mpagenkof1d21d12021-06-11 13:14:45 +0000468 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
469 oFsm.mutexFlowParams.RUnlock()
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530470 if err = oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +0000471 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
472 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700473 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000474 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700475 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000476 }
477 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000478 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000479 }
480 }
481 }
482 oFsm.mutexFlowParams.RUnlock()
483
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000484 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000485 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000486 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200487 oFsm.lastFlowToReconcile = lastFlowToReconcile
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +0530488 oFsm.lastFlowToConfigOnReboot = lastFlowToConfigOnReboot
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000489 //mutex protection is required for possible concurrent access to FSM members
490 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000491 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
492 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
493 // countable run time optimization (perhaps with including the hash in kvStore storage?)
494 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000495 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300497 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
498 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
499 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000500 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000501 var cookieMatch bool
502 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
503 cookieMatch = false
504 for _, cookie := range storedUniFlowParams.CookieSlice {
505 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000506 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000507 "device-id": oFsm.deviceID, "cookie": cookie})
508 cookieMatch = true
509 break //found new cookie - no further search for this requested cookie
510 }
511 }
512 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000513 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
514 if delayedCookie != 0 {
515 //a delay for adding the cookie to this rule is requested
516 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
517 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000518 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
519 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
520 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700521 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000522 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700523 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000524 }
mpagenkobc4170a2021-08-17 16:42:10 +0000525 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000526 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000527 } else {
528 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
529 "device-id": oFsm.deviceID, "cookie": newCookie})
530 //as range works with copies of the slice we have to write to the original slice!!
531 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
532 newCookie)
533 flowCookieModify = true
534 }
mpagenko01e726e2020-10-23 09:45:29 +0000535 }
536 } //for all new cookies
537 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000538 }
539 }
mpagenkof1fc3862021-02-16 10:09:52 +0000540 oFsm.mutexFlowParams.Unlock()
541
542 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000543 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
544 if !deleteSuccess {
545 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
546 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700547 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000548 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700549 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000550 }
mpagenkof1fc3862021-02-16 10:09:52 +0000551 requestAppendRule = true //default assumption here is that rule is to be appended
552 flowCookieModify = true //and that the the flow data base is to be updated
553 if delayedCookie != 0 { //it was suspended
554 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
555 }
556 }
557 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
558 if requestAppendRule {
559 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700561 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000562 loFlowParams.CookieSlice = make([]uint64, 0)
563 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300564 if aMeter != nil {
565 loFlowParams.Meter = aMeter
566 }
mpagenko01e726e2020-10-23 09:45:29 +0000567 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000568 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000570 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
571 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
573 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000574
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000576 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
577 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 oFsm.NumUniFlows++
579 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000580
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000582 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000584 //attention: take care to release the mutexFlowParams when calling the FSM directly -
585 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000586 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
588 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000589 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000590 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700591 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000592 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700593 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000594 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000595 }
596 return nil
597 }
mpagenko01e726e2020-10-23 09:45:29 +0000598 // note: theoretical it would be possible to clear the same rule from the remove slice
599 // (for entries that have not yet been started with removal)
600 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
601 // anyway the precondition here is that the FSM checks for rules to delete first and adds new rules afterwards
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000602
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000603 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000604 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000605 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000606 // this is a restart with a complete new flow, we can re-use the initial flow config control
607 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000608 //attention: take care to release the mutexFlowParams when calling the FSM directly -
609 // synchronous FSM 'event/state' functions may rely on this mutex
610 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000612 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
613 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
614 }
mpagenko551a4d42020-12-08 18:09:20 +0000615 } else {
616 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000617 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000619 //check introduced after having observed some panic here
620 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000621 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000622 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
623 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700624 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000625 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000627 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700628
629 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000630 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700631 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000632 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700633 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000634 //attention: take care to release the mutexFlowParams when calling the FSM directly -
635 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000636 // but it must be released already before calling getTechProfileDone() as it may already be locked
637 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000638 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000639 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000640 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000642 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
643
mpagenkobb47bc22021-04-20 13:29:09 +0000644 var fsmErr error
645 if loTechProfDone {
646 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000647 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000648 } else {
649 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000650 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000651 }
652 if fsmErr != nil {
653 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
654 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000655 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700656 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000657 }
mpagenko551a4d42020-12-08 18:09:20 +0000658 }
mpagenkobb47bc22021-04-20 13:29:09 +0000659 } else {
660 // if not in the appropriate state a new entry will be automatically considered later
661 // when the configDone state is reached
662 oFsm.mutexFlowParams.Unlock()
663 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000664 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000666 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000667 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700668 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000669 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700670 return err
mpagenko01e726e2020-10-23 09:45:29 +0000671 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 } else {
673 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000674 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700675 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000676 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700677
mpagenko15ff4a52021-03-02 10:09:20 +0000678 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000679 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 //all requested rules really have been configured
681 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000682 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000683 if oFsm.pDeviceHandler != nil {
684 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000686 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000687 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
688 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000689 }
690 } else {
691 // avoid device reason update as the rule config connected to this flow may still be in progress
692 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000694 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000696 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000697 }
698 }
mpagenko01e726e2020-10-23 09:45:29 +0000699
mpagenkof1fc3862021-02-16 10:09:52 +0000700 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000701 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000702 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000703 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000704 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000705 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000706 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000707 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000708 }
mpagenko15ff4a52021-03-02 10:09:20 +0000709 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000710 }
711 return nil
712}
713
mpagenkof1d21d12021-06-11 13:14:45 +0000714func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
715 oFsm.mutexFlowParams.Lock()
716 deleteChannel := apRemoveFlowParams.removeChannel
717 apRemoveFlowParams.isSuspendedOnAdd = true
718 oFsm.mutexFlowParams.Unlock()
719
720 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
721 select {
722 case success := <-deleteChannel:
723 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
724 if success {
725 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
726 "device-id": oFsm.deviceID})
727 return nil
728 }
729 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
730 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
731 oFsm.mutexFlowParams.Lock()
732 if apRemoveFlowParams != nil {
733 apRemoveFlowParams.isSuspendedOnAdd = false
734 }
735 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000736 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000737 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000738 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000739 }
mpagenkof1d21d12021-06-11 13:14:45 +0000740}
741
mpagenkof1fc3862021-02-16 10:09:52 +0000742// VOL-3828 flow config sequence workaround ########### start ##########
743func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
744 //assumes mutexFlowParams.Lock() protection from caller!
745 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
746 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000747 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000748 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
749 newCookie := aCookieSlice[0]
750 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
751 for _, cookie := range storedUniFlowParams.CookieSlice {
752 if cookie == newCookie {
753 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
754 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
755 oFsm.delayNewRuleCookie = newCookie
756 return newCookie //found new cookie in some existing rule
757 }
758 } // for all stored cookies of the actual inspected rule
759 } //for all rules
760 }
761 return 0 //no delay requested
762}
mpagenkobc4170a2021-08-17 16:42:10 +0000763func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000764 oFsm.mutexFlowParams.RLock()
765 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
766 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
767 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000768 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000769 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000770 case cookieDeleted = <-oFsm.chCookieDeleted:
771 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
772 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000773 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000774 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
775 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
776 }
777 oFsm.mutexFlowParams.Lock()
778 oFsm.delayNewRuleCookie = 0
779 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000780 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000781}
mpagenkobc4170a2021-08-17 16:42:10 +0000782func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000783 oFsm.mutexFlowParams.Lock()
784 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
785 oFsm.mutexFlowParams.Unlock()
786
mpagenkobc4170a2021-08-17 16:42:10 +0000787 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000788 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000789 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000790 }
mpagenkobc4170a2021-08-17 16:42:10 +0000791 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000792}
793
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530794// returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000795func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000796 flowEntryMatch := false
797 oFsm.mutexFlowParams.Lock()
798 defer oFsm.mutexFlowParams.Unlock()
799 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
800 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
801 flowEntryMatch = true
802 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
803 "device-id": oFsm.deviceID})
804 cookieMatch := false
805 for _, cookie := range storedUniFlowParams.CookieSlice {
806 if cookie == aCookie {
807 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
808 "device-id": oFsm.deviceID, "cookie": cookie})
809 cookieMatch = true
810 break //found new cookie - no further search for this requested cookie
811 }
812 }
813 if !cookieMatch {
814 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
815 "device-id": oFsm.deviceID, "cookie": aCookie})
816 //as range works with copies of the slice we have to write to the original slice!!
817 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
818 aCookie)
819 return true, false //flowModified, NoRuleAppend
820 }
821 break // found rule - no further rule search
822 }
823 }
824 if !flowEntryMatch { //it is a new rule
825 return true, true //flowModified, RuleAppend
826 }
827 return false, false //flowNotModified, NoRuleAppend
828}
829
830// VOL-3828 flow config sequence workaround ########### end ##########
831
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530832// RemoveUniFlowParams verifies on existence of flow cookie,
mpagenko01e726e2020-10-23 09:45:29 +0000833// if found removes cookie from flow cookie list and if this is empty
834// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700835func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000836 if oFsm == nil {
837 logger.Error(ctx, "no valid UniVlanConfigFsm!")
838 return fmt.Errorf("no-valid-UniVlanConfigFsm")
839 }
mpagenkof1fc3862021-02-16 10:09:52 +0000840 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000841 flowCookieMatch := false
842 //mutex protection is required for possible concurrent access to FSM members
843 oFsm.mutexFlowParams.Lock()
844 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000845remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000846 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
847 for i, cookie := range storedUniFlowParams.CookieSlice {
848 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000849 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000850 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000851 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000852 //remove the cookie from the cookie slice and verify it is getting empty
853 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000854 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700855 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000856 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000857 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000858 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000859 //cut off the requested cookie by slicing out this element
860 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
861 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
862 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000863 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
864 // state transition notification is checked in deviceHandler
865 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000866 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
867 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000868 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000869 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000870 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000871 if deletedCookie == oFsm.delayNewRuleCookie {
872 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
873 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
874 //simply use the first one
875 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
876 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
877 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
878 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700879 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000880 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000881 //permanently store the modified flow config for reconcile case and immediately write to KvStore
882 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000883 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000884 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
885 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
886 return err
887 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000888 }
mpagenko01e726e2020-10-23 09:45:29 +0000889 }
mpagenkof1fc3862021-02-16 10:09:52 +0000890 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000891 }
892 }
mpagenko01e726e2020-10-23 09:45:29 +0000893 } //search all flows
894 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000896 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
897 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000898 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
899 // state transition notification is checked in deviceHandler
900 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000901 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000902 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000903 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700904 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000905 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000906 return nil
907 } //unknown cookie
908
909 return nil
910}
911
mpagenkof582d6a2021-06-18 15:58:10 +0000912// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000913// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000914func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700915 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000916 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mgoudad611f4c2025-10-30 14:49:27 +0530917 var cancelPendingConfig = false
918 var loRemoveParams = uniRemoveVlanFlowParams{}
mpagenkof582d6a2021-06-18 15:58:10 +0000919 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
920 "device-id": oFsm.deviceID})
921 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
922 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
923 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
924 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000925 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000926 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
927 log.Fields{"device-id": oFsm.deviceID})
928 cancelPendingConfig = true
929 } else {
930 //create a new element for the removeVlanFlow slice
931 loRemoveParams = uniRemoveVlanFlowParams{
932 vlanRuleParams: aUniFlowParams.VlanRuleParams,
933 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700934 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000935 }
936 loRemoveParams.removeChannel = make(chan bool)
937 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
938 }
939
940 usedTpID := aUniFlowParams.VlanRuleParams.TpID
941 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
942 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
943 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
944 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000945 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
946 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000947 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
948 "device-id": oFsm.deviceID})
949 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000950 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000951 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000952 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000953 }
954 } else {
955 if !cancelPendingConfig {
956 oFsm.updateTechProfileToDelete(ctx, usedTpID)
957 }
958 }
959 //trigger the FSM to remove the relevant rule
960 if cancelPendingConfig {
961 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000963 //call from 'non-configured' state of the rules
964 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
965 //something quite inconsistent detected, perhaps just try to recover with FSM reset
966 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000968 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
969 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
970 }
971 return false //data base update could not be done, return like cookie not found
972 }
973
974 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
975 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
976 // synchronous FSM 'event/state' functions may rely on this mutex
977 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000979 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
980 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
981 }
982 oFsm.mutexFlowParams.Lock()
983 return true
984 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000985 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000986 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000987 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000988 "tp-id": loRemoveParams.vlanRuleParams.TpID,
989 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
990 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
991 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
992 // synchronous FSM 'event/state' functions may rely on this mutex
993 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000995 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
996 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
997 }
998 oFsm.mutexFlowParams.Lock()
bseeniva34743192025-07-24 14:42:56 +0530999 return true
mpagenkof582d6a2021-06-18 15:58:10 +00001000 } // if not in the appropriate state a new entry will be automatically considered later
1001 // when the configDone state is reached
bseeniva34743192025-07-24 14:42:56 +05301002 // If the FSM is in Disabled or resetted state, push a response on the flow response channel
1003 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkof582d6a2021-06-18 15:58:10 +00001004 return true
1005}
1006
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301007// removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1008//
1009// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1010// from the start of the deletion request to avoid to much interference
1011// so when called, there can only be one cookie active for this flow
1012//
mpagenkof1d21d12021-06-11 13:14:45 +00001013// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001014func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001015 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1016 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001017 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001018removeFromSlice_loop:
1019 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001020 // if UniFlowParams exists, cookieSlice should always have at least one element
1021 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
mgoudad611f4c2025-10-30 14:49:27 +05301022 switch cookieSliceLen {
1023 case 1:
mpagenkof582d6a2021-06-18 15:58:10 +00001024 if storedUniFlowParams.CookieSlice[0] == aCookie {
1025 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001026 }
mgoudad611f4c2025-10-30 14:49:27 +05301027 case 0:
mpagenkof582d6a2021-06-18 15:58:10 +00001028 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1029 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1030 return errors.New(errStr)
mgoudad611f4c2025-10-30 14:49:27 +05301031 default:
mpagenkof582d6a2021-06-18 15:58:10 +00001032 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1033 logger.Errorw(ctx, errStr, log.Fields{
1034 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1035 for _, cookie := range storedUniFlowParams.CookieSlice {
1036 if cookie == aCookie {
1037 cookieFound = true
1038 break
1039 }
1040 }
1041 }
1042 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001043 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1044 "device-id": oFsm.deviceID, "cookie": aCookie})
1045 //remove the actual element from the addVlanFlow slice
1046 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1047 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001048 oFsm.NumUniFlows = 0 //no more flows
1049 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001050 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1051 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1052 //request that this profile gets deleted before a new flow add is allowed
1053 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1054 "device-id": oFsm.deviceID})
1055 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001056 oFsm.NumUniFlows--
1057 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1058 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001059 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001060 if !aWasConfigured {
1061 // We did not actually process this flow but was removed before that.
1062 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001063 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001064 }
1065
mpagenkof1d21d12021-06-11 13:14:45 +00001066 //cut off the requested flow by slicing out this element
1067 oFsm.uniVlanFlowParamsSlice = append(
1068 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1069 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1070 "device-id": oFsm.deviceID})
1071 }
1072 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1073 }
1074 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001075 if !cookieFound {
1076 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1077 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1078 return errors.New(errStr)
1079 }
mpagenkodee02a62021-07-21 10:56:10 +00001080 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1081 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001082 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001083 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1084 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1085 return err
1086 }
mpagenkof582d6a2021-06-18 15:58:10 +00001087 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001088}
1089
1090// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001091func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1092 //here we have to check, if there are still other flows referencing to the actual ProfileId
1093 // before we can request that this profile gets deleted before a new flow add is allowed
1094 tpIDInOtherFlows := false
1095 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1096 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1097 tpIDInOtherFlows = true
1098 break // search loop can be left
1099 }
1100 }
1101 if tpIDInOtherFlows {
1102 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1103 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1104 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001105 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore - set TechProfile to-delete", log.Fields{
mpagenkof1fc3862021-02-16 10:09:52 +00001106 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001107 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1108 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001109 if oFsm.pUniTechProf != nil {
1110 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001111 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001112 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001113 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001114 }
1115}
1116
mpagenkof1d21d12021-06-11 13:14:45 +00001117func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1118 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001119
1120 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001121 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001122 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001123 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001124 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001125 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001126 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001128 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001129 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001130 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001131 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001132 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001133 go func(a_pAFsm *cmn.AdapterFsm) {
1134 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001135 }(pConfigVlanStateAFsm)
1136 return
1137 }
mpagenkof1d21d12021-06-11 13:14:45 +00001138 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001139 go func(a_pAFsm *cmn.AdapterFsm) {
1140 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001141 }(pConfigVlanStateAFsm)
1142 return
1143 }
1144 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1145 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1146 //should never happen, else: recovery would be needed from outside the FSM
1147}
1148
1149func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1150 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001151 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001152 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001153 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001154 //possibly the entry is not valid anymore based on intermediate delete requests
1155 //just a basic protection ...
1156 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1157 oFsm.mutexFlowParams.Unlock()
1158 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1159 "device-id": oFsm.deviceID})
1160 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001161 go func(a_pAFsm *cmn.AdapterFsm) {
1162 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001163 }(pConfigVlanStateAFsm)
1164 return
1165 }
mpagenko9a304ea2020-12-16 15:54:01 +00001166 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1167 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001168 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1169 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001170 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001171 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001172 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1173 // synchronous FSM 'event/state' functions may rely on this mutex
1174 // but it must be released already before calling getTechProfileDone() as it may already be locked
1175 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001176 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001177 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001178 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001179 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001180 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001181
mpagenko9a304ea2020-12-16 15:54:01 +00001182 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001183 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1184 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001185 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001186 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001187 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001188 } else {
1189 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001190 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001191 }
1192 }
mpagenko551a4d42020-12-08 18:09:20 +00001193 }(pConfigVlanStateAFsm, loTechProfDone)
1194 } else {
1195 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1196 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1197 //should never happen, else: recovery would be needed from outside the FSM
1198 return
mpagenkodff5dda2020-08-28 11:52:01 +00001199 }
1200}
1201
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001203 //mutex protection is required for possible concurrent access to FSM members
1204 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001205 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001206 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001207 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001208 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001210 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001211 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001212 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001213 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001214 go func(a_pAFsm *cmn.AdapterFsm) {
1215 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001216 }(pConfigVlanStateAFsm)
1217 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001218 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1219 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001220 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001221 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001222 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001223 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001224 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001225 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001226 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001227 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001228 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001229 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1230 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001231 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001232 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001233 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001234 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1235 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1236 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001237 },
1238 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001239 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001240 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001241 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001242 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1243 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001244 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001245 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001246 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1247 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001248 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001249 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001250 go func(a_pAFsm *cmn.AdapterFsm) {
1251 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001252 }(pConfigVlanStateAFsm)
1253 }
1254 return
1255 }
mpagenkodff5dda2020-08-28 11:52:01 +00001256 //accept also nil as (error) return value for writing to LastTx
1257 // - this avoids misinterpretation of new received OMCI messages
1258 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1259 // send shall return (dual format) error code that can be used here for immediate error treatment
1260 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001261 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001262 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001263 }
1264}
1265
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301266//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1268 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001269 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001270 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001271 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001272 //using the first element in the slice because it's the first flow per definition here
1273 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001274 //This is correct passing scenario
1275 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001276 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001277 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1278 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001280 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1281 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001284 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001285 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001286 vlanID)
1287 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001288 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001289 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001290 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001291 }
1292 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001293 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001294 if oFsm.actualUniFlowParam.Meter != nil {
1295 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001297 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1298 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001300 if errCreateTrafficDescriptor != nil {
1301 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1302 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001304 }
1305 }
1306 }
1307
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001308 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001309 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001310 }
1311 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001312}
1313
dbainbri4d3a0dc2020-12-02 00:33:42 +00001314func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001315
mpagenkof1d21d12021-06-11 13:14:45 +00001316 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001317
mpagenkof1fc3862021-02-16 10:09:52 +00001318 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001319 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001321 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001322 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001323 }
1324
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001325 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001326 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001327 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001328 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1329 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1330 //should never happen, else: recovery would be needed from outside the FSM
1331 return
1332 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001334 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1335 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001336 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001338 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1339 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001340 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001341 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001342 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001343 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001344 }(pConfigVlanStateBaseFsm)
1345 return
1346 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001347 if oFsm.lastFlowToReconcile {
1348 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1349 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1350 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1351 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1352 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1353 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301354 if oFsm.lastFlowToConfigOnReboot {
1355 logger.Debugw(ctx, "rebooting - flow processing finished", log.Fields{
1356 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1357 oFsm.pDeviceHandler.SendChUniVlanConfigFinishedOnReboot(uint16(oFsm.pOnuUniPort.UniID))
1358 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001359 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1360 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001361 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001362 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001363 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001364 return
1365 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1367 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001368 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001369 // this is a restart with a complete new flow, we can re-use the initial flow config control
1370 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001371 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001372 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001373 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001374 }(pConfigVlanStateBaseFsm)
1375 return
1376 }
1377
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001378 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001379 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001380 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001381 //check introduced after having observed some panic in this processing
1382 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001383 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001384 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1385 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 go func(a_pAFsm *cmn.AdapterFsm) {
1387 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001388 }(pConfigVlanStateAFsm)
1389 return
1390 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001391 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001392 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001393 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001394 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001395 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001396 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1397 // synchronous FSM 'event/state' functions may rely on this mutex
1398 // but it must be released already before calling getTechProfileDone() as it may already be locked
1399 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1400 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001401 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001402 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001404 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1405
mpagenko9a304ea2020-12-16 15:54:01 +00001406 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001407 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1408 if aTechProfDone {
1409 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001411 } else {
1412 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001414 }
1415 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001416 return
1417 }
mpagenkof1d21d12021-06-11 13:14:45 +00001418 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001420 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001421 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1422 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001423 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001424 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001425 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001426 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001427 }
1428}
1429
dbainbri4d3a0dc2020-12-02 00:33:42 +00001430func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001431
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001432 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001433 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001434 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001435 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1437 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001438 return
1439 }
mpagenko15ff4a52021-03-02 10:09:20 +00001440 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001442 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001443 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001444 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001445
Girish Gowdrae95687a2021-09-08 16:30:58 -07001446 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001447 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001449 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001450 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001451 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1452 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1453 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1454 // in practice should have no influence by now as no other state transition is currently accepted (while cancel() is ensured)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001455 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001456 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1457 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001458 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001459 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001460 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001461 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001462 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001463 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001464 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001465 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001466
mpagenko01e726e2020-10-23 09:45:29 +00001467 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001468 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1469 oFsm.numVlanFilterEntries = 1
1470 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001471 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001472 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001473 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1474 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1475 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001476 },
1477 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001478 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001479 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1480 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001481 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001482 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001483 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001484 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1485 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001487 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001488 go func(a_pAFsm *cmn.AdapterFsm) {
1489 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001490 }(pConfigVlanStateAFsm)
1491 }
1492 return
1493 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001494 //accept also nil as (error) return value for writing to LastTx
1495 // - this avoids misinterpretation of new received OMCI messages
1496 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1497 // send shall return (dual format) error code that can be used here for immediate error treatment
1498 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001499 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001500 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001501 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001502 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1503 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001504 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001505
dbainbri4d3a0dc2020-12-02 00:33:42 +00001506 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001507 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001508 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001509 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001510 // setVid is assumed to be masked already by the caller to 12 bit
1511 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001512 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001513 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001514
1515 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1516 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1517 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001518 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001519
1520 oFsm.numVlanFilterEntries++
1521 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001522 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001523 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001524 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1525 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1526 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001527 },
1528 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001529 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001530 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1531 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001532 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001533 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001534 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001535 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1536 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001538 return
1539 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001540 //accept also nil as (error) return value for writing to LastTx
1541 // - this avoids misinterpretation of new received OMCI messages
1542 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1543 // send shall return (dual format) error code that can be used here for immediate error treatment
1544 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001545 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001546 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001547 }
1548 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001550 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001551 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001553 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001554 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001555 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001556 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001557 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001558 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001559 return
1560 }
1561 }
mpagenkof1d21d12021-06-11 13:14:45 +00001562
mpagenkof1fc3862021-02-16 10:09:52 +00001563 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001564 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001565 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001566 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001567 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1568 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001569 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001570 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001571 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001572 //This is correct passing scenario
1573 if errEvto == nil {
1574 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001576 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001577 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001579 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001580 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001581 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001583 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001585 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001587 }
1588 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001589 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001590 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001591 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001592 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1593 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001594 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001595 if errCreateTrafficDescriptor != nil {
1596 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1597 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001598 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001599 }
1600 }
1601 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001602 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001603 }
1604 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001605}
1606
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001608 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001609 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001610 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1611 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001612
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1614 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001615 loVlanEntryClear := uint8(0)
1616 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1617 //shallow copy is sufficient as no reference variables are used within struct
1618 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001619 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001621 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1622 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1623 "device-id": oFsm.deviceID})
1624
1625 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1626 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001628 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1629 } else {
1630 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1631 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001633 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1634 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001636 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001637 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001639 loVlanEntryClear = 1 //full VlanFilter clear request
1640 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001641 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001642 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1643 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001644 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001645 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001646 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1647 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001648 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001649 return
1650 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001651 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001652 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001653 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001656 }
mpagenko01e726e2020-10-23 09:45:29 +00001657 } else {
1658 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1659 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001661 log.Fields{"current vlan list": oFsm.vlanFilterList,
1662 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1663 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1664 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1665 loVlanEntryRmPos = i
1666 break //abort search
1667 }
1668 }
1669 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001671 //valid entry was found - to be eclipsed
1672 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1673 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1674 if i < loVlanEntryRmPos {
1675 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1676 } else if i < (cVtfdTableSize - 1) {
1677 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1678 } else {
1679 vtfdFilterList[i] = 0 //set last byte if needed
1680 }
1681 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001683 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001684 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001685 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001686
mpagenkofc4f56e2020-11-04 17:17:49 +00001687 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001688 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001689 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001690 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1691 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001692 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001693 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001694 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1695 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001696 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001697 return
1698 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001700 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001701 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001703 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001704 }
mpagenko01e726e2020-10-23 09:45:29 +00001705 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001707 log.Fields{"device-id": oFsm.deviceID})
1708 }
1709 }
1710 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001711 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1712 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001714 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001715 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001716 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001717 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001718 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001719 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001720 }(pConfigVlanStateBaseFsm)
1721 return
1722 }
mpagenko01e726e2020-10-23 09:45:29 +00001723 }
1724
mpagenko15ff4a52021-03-02 10:09:20 +00001725 oFsm.mutexFlowParams.Lock()
mgoudad611f4c2025-10-30 14:49:27 +05301726 switch loVlanEntryClear {
1727 case 1:
mpagenko01e726e2020-10-23 09:45:29 +00001728 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1729 oFsm.numVlanFilterEntries = 0
mgoudad611f4c2025-10-30 14:49:27 +05301730 case 2:
mpagenko01e726e2020-10-23 09:45:29 +00001731 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1732 // this loop now includes the 0 element on previous last valid entry
1733 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1734 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1735 }
1736 oFsm.numVlanFilterEntries--
1737 }
mpagenko15ff4a52021-03-02 10:09:20 +00001738 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001739 }
1740 }
1741
mpagenkofc4f56e2020-11-04 17:17:49 +00001742 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001743 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001744 } else {
1745 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001747 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001748 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001749 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001750 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001751 }(pConfigVlanStateBaseFsm)
1752 }
mpagenkodff5dda2020-08-28 11:52:01 +00001753}
1754
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001756 var tpID uint8
1757 // Extract the tpID
1758 if len(e.Args) > 0 {
1759 tpID = e.Args[0].(uint8)
1760 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1761 } else {
1762 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1763 }
mpagenko01e726e2020-10-23 09:45:29 +00001764 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001765 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001766
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001767 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001768 if pConfigVlanStateAFsm == nil {
1769 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1770 log.Fields{"device-id": oFsm.deviceID})
1771 //would have to be fixed from outside somehow
1772 return
1773 }
1774
mpagenkof1d21d12021-06-11 13:14:45 +00001775 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1776 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001777 //call from 'configured' state of the rule
1778 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1779 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1780 oFsm.mutexFlowParams.Unlock()
1781 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001782 go func(a_pAFsm *cmn.AdapterFsm) {
1783 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001784 }(pConfigVlanStateAFsm)
1785 return
1786 }
mpagenkof1d21d12021-06-11 13:14:45 +00001787 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1788 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1789 oFsm.mutexFlowParams.Unlock()
1790 removeChannel <- true
1791 oFsm.mutexFlowParams.Lock()
1792 }
1793
mpagenkof1fc3862021-02-16 10:09:52 +00001794 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1795 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1796 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1797
Girish Gowdrae95687a2021-09-08 16:30:58 -07001798 // Store the reference to the flow response channel before this entry in the slice is deleted
1799 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1800
mpagenko01e726e2020-10-23 09:45:29 +00001801 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1802 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001804 "device-id": oFsm.deviceID})
1805 } else {
1806 //cut off the actual flow by slicing out the first element
1807 oFsm.uniRemoveFlowsSlice = append(
1808 oFsm.uniRemoveFlowsSlice[:0],
1809 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001811 "device-id": oFsm.deviceID})
1812 }
1813 oFsm.mutexFlowParams.Unlock()
1814
mpagenkof1fc3862021-02-16 10:09:52 +00001815 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001816 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001817 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001818 go func(a_pAFsm *cmn.AdapterFsm) {
1819 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001820 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001821
mpagenkobb47bc22021-04-20 13:29:09 +00001822 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001823 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001824 if deletedCookie == oFsm.delayNewRuleCookie {
1825 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1826 select {
1827 case <-oFsm.chCookieDeleted:
1828 logger.Debug(ctx, "flushed CookieDeleted")
1829 default:
1830 }
1831 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1832 }
mpagenkobb47bc22021-04-20 13:29:09 +00001833 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1834 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1835 logger.Debugw(ctx, "signal flow removal for pending TP delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
Girish Gowdra26a40922021-01-29 17:14:34 -08001836 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001837 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1838 oFsm.flowDeleteChannel <- true
1839 oFsm.signalOnFlowDelete = false
1840 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001841 }
mpagenkobb47bc22021-04-20 13:29:09 +00001842 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001843
1844 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001845 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001846}
1847
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301848//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001849func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1850 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001851
mpagenko0f543222021-11-03 16:24:14 +00001852 oFsm.mutexPLastTxMeInstance.Lock()
1853 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1854 oFsm.mutexPLastTxMeInstance.Unlock()
1855
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001856 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001857 if pConfigVlanStateAFsm != nil {
1858 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001859 fsmAbortMsg := cmn.Message{
1860 Type: cmn.TestMsg,
1861 Data: cmn.TestMessage{
1862 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001863 },
1864 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001865 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001866
mpagenko0f543222021-11-03 16:24:14 +00001867 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1868 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1869
1870 oFsm.mutexFlowParams.RLock()
1871 if oFsm.delayNewRuleCookie != 0 {
1872 // looks like the waiting AddFlow is stuck
1873 oFsm.mutexFlowParams.RUnlock()
1874 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1875 select {
1876 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1877 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001878 }
mpagenko0f543222021-11-03 16:24:14 +00001879 oFsm.mutexFlowParams.RLock()
1880 }
1881 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1882 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1883 if removeUniFlowParams.isSuspendedOnAdd {
1884 removeChannel := removeUniFlowParams.removeChannel
1885 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1886 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1887 oFsm.mutexFlowParams.RUnlock()
1888 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1889 select {
1890 case removeChannel <- false:
1891 default:
1892 }
1893 oFsm.mutexFlowParams.RLock()
1894 }
1895 // Send response on response channel if the caller is waiting on it.
1896 var err error = nil
1897 if !oFsm.isCanceled {
1898 //only if the FSM is not canceled on external request use some error indication for the respChan
1899 // so only at real internal FSM abortion some error code is sent back
1900 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1901 err = fmt.Errorf("internal-error")
1902 }
1903 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1904 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1905 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1906 }
1907 }
1908
1909 if oFsm.pDeviceHandler != nil {
1910 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1911 if !oFsm.isCanceled {
1912 //if the FSM is not canceled on external request use "internal-error" for the respChan
1913 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1914 // Send response on response channel if the caller is waiting on it with according error indication.
1915 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1916 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301917 // Do not remove pers uni data during reset of FSM. It will be removed when the device is deleted
1918 //var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1919 //_ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
mpagenko0f543222021-11-03 16:24:14 +00001920 } else {
1921 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1922 // no need to remove specific data in this case here
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +05301923 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1924 // Send response on response channel if the caller is waiting on it with according error indication.
1925 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("config-cancelled"))
1926 }
mpagenko0f543222021-11-03 16:24:14 +00001927 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1928 }
1929 }
1930 oFsm.mutexFlowParams.RUnlock()
1931
1932 //try to let the FSM proceed to 'disabled'
1933 // Can't call FSM Event directly, decoupling it
1934 go func(a_pAFsm *cmn.AdapterFsm) {
1935 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1936 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1937 }
1938 }(pConfigVlanStateAFsm)
1939 return
1940 }
1941 oFsm.mutexFlowParams.RUnlock()
1942 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1943 log.Fields{"device-id": oFsm.deviceID})
1944 return
mpagenkodff5dda2020-08-28 11:52:01 +00001945 }
mpagenko0f543222021-11-03 16:24:14 +00001946 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1947 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001948}
1949
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301950//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1952 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001953
mpagenkodff5dda2020-08-28 11:52:01 +00001954 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001955 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001957 return
mpagenkodff5dda2020-08-28 11:52:01 +00001958 }
mpagenko0f543222021-11-03 16:24:14 +00001959 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1960 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001961}
1962
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1964 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001965loop:
1966 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001967 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001969 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001970 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301971 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301973 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301975 break loop
1976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301978
1979 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001980 case cmn.TestMsg:
1981 msg, _ := message.Data.(cmn.TestMessage)
1982 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001984 break loop
1985 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001987 case cmn.OMCI:
1988 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301990 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301992 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001993 }
1994 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001996}
1997
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001998func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00002000 "msgType": msg.OmciMsg.MessageType})
2001
2002 switch msg.OmciMsg.MessageType {
2003 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00002004 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002006 logger.Warnw(ctx, "CreateResponse handling aborted",
2007 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00002008 return
2009 }
mpagenkodff5dda2020-08-28 11:52:01 +00002010 } //CreateResponseType
2011 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00002012 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00002013 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
2014 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002016 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002017 return
2018 }
2019 msgObj, msgOk := msgLayer.(*omci.SetResponse)
2020 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002021 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002022 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002023 return
2024 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002026 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002027 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002028 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002029 // possibly force FSM into abort or ignore some errors for some messages?
2030 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2031 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002032 return
2033 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002034 oFsm.mutexPLastTxMeInstance.RLock()
2035 if oFsm.pLastTxMeInstance != nil {
2036 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2037 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2038 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002039 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002040 { // let the MultiEntity config proceed by stopping the wait function
2041 oFsm.mutexPLastTxMeInstance.RUnlock()
2042 oFsm.omciMIdsResponseReceived <- true
2043 return
2044 }
2045 default:
2046 {
2047 logger.Warnw(ctx, "Unsupported ME name received!",
2048 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2049 }
mpagenkodff5dda2020-08-28 11:52:01 +00002050 }
2051 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002052 } else {
2053 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002054 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002055 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002056 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002057 case omci.DeleteResponseType:
2058 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002060 logger.Warnw(ctx, "DeleteResponse handling aborted",
2061 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002062 return
2063 }
2064 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002065 default:
2066 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002068 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002069 return
2070 }
2071 }
2072}
2073
dbainbri4d3a0dc2020-12-02 00:33:42 +00002074func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002075 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2076 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002077 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002078 log.Fields{"device-id": oFsm.deviceID})
2079 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2080 oFsm.deviceID)
2081 }
2082 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2083 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002085 log.Fields{"device-id": oFsm.deviceID})
2086 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2087 oFsm.deviceID)
2088 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002090 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002091 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002092 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002093 // possibly force FSM into abort or ignore some errors for some messages?
2094 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2095 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002096 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2097 oFsm.deviceID)
2098 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002099 oFsm.mutexPLastTxMeInstance.RLock()
2100 if oFsm.pLastTxMeInstance != nil {
2101 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2102 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2103 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2104 switch oFsm.pLastTxMeInstance.GetName() {
2105 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2106 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002107 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002108 {
2109 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002110 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002111 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002112 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002113 } else { // let the MultiEntity config proceed by stopping the wait function
2114 oFsm.omciMIdsResponseReceived <- true
2115 }
2116 return nil
2117 }
2118 default:
2119 {
2120 logger.Warnw(ctx, "Unsupported ME name received!",
2121 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002122 }
2123 }
2124 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002125 } else {
2126 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002127 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002128 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002129 return nil
2130}
2131
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002133 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2134 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002136 log.Fields{"device-id": oFsm.deviceID})
2137 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2138 oFsm.deviceID)
2139 }
2140 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2141 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002143 log.Fields{"device-id": oFsm.deviceID})
2144 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2145 oFsm.deviceID)
2146 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05302148 if msgObj.Result == me.UnknownInstance {
2149 logger.Warnw(ctx, "UniVlanConfigFsm - Unknow Instance",
2150 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
2151 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002153 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002154 // possibly force FSM into abort or ignore some errors for some messages?
2155 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2156 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002157 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2158 oFsm.deviceID)
2159 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002160 oFsm.mutexPLastTxMeInstance.RLock()
2161 if oFsm.pLastTxMeInstance != nil {
2162 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2163 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2164 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002165 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002166 { // let the MultiEntity config proceed by stopping the wait function
2167 oFsm.mutexPLastTxMeInstance.RUnlock()
2168 oFsm.omciMIdsResponseReceived <- true
2169 return nil
2170 }
2171 default:
2172 {
2173 logger.Warnw(ctx, "Unsupported ME name received!",
2174 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2175 }
mpagenko01e726e2020-10-23 09:45:29 +00002176 }
2177 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002178 } else {
2179 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002180 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002181 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002182 return nil
2183}
2184
dbainbri4d3a0dc2020-12-02 00:33:42 +00002185func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002186 oFsm.mutexFlowParams.RLock()
2187 evtocdID := oFsm.evtocdID
2188 oFsm.mutexFlowParams.RUnlock()
2189
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002190 if aFlowEntryNo == 0 {
2191 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002192 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2193 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002195 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002196 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002197 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002198 associationType := 2 // default to UniPPTP
2199 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002200 associationType = 10
2201 }
2202 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002203 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002204 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002205 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002206 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2207 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002208 },
2209 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002210 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2212 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002213 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002214 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002215 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2216 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002217 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002218 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2219 }
mpagenkodff5dda2020-08-28 11:52:01 +00002220 //accept also nil as (error) return value for writing to LastTx
2221 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002222 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002223 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002224
2225 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002226 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002227 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002228 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002229 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002230 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002231 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2232 }
2233
2234 // Set the EVTOCD ME default params
2235 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002236 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002237 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002238 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2239 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2240 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002241 },
2242 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002243 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002244 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2245 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2246 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002247 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002248 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002249 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2250 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002252 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2253 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002254 //accept also nil as (error) return value for writing to LastTx
2255 // - this avoids misinterpretation of new received OMCI messages
2256 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002257 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002258
2259 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002261 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002263 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002264 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002265 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002266 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002267 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002268
mpagenko551a4d42020-12-08 18:09:20 +00002269 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302270 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2271 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002272 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002273 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002274 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002275 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002276 sliceEvtocdRule := make([]uint8, 16)
2277 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2278 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2279 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2280 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2281 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2282
2283 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2284 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2285 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2286 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2287 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2288
2289 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2290 0<<cTreatTTROffset| // Do not pop any tags
2291 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2292 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2293 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2294
2295 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2296 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2297 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2298 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2299
2300 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002301 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002302 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002303 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002304 },
2305 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002306 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002307 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2308 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2309 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002311 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002312 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2313 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002315 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2316 }
mpagenkodff5dda2020-08-28 11:52:01 +00002317 //accept also nil as (error) return value for writing to LastTx
2318 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002319 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002320 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002321
2322 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002323 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002324 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002326 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002327 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002328 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2329
mpagenkodff5dda2020-08-28 11:52:01 +00002330 }
2331 } else {
2332 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2333 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002334 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2335 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2336 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2337 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302338 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002339 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002340
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302341 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2342 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2343 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
bseeniva5f32c452025-07-18 17:30:41 +05302344 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID,
2345 "tags-to-remove": oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove})
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302346 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2347 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2348 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2349 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2350 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002351
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302352 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2353 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2354 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2355 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2356 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002357
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302358 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2359 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2360 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2361 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2362 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2363
2364 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2365 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2366 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2367 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2368
2369 } else {
2370 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2371 //As of now only a match and no action can be done on the inner tag .
2372 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2373 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2374 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2375 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2376 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2377 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2378 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2379
2380 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2381 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2382 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2383 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2384 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2385
2386 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2387 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2388 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2389 setVid<<cTreatVidOffset| // Set VID
2390 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2391
2392 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2393 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2394 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2395 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2396 }
mpagenko551a4d42020-12-08 18:09:20 +00002397 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002398 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002399 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002400 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002401 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002402 },
2403 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002404 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002405 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2406 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2407 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002408 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002409 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002410 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2411 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002412 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002413 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2414 }
mpagenkodff5dda2020-08-28 11:52:01 +00002415 //accept also nil as (error) return value for writing to LastTx
2416 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002417 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002418 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002419
2420 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002421 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002422 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302423 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002424 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002425 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302426 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002427 }
2428 } else {
2429 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2430 { // just for local var's
2431 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002432 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002433 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002434 sliceEvtocdRule := make([]uint8, 16)
2435 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2436 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2437 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2438 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2439 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2440
2441 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2442 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2443 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2444 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2445 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2446
2447 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2448 0<<cTreatTTROffset| // Do not pop any tags
2449 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2450 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2451 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2452
2453 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2454 0<<cTreatPrioOffset| // vlan prio set to 0
2455 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002456 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002457 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2458
mpagenko551a4d42020-12-08 18:09:20 +00002459 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002460 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002461 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002462 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002463 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002464 },
2465 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002466 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2468 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2469 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002470 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002471 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002472 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2473 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002474 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002475 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2476 }
mpagenkodff5dda2020-08-28 11:52:01 +00002477 //accept also nil as (error) return value for writing to LastTx
2478 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002479 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002480 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002481
2482 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002483 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002484 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002486 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002487 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002488 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2489
mpagenkodff5dda2020-08-28 11:52:01 +00002490 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002491 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002492 { // just for local var's
2493 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002494 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002495 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002496 sliceEvtocdRule := make([]uint8, 16)
2497 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2498 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2499 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2500 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2501 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2502
2503 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2504 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2505 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2506 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2507 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2508
2509 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2510 1<<cTreatTTROffset| // pop the prio-tag
2511 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2512 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2513 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2514
mpagenko551a4d42020-12-08 18:09:20 +00002515 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002516 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2517 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2518 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002519 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002520 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002521 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002522
2523 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002524 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002525 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002526 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002527 },
2528 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002529 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002530 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2531 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2532 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002533 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002534 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002535 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2536 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002537 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002538 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2539 }
mpagenkodff5dda2020-08-28 11:52:01 +00002540 //accept also nil as (error) return value for writing to LastTx
2541 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002542 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002543 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002544
2545 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002546 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002547 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002548 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002549 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002550 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002551 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2552
mpagenkodff5dda2020-08-28 11:52:01 +00002553 }
2554 } //just for local var's
2555 }
2556 }
2557
mpagenkofc4f56e2020-11-04 17:17:49 +00002558 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002560 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002562 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002563 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002564}
2565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002566func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002567 oFsm.mutexFlowParams.RLock()
2568 evtocdID := oFsm.evtocdID
2569 oFsm.mutexFlowParams.RUnlock()
2570
mpagenko01e726e2020-10-23 09:45:29 +00002571 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2572 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2573 //transparent transmission was set
2574 //perhaps the config is not needed for removal,
2575 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002576 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002577 "device-id": oFsm.deviceID})
2578 sliceEvtocdRule := make([]uint8, 16)
2579 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2580 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2581 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2582 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2583 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2584
2585 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2586 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2587 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2588 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2589 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2590
2591 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2592 0<<cTreatTTROffset| // Do not pop any tags
2593 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2594 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2595 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2596
2597 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2598 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2599 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2600 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2601
2602 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002603 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002604 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002605 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002606 },
2607 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002608 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002609 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2610 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2611 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002612 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002613 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002614 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2615 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002617 return
2618 }
mpagenko01e726e2020-10-23 09:45:29 +00002619 //accept also nil as (error) return value for writing to LastTx
2620 // - this avoids misinterpretation of new received OMCI messages
2621 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002622 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002623
2624 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002625 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002626 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002627 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002628 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002629 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002630 return
2631 }
2632 } else {
2633 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002634 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002635 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002636 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002637 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302638 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002639
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302640 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2641 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2642 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2643 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2644 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2645 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2646 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2647 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002648
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302649 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2650 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2651 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2652 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2653 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002654
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302655 // delete indication for the indicated Filter
2656 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2657 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2658
2659 } else {
2660 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2661 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2662 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302663 sliceEvtocdRule = make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302664 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2665 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2666 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2667 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2668 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2669
2670 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2671 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2672 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2673 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2674 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2675
2676 // delete indication for the indicated Filter
2677 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2678 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2679 }
mpagenko01e726e2020-10-23 09:45:29 +00002680 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002681 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002682 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002683 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002684 },
2685 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002686 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002687 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2688 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2689 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002690 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002691 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002692 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2693 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002694 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002695 return
2696 }
mpagenko01e726e2020-10-23 09:45:29 +00002697 //accept also nil as (error) return value for writing to LastTx
2698 // - this avoids misinterpretation of new received OMCI messages
2699 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002700 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002701
2702 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002703 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002704 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302705 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2706 log.Fields{"device-id": oFsm.deviceID,
2707 "match-vlan": aRuleParams.MatchVid,
2708 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002710 return
2711 }
2712 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002713 // VOL-3685
2714 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2715 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2716 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2717 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2718 // later when the flow is being re-installed.
2719 // Of course this is applicable to case only where single service (or single tcont) is in use and
2720 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2721 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2722 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002723 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002724 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002725 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002726 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2727 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002728 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002729 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002730 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002731 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2733 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2734 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002735 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002736 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002737 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2738 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002739 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002740 return
2741 }
mpagenko01e726e2020-10-23 09:45:29 +00002742 //accept also nil as (error) return value for writing to LastTx
2743 // - this avoids misinterpretation of new received OMCI messages
2744 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002745 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002746
2747 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002748 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002749 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002750 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002751 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002752 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002753 return
2754 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 } else {
2756 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2757 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002758 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002759 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002760 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002761 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2762 { // just for local var's
2763 // this defines stacking scenario: untagged->singletagged
2764 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2765 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2766 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2767 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002768 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002769 "device-id": oFsm.deviceID})
2770 sliceEvtocdRule := make([]uint8, 16)
2771 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2772 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2773 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2774 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2775 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002776
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002777 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2778 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2779 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2780 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2781 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002782
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002783 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2784 0<<cTreatTTROffset| // Do not pop any tags
2785 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2786 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2787 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002788
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002789 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2790 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2791 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2792 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002793
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002794 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002795 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002796 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002797 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002798 },
2799 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002800 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002801 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2802 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2803 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002804 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002805 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002806 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2807 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002808 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002809 return
2810 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002811 //accept also nil as (error) return value for writing to LastTx
2812 // - this avoids misinterpretation of new received OMCI messages
2813 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002814 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002815
2816 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002817 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002818 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002820 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002822 return
2823 }
2824 } // just for local var's
2825 { // just for local var's
2826 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002828 "device-id": oFsm.deviceID})
2829 sliceEvtocdRule := make([]uint8, 16)
2830 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2831 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2832 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2833 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2834 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2835
2836 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2837 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2838 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2839 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2840 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2841
2842 // delete indication for the indicated Filter
2843 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2844 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2845
2846 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002847 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002849 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002850 },
2851 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002852 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2854 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2855 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002856 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002857 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002858 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2859 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002860 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002861 return
2862 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002863 //accept also nil as (error) return value for writing to LastTx
2864 // - this avoids misinterpretation of new received OMCI messages
2865 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002866 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867
2868 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002869 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002870 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002872 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002873 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002874 return
2875 }
mpagenko01e726e2020-10-23 09:45:29 +00002876 }
2877 } //just for local var's
2878 }
2879 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002880 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002883}
2884
dbainbri4d3a0dc2020-12-02 00:33:42 +00002885func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002886 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002887 if oFsm.isCanceled {
2888 // FSM already canceled before entering wait
2889 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2890 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002891 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002892 }
mpagenko7d6bb022021-03-11 15:07:55 +00002893 oFsm.isAwaitingResponse = true
2894 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002895 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302896 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002897 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002898 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002899 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002901 oFsm.mutexIsAwaitingResponse.Lock()
2902 oFsm.isAwaitingResponse = false
2903 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002904 oFsm.mutexPLastTxMeInstance.RLock()
2905 if oFsm.pLastTxMeInstance != nil {
2906 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2907 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2908 }
2909 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002910 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002911 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302912 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002913 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002914 oFsm.mutexIsAwaitingResponse.Lock()
2915 oFsm.isAwaitingResponse = false
2916 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002917 return nil
2918 }
mpagenko7d6bb022021-03-11 15:07:55 +00002919 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002920 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002921 oFsm.mutexIsAwaitingResponse.Lock()
2922 oFsm.isAwaitingResponse = false
2923 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002925 }
2926}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002927
mpagenko551a4d42020-12-08 18:09:20 +00002928func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002932 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002936 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2937 }
2938
dbainbri4d3a0dc2020-12-02 00:33:42 +00002939 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002940 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002941 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002942 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002943 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002944 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2945 }
2946
dbainbri4d3a0dc2020-12-02 00:33:42 +00002947 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002948 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002949 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002950 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002952 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2953 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002955 if errMacBpCdEID != nil {
2956 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2957 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002959 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002960
Mahir Gunyel6781f962021-05-16 23:30:08 -07002961 }
2962 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2964 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002965 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002966 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002967 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002968 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2969 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2970 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2971 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002972 },
2973 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002974 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2976 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002977 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002978 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002979 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2980 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002982 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2983 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002984 //accept also nil as (error) return value for writing to LastTx
2985 // - this avoids misinterpretation of new received OMCI messages
2986 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002987 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002988 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002989 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002990 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2992 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002993 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2994 }
2995
2996 // ==> Start creating VTFD for mcast vlan
2997
2998 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2999 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07003000 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003001
dbainbri4d3a0dc2020-12-02 00:33:42 +00003002 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003003 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003005 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
3006
3007 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
3008 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
3009 // new vlan associated with a different TP.
3010 vtfdFilterList[0] = uint16(vlanID)
3011
3012 meParams = me.ParamData{
3013 EntityID: mcastVtfdID,
3014 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003015 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
3016 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
3017 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003018 },
3019 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003020 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3022 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003023 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003024 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003025 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3026 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003027 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003028 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3029 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003030 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003031 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003032 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003033 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003034 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003035 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003037 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3038 }
3039
3040 return nil
3041}
3042
dbainbri4d3a0dc2020-12-02 00:33:42 +00003043func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003044 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003045 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003046 logger.Errorw(ctx, "error generrating me instance id",
3047 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003048 return err
3049 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003050 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3051 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003052 meParams := me.ParamData{
3053 EntityID: instID,
3054 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003055 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003056 //Direct reference to the Operation profile
3057 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003058 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003059 },
3060 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003061 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003062 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3063 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3064 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003065 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003066 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003067 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3068 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003070 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3071 oFsm.deviceID, err)
3072 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003073 //accept also nil as (error) return value for writing to LastTx
3074 // - this avoids misinterpretation of new received OMCI messages
3075 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003076 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003077 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003078 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003079 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003080 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003081 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3082 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3083 }
3084 return nil
3085}
3086
dbainbri4d3a0dc2020-12-02 00:33:42 +00003087func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003088 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003089 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003090 logger.Errorw(ctx, "error generating me instance id",
3091 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003092 return err
3093 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003094 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3095 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003096 meParams := me.ParamData{
3097 EntityID: instID,
3098 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003099 me.MulticastOperationsProfile_IgmpVersion: 2,
3100 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003101 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003102 me.MulticastOperationsProfile_ImmediateLeave: 0,
3103 me.MulticastOperationsProfile_Robustness: 2,
3104 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3105 me.MulticastOperationsProfile_QueryInterval: 125,
3106 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3107 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003108 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003109 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003110 },
3111 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003112 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003113 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3114 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3115 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003116 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003117 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003118 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3119 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003120 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003121 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3122 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003123 //accept also nil as (error) return value for writing to LastTx
3124 // - this avoids misinterpretation of new received OMCI messages
3125 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003126 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003127 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003128 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003129 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003130 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003131 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003132 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003133 }
3134 return nil
3135}
3136
dbainbri4d3a0dc2020-12-02 00:33:42 +00003137func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003139 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003140 logger.Errorw(ctx, "error generating me instance id",
3141 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003142 return err
3143 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003144 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3145 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003146 //TODO check that this is correct
3147 // Table control
3148 //setCtrl = 1
3149 //rowPartId = 0
3150 //test = 0
3151 //rowKey = 0
3152 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003153 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003154 dynamicAccessCL := make([]uint8, 24)
3155 copy(dynamicAccessCL, tableCtrl)
3156 //Multicast GemPortId
3157 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3158 // python version waits for installation of flows, see line 723 onward of
3159 // brcm_openomci_onu_handler.py
3160 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3161 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003163 //TODO start and end are hardcoded, get from TP
3164 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003166 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003167 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003168 //imputed group bandwidth
3169 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3170
3171 meParams := me.ParamData{
3172 EntityID: instID,
3173 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003174 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003175 },
3176 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003177 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003178 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3179 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3180 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003181 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003182 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003183 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3184 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003185 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003186 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3187 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003188 //accept also nil as (error) return value for writing to LastTx
3189 // - this avoids misinterpretation of new received OMCI messages
3190 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003191 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003192 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003193 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003194 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003195 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003196 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003197 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003198 }
3199 return nil
3200}
Girish Gowdra26a40922021-01-29 17:14:34 -08003201
khenaidoo42dcdfd2021-10-19 17:34:12 -04003202func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003203 tpID uint8, uniID uint8, gemPortID uint16) error {
3204 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3205 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3206 // I created unique TD ID by flow direction.
3207 // TODO! Traffic descriptor ME ID will check
3208 trafficDescriptorID := gemPortID
3209 if aMeter == nil {
3210 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3211 }
3212 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3213 if err != nil {
3214 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3215 return err
3216 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003217 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003218 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003219 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003220 pbs := trafficShapingInfo.Pbs
3221
3222 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3223 meParams := me.ParamData{
3224 EntityID: trafficDescriptorID,
3225 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003226 me.TrafficDescriptor_Cir: cir,
3227 me.TrafficDescriptor_Pir: pir,
3228 me.TrafficDescriptor_Cbs: cbs,
3229 me.TrafficDescriptor_Pbs: pbs,
3230 me.TrafficDescriptor_ColourMode: 1,
3231 me.TrafficDescriptor_IngressColourMarking: 3,
3232 me.TrafficDescriptor_EgressColourMarking: 3,
3233 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003234 },
3235 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003236 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003237 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3238 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003239 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003240 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003241 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3242 return err
3243 }
3244 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003245 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003246 err = oFsm.waitforOmciResponse(ctx)
3247 if err != nil {
3248 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3249 return err
3250 }
3251
Girish Gowdra09e5f212021-09-30 16:28:36 -07003252 // Note: in the below request the gemport entity id is same as the gemport id and the traffic descriptor entity id is also same as gemport id
3253 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003254 if err != nil {
3255 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3256 return err
3257 }
3258 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3259
3260 return nil
3261}
3262
Girish Gowdra09e5f212021-09-30 16:28:36 -07003263func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3264 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3265 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003266 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003267 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003268 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003269 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003270 },
3271 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003272 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003273 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3274 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003275 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003276 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003277 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3278 return err
3279 }
3280 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003281 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003282 err = oFsm.waitforOmciResponse(ctx)
3283 if err != nil {
3284 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3285 return err
3286 }
3287 return nil
3288}
3289
Girish Gowdra26a40922021-01-29 17:14:34 -08003290// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003291func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3292 if oFsm == nil {
3293 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3294 return false
3295 }
mpagenkobb47bc22021-04-20 13:29:09 +00003296 oFsm.mutexFlowParams.Lock()
3297 defer oFsm.mutexFlowParams.Unlock()
3298 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3299 //flow removal is still ongoing/pending
3300 oFsm.signalOnFlowDelete = true
3301 oFsm.flowDeleteChannel = aFlowDeleteChannel
3302 return true
3303 }
3304 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003305}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003306
3307func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3308 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3309 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3310 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3311 log.Fields{"device-id": oFsm.deviceID})
3312 } else {
3313 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3314 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3315 "index": oFsm.numVlanFilterEntries,
3316 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3317 "device-id": oFsm.deviceID})
3318 oFsm.numVlanFilterEntries++
3319 }
3320}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003321
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003322// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3323func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003324 if respChan != nil {
3325 // Do it in a non blocking fashion, so that in case the flow handler routine has shutdown for any reason, we do not block here
3326 select {
3327 case *respChan <- err:
3328 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3329 default:
3330 }
3331 }
3332}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003333
3334// PrepareForGarbageCollection - remove references to prepare for garbage collection
3335func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3336 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3337 oFsm.pDeviceHandler = nil
3338 oFsm.pOnuDeviceEntry = nil
3339 oFsm.pOmciCC = nil
3340}