blob: 30aa96a6604bb9ea51a004bdbea1ec9d0b88120c [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
mpagenkof582d6a2021-06-18 15:58:10 +0000917 var cancelPendingConfig bool = false
918 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
919 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()
999 } // if not in the appropriate state a new entry will be automatically considered later
1000 // when the configDone state is reached
1001 return true
1002}
1003
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301004// removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1005//
1006// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1007// from the start of the deletion request to avoid to much interference
1008// so when called, there can only be one cookie active for this flow
1009//
mpagenkof1d21d12021-06-11 13:14:45 +00001010// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001011func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001012 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1013 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001014 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001015removeFromSlice_loop:
1016 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001017 // if UniFlowParams exists, cookieSlice should always have at least one element
1018 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1019 if cookieSliceLen == 1 {
1020 if storedUniFlowParams.CookieSlice[0] == aCookie {
1021 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001022 }
mpagenkof582d6a2021-06-18 15:58:10 +00001023 } else if cookieSliceLen == 0 {
1024 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1025 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1026 return errors.New(errStr)
1027 } else {
1028 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1029 logger.Errorw(ctx, errStr, log.Fields{
1030 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1031 for _, cookie := range storedUniFlowParams.CookieSlice {
1032 if cookie == aCookie {
1033 cookieFound = true
1034 break
1035 }
1036 }
1037 }
1038 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001039 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1040 "device-id": oFsm.deviceID, "cookie": aCookie})
1041 //remove the actual element from the addVlanFlow slice
1042 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1043 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001044 oFsm.NumUniFlows = 0 //no more flows
1045 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001046 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1047 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1048 //request that this profile gets deleted before a new flow add is allowed
1049 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1050 "device-id": oFsm.deviceID})
1051 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001052 oFsm.NumUniFlows--
1053 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1054 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001055 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001056 if !aWasConfigured {
1057 // We did not actually process this flow but was removed before that.
1058 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001059 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001060 }
1061
mpagenkof1d21d12021-06-11 13:14:45 +00001062 //cut off the requested flow by slicing out this element
1063 oFsm.uniVlanFlowParamsSlice = append(
1064 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1065 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1066 "device-id": oFsm.deviceID})
1067 }
1068 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1069 }
1070 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001071 if !cookieFound {
1072 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1073 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1074 return errors.New(errStr)
1075 }
mpagenkodee02a62021-07-21 10:56:10 +00001076 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1077 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001078 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001079 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1080 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1081 return err
1082 }
mpagenkof582d6a2021-06-18 15:58:10 +00001083 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001084}
1085
1086// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001087func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1088 //here we have to check, if there are still other flows referencing to the actual ProfileId
1089 // before we can request that this profile gets deleted before a new flow add is allowed
1090 tpIDInOtherFlows := false
1091 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1092 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1093 tpIDInOtherFlows = true
1094 break // search loop can be left
1095 }
1096 }
1097 if tpIDInOtherFlows {
1098 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1099 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1100 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001101 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 +00001102 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001103 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1104 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001105 if oFsm.pUniTechProf != nil {
1106 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001107 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001108 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001109 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001110 }
1111}
1112
mpagenkof1d21d12021-06-11 13:14:45 +00001113func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1114 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001115
1116 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001117 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001118 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001119 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001120 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001121 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001122 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001123 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001124 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001125 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001126 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001127 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001128 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001129 go func(a_pAFsm *cmn.AdapterFsm) {
1130 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001131 }(pConfigVlanStateAFsm)
1132 return
1133 }
mpagenkof1d21d12021-06-11 13:14:45 +00001134 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001135 go func(a_pAFsm *cmn.AdapterFsm) {
1136 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001137 }(pConfigVlanStateAFsm)
1138 return
1139 }
1140 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1141 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1142 //should never happen, else: recovery would be needed from outside the FSM
1143}
1144
1145func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1146 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001147 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001148 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001149 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001150 //possibly the entry is not valid anymore based on intermediate delete requests
1151 //just a basic protection ...
1152 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1153 oFsm.mutexFlowParams.Unlock()
1154 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1155 "device-id": oFsm.deviceID})
1156 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001157 go func(a_pAFsm *cmn.AdapterFsm) {
1158 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001159 }(pConfigVlanStateAFsm)
1160 return
1161 }
mpagenko9a304ea2020-12-16 15:54:01 +00001162 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1163 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001164 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1165 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001166 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001167 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001168 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1169 // synchronous FSM 'event/state' functions may rely on this mutex
1170 // but it must be released already before calling getTechProfileDone() as it may already be locked
1171 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001172 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001173 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001174 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001175 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001176 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001177
mpagenko9a304ea2020-12-16 15:54:01 +00001178 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001179 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1180 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001181 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001182 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001183 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001184 } else {
1185 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001186 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001187 }
1188 }
mpagenko551a4d42020-12-08 18:09:20 +00001189 }(pConfigVlanStateAFsm, loTechProfDone)
1190 } else {
1191 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1192 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1193 //should never happen, else: recovery would be needed from outside the FSM
1194 return
mpagenkodff5dda2020-08-28 11:52:01 +00001195 }
1196}
1197
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001199 //mutex protection is required for possible concurrent access to FSM members
1200 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001201 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001202 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001203 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001204 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001206 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001207 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001208 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001209 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001210 go func(a_pAFsm *cmn.AdapterFsm) {
1211 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001212 }(pConfigVlanStateAFsm)
1213 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001214 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1215 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001216 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001218 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001219 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001220 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001221 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001222 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001223 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001224 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001225 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1226 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001227 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001228 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001229 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001230 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1231 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1232 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001233 },
1234 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001236 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001237 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1239 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001240 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001241 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001242 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1243 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001244 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001245 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001246 go func(a_pAFsm *cmn.AdapterFsm) {
1247 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001248 }(pConfigVlanStateAFsm)
1249 }
1250 return
1251 }
mpagenkodff5dda2020-08-28 11:52:01 +00001252 //accept also nil as (error) return value for writing to LastTx
1253 // - this avoids misinterpretation of new received OMCI messages
1254 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1255 // send shall return (dual format) error code that can be used here for immediate error treatment
1256 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001257 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001258 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001259 }
1260}
1261
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301262//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001263func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1264 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001265 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001266 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001267 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001268 //using the first element in the slice because it's the first flow per definition here
1269 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001270 //This is correct passing scenario
1271 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001272 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001273 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1274 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001276 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1277 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001279 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001282 vlanID)
1283 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001285 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001287 }
1288 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001289 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001290 if oFsm.actualUniFlowParam.Meter != nil {
1291 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001293 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1294 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001296 if errCreateTrafficDescriptor != nil {
1297 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1298 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001300 }
1301 }
1302 }
1303
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001304 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001305 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001306 }
1307 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001308}
1309
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001311
mpagenkof1d21d12021-06-11 13:14:45 +00001312 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001313
mpagenkof1fc3862021-02-16 10:09:52 +00001314 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001315 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001316 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001317 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001318 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001319 }
1320
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001321 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001322 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001323 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001324 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1325 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1326 //should never happen, else: recovery would be needed from outside the FSM
1327 return
1328 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001329 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001330 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1331 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001332 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001334 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1335 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001336 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001337 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001338 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001340 }(pConfigVlanStateBaseFsm)
1341 return
1342 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001343 if oFsm.lastFlowToReconcile {
1344 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1345 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1346 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1347 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1348 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1349 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301350 if oFsm.lastFlowToConfigOnReboot {
1351 logger.Debugw(ctx, "rebooting - flow processing finished", log.Fields{
1352 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1353 oFsm.pDeviceHandler.SendChUniVlanConfigFinishedOnReboot(uint16(oFsm.pOnuUniPort.UniID))
1354 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001355 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1356 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001357 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001359 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001360 return
1361 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001362 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1363 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001364 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001365 // this is a restart with a complete new flow, we can re-use the initial flow config control
1366 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001367 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001368 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001369 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001370 }(pConfigVlanStateBaseFsm)
1371 return
1372 }
1373
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001374 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001375 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001376 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001377 //check introduced after having observed some panic in this processing
1378 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001379 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001380 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1381 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 go func(a_pAFsm *cmn.AdapterFsm) {
1383 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001384 }(pConfigVlanStateAFsm)
1385 return
1386 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001387 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001388 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001389 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001390 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001391 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001392 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1393 // synchronous FSM 'event/state' functions may rely on this mutex
1394 // but it must be released already before calling getTechProfileDone() as it may already be locked
1395 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1396 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001397 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001398 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001399 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001400 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1401
mpagenko9a304ea2020-12-16 15:54:01 +00001402 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001403 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1404 if aTechProfDone {
1405 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001406 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001407 } else {
1408 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001410 }
1411 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001412 return
1413 }
mpagenkof1d21d12021-06-11 13:14:45 +00001414 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001415 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001416 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001417 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1418 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001419 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001420 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001421 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001423 }
1424}
1425
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001427
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001428 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001429 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001431 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001432 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1433 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001434 return
1435 }
mpagenko15ff4a52021-03-02 10:09:20 +00001436 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001438 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001439 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001440 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001441
Girish Gowdrae95687a2021-09-08 16:30:58 -07001442 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001443 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001444 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001445 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001446 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001447 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1448 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1449 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1450 // 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 +00001451 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001452 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1453 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001454 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001455 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001457 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001458 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001459 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001460 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001461 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001462
mpagenko01e726e2020-10-23 09:45:29 +00001463 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001464 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1465 oFsm.numVlanFilterEntries = 1
1466 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001467 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001468 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001469 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1470 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1471 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001472 },
1473 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001474 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001475 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1476 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001477 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001478 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001479 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001480 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1481 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001482 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001483 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001484 go func(a_pAFsm *cmn.AdapterFsm) {
1485 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001486 }(pConfigVlanStateAFsm)
1487 }
1488 return
1489 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001490 //accept also nil as (error) return value for writing to LastTx
1491 // - this avoids misinterpretation of new received OMCI messages
1492 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1493 // send shall return (dual format) error code that can be used here for immediate error treatment
1494 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001495 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001496 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001497 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001498 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1499 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001500 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001501
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001503 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001504 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001505 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001506 // setVid is assumed to be masked already by the caller to 12 bit
1507 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001508 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001509 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001510
1511 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1512 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1513 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001514 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001515
1516 oFsm.numVlanFilterEntries++
1517 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001518 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001519 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001520 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1521 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1522 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001523 },
1524 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001525 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001526 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1527 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001528 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001529 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001530 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001531 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1532 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001533 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001534 return
1535 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001536 //accept also nil as (error) return value for writing to LastTx
1537 // - this avoids misinterpretation of new received OMCI messages
1538 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1539 // send shall return (dual format) error code that can be used here for immediate error treatment
1540 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001541 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001542 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001543 }
1544 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001546 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001547 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001549 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001550 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001551 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001552 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001553 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001554 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001555 return
1556 }
1557 }
mpagenkof1d21d12021-06-11 13:14:45 +00001558
mpagenkof1fc3862021-02-16 10:09:52 +00001559 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001560 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001561 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001562 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001563 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1564 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001565 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001566 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001567 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 //This is correct passing scenario
1569 if errEvto == nil {
1570 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001572 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001573 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001574 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001575 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001576 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001577 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001578 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001579 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001580 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001581 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001583 }
1584 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001585 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001586 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001587 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001588 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1589 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001591 if errCreateTrafficDescriptor != nil {
1592 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1593 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001594 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001595 }
1596 }
1597 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001598 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001599 }
1600 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001601}
1602
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001604 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001606 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1607 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001608
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1610 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001611 loVlanEntryClear := uint8(0)
1612 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1613 //shallow copy is sufficient as no reference variables are used within struct
1614 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001615 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001617 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1618 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1619 "device-id": oFsm.deviceID})
1620
1621 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1622 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001624 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1625 } else {
1626 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1627 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001629 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1630 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001632 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001633 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001634 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001635 loVlanEntryClear = 1 //full VlanFilter clear request
1636 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001637 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001638 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1639 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001640 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001641 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001642 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1643 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001644 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001645 return
1646 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001647 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001648 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001649 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001650 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001652 }
mpagenko01e726e2020-10-23 09:45:29 +00001653 } else {
1654 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1655 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001657 log.Fields{"current vlan list": oFsm.vlanFilterList,
1658 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1659 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1660 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1661 loVlanEntryRmPos = i
1662 break //abort search
1663 }
1664 }
1665 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001667 //valid entry was found - to be eclipsed
1668 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1669 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1670 if i < loVlanEntryRmPos {
1671 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1672 } else if i < (cVtfdTableSize - 1) {
1673 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1674 } else {
1675 vtfdFilterList[i] = 0 //set last byte if needed
1676 }
1677 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001679 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001680 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001682
mpagenkofc4f56e2020-11-04 17:17:49 +00001683 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001684 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001685 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001686 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1687 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001688 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001689 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001690 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1691 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001692 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001693 return
1694 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001695 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001696 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001697 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001700 }
mpagenko01e726e2020-10-23 09:45:29 +00001701 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001702 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001703 log.Fields{"device-id": oFsm.deviceID})
1704 }
1705 }
1706 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001707 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1708 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001709 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001710 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001711 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001712 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001713 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001714 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001715 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001716 }(pConfigVlanStateBaseFsm)
1717 return
1718 }
mpagenko01e726e2020-10-23 09:45:29 +00001719 }
1720
mpagenko15ff4a52021-03-02 10:09:20 +00001721 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001722 if loVlanEntryClear == 1 {
1723 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1724 oFsm.numVlanFilterEntries = 0
1725 } else if loVlanEntryClear == 2 {
1726 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1727 // this loop now includes the 0 element on previous last valid entry
1728 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1729 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1730 }
1731 oFsm.numVlanFilterEntries--
1732 }
mpagenko15ff4a52021-03-02 10:09:20 +00001733 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001734 }
1735 }
1736
mpagenkofc4f56e2020-11-04 17:17:49 +00001737 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001739 } else {
1740 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001742 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001743 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001744 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001745 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001746 }(pConfigVlanStateBaseFsm)
1747 }
mpagenkodff5dda2020-08-28 11:52:01 +00001748}
1749
dbainbri4d3a0dc2020-12-02 00:33:42 +00001750func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001751 var tpID uint8
1752 // Extract the tpID
1753 if len(e.Args) > 0 {
1754 tpID = e.Args[0].(uint8)
1755 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1756 } else {
1757 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1758 }
mpagenko01e726e2020-10-23 09:45:29 +00001759 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001760 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001761
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001763 if pConfigVlanStateAFsm == nil {
1764 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1765 log.Fields{"device-id": oFsm.deviceID})
1766 //would have to be fixed from outside somehow
1767 return
1768 }
1769
mpagenkof1d21d12021-06-11 13:14:45 +00001770 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1771 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001772 //call from 'configured' state of the rule
1773 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1774 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1775 oFsm.mutexFlowParams.Unlock()
1776 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001777 go func(a_pAFsm *cmn.AdapterFsm) {
1778 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001779 }(pConfigVlanStateAFsm)
1780 return
1781 }
mpagenkof1d21d12021-06-11 13:14:45 +00001782 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1783 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1784 oFsm.mutexFlowParams.Unlock()
1785 removeChannel <- true
1786 oFsm.mutexFlowParams.Lock()
1787 }
1788
mpagenkof1fc3862021-02-16 10:09:52 +00001789 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1790 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1791 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1792
Girish Gowdrae95687a2021-09-08 16:30:58 -07001793 // Store the reference to the flow response channel before this entry in the slice is deleted
1794 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1795
mpagenko01e726e2020-10-23 09:45:29 +00001796 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1797 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001799 "device-id": oFsm.deviceID})
1800 } else {
1801 //cut off the actual flow by slicing out the first element
1802 oFsm.uniRemoveFlowsSlice = append(
1803 oFsm.uniRemoveFlowsSlice[:0],
1804 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001806 "device-id": oFsm.deviceID})
1807 }
1808 oFsm.mutexFlowParams.Unlock()
1809
mpagenkof1fc3862021-02-16 10:09:52 +00001810 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001811 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001812 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001813 go func(a_pAFsm *cmn.AdapterFsm) {
1814 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001815 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001816
mpagenkobb47bc22021-04-20 13:29:09 +00001817 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001818 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001819 if deletedCookie == oFsm.delayNewRuleCookie {
1820 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1821 select {
1822 case <-oFsm.chCookieDeleted:
1823 logger.Debug(ctx, "flushed CookieDeleted")
1824 default:
1825 }
1826 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1827 }
mpagenkobb47bc22021-04-20 13:29:09 +00001828 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1829 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1830 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 -08001831 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001832 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1833 oFsm.flowDeleteChannel <- true
1834 oFsm.signalOnFlowDelete = false
1835 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001836 }
mpagenkobb47bc22021-04-20 13:29:09 +00001837 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001838
1839 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001840 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001841}
1842
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301843//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1845 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001846
mpagenko0f543222021-11-03 16:24:14 +00001847 oFsm.mutexPLastTxMeInstance.Lock()
1848 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1849 oFsm.mutexPLastTxMeInstance.Unlock()
1850
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001851 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001852 if pConfigVlanStateAFsm != nil {
1853 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 fsmAbortMsg := cmn.Message{
1855 Type: cmn.TestMsg,
1856 Data: cmn.TestMessage{
1857 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001858 },
1859 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001860 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001861
mpagenko0f543222021-11-03 16:24:14 +00001862 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1863 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1864
1865 oFsm.mutexFlowParams.RLock()
1866 if oFsm.delayNewRuleCookie != 0 {
1867 // looks like the waiting AddFlow is stuck
1868 oFsm.mutexFlowParams.RUnlock()
1869 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1870 select {
1871 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1872 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001873 }
mpagenko0f543222021-11-03 16:24:14 +00001874 oFsm.mutexFlowParams.RLock()
1875 }
1876 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1877 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1878 if removeUniFlowParams.isSuspendedOnAdd {
1879 removeChannel := removeUniFlowParams.removeChannel
1880 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1881 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1882 oFsm.mutexFlowParams.RUnlock()
1883 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1884 select {
1885 case removeChannel <- false:
1886 default:
1887 }
1888 oFsm.mutexFlowParams.RLock()
1889 }
1890 // Send response on response channel if the caller is waiting on it.
1891 var err error = nil
1892 if !oFsm.isCanceled {
1893 //only if the FSM is not canceled on external request use some error indication for the respChan
1894 // so only at real internal FSM abortion some error code is sent back
1895 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1896 err = fmt.Errorf("internal-error")
1897 }
1898 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1899 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1900 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1901 }
1902 }
1903
1904 if oFsm.pDeviceHandler != nil {
1905 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1906 if !oFsm.isCanceled {
1907 //if the FSM is not canceled on external request use "internal-error" for the respChan
1908 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1909 // Send response on response channel if the caller is waiting on it with according error indication.
1910 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1911 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301912 // Do not remove pers uni data during reset of FSM. It will be removed when the device is deleted
1913 //var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1914 //_ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
mpagenko0f543222021-11-03 16:24:14 +00001915 } else {
1916 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1917 // no need to remove specific data in this case here
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +05301918 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1919 // Send response on response channel if the caller is waiting on it with according error indication.
1920 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("config-cancelled"))
1921 }
mpagenko0f543222021-11-03 16:24:14 +00001922 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1923 }
1924 }
1925 oFsm.mutexFlowParams.RUnlock()
1926
1927 //try to let the FSM proceed to 'disabled'
1928 // Can't call FSM Event directly, decoupling it
1929 go func(a_pAFsm *cmn.AdapterFsm) {
1930 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1931 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1932 }
1933 }(pConfigVlanStateAFsm)
1934 return
1935 }
1936 oFsm.mutexFlowParams.RUnlock()
1937 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1938 log.Fields{"device-id": oFsm.deviceID})
1939 return
mpagenkodff5dda2020-08-28 11:52:01 +00001940 }
mpagenko0f543222021-11-03 16:24:14 +00001941 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1942 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001943}
1944
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301945//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1947 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001948
mpagenkodff5dda2020-08-28 11:52:01 +00001949 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001950 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001952 return
mpagenkodff5dda2020-08-28 11:52:01 +00001953 }
mpagenko0f543222021-11-03 16:24:14 +00001954 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1955 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001956}
1957
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1959 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001960loop:
1961 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001962 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001964 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001965 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301966 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301968 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301970 break loop
1971 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301973
1974 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975 case cmn.TestMsg:
1976 msg, _ := message.Data.(cmn.TestMessage)
1977 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001979 break loop
1980 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001982 case cmn.OMCI:
1983 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301985 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301987 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001988 }
1989 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001991}
1992
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001993func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001994 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001995 "msgType": msg.OmciMsg.MessageType})
1996
1997 switch msg.OmciMsg.MessageType {
1998 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001999 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002001 logger.Warnw(ctx, "CreateResponse handling aborted",
2002 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00002003 return
2004 }
mpagenkodff5dda2020-08-28 11:52:01 +00002005 } //CreateResponseType
2006 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00002007 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00002008 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
2009 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002010 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002011 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002012 return
2013 }
2014 msgObj, msgOk := msgLayer.(*omci.SetResponse)
2015 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002017 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002018 return
2019 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002020 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002021 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002022 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002023 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002024 // possibly force FSM into abort or ignore some errors for some messages?
2025 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2026 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002027 return
2028 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002029 oFsm.mutexPLastTxMeInstance.RLock()
2030 if oFsm.pLastTxMeInstance != nil {
2031 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2032 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2033 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002034 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002035 { // let the MultiEntity config proceed by stopping the wait function
2036 oFsm.mutexPLastTxMeInstance.RUnlock()
2037 oFsm.omciMIdsResponseReceived <- true
2038 return
2039 }
2040 default:
2041 {
2042 logger.Warnw(ctx, "Unsupported ME name received!",
2043 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2044 }
mpagenkodff5dda2020-08-28 11:52:01 +00002045 }
2046 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002047 } else {
2048 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002049 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002050 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002051 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002052 case omci.DeleteResponseType:
2053 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002055 logger.Warnw(ctx, "DeleteResponse handling aborted",
2056 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002057 return
2058 }
2059 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002060 default:
2061 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002062 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002063 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002064 return
2065 }
2066 }
2067}
2068
dbainbri4d3a0dc2020-12-02 00:33:42 +00002069func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002070 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2071 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002073 log.Fields{"device-id": oFsm.deviceID})
2074 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2075 oFsm.deviceID)
2076 }
2077 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2078 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002080 log.Fields{"device-id": oFsm.deviceID})
2081 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2082 oFsm.deviceID)
2083 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002084 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002085 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002086 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002087 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002088 // possibly force FSM into abort or ignore some errors for some messages?
2089 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2090 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002091 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2092 oFsm.deviceID)
2093 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002094 oFsm.mutexPLastTxMeInstance.RLock()
2095 if oFsm.pLastTxMeInstance != nil {
2096 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2097 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2098 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2099 switch oFsm.pLastTxMeInstance.GetName() {
2100 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2101 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002102 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002103 {
2104 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002105 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002106 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002107 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002108 } else { // let the MultiEntity config proceed by stopping the wait function
2109 oFsm.omciMIdsResponseReceived <- true
2110 }
2111 return nil
2112 }
2113 default:
2114 {
2115 logger.Warnw(ctx, "Unsupported ME name received!",
2116 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002117 }
2118 }
2119 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002120 } else {
2121 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002122 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002123 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002124 return nil
2125}
2126
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002128 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2129 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002131 log.Fields{"device-id": oFsm.deviceID})
2132 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2133 oFsm.deviceID)
2134 }
2135 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2136 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002138 log.Fields{"device-id": oFsm.deviceID})
2139 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2140 oFsm.deviceID)
2141 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002142 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05302143 if msgObj.Result == me.UnknownInstance {
2144 logger.Warnw(ctx, "UniVlanConfigFsm - Unknow Instance",
2145 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
2146 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002148 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002149 // possibly force FSM into abort or ignore some errors for some messages?
2150 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2151 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002152 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2153 oFsm.deviceID)
2154 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002155 oFsm.mutexPLastTxMeInstance.RLock()
2156 if oFsm.pLastTxMeInstance != nil {
2157 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2158 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2159 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002160 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002161 { // let the MultiEntity config proceed by stopping the wait function
2162 oFsm.mutexPLastTxMeInstance.RUnlock()
2163 oFsm.omciMIdsResponseReceived <- true
2164 return nil
2165 }
2166 default:
2167 {
2168 logger.Warnw(ctx, "Unsupported ME name received!",
2169 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2170 }
mpagenko01e726e2020-10-23 09:45:29 +00002171 }
2172 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002173 } else {
2174 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002175 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002177 return nil
2178}
2179
dbainbri4d3a0dc2020-12-02 00:33:42 +00002180func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002181 oFsm.mutexFlowParams.RLock()
2182 evtocdID := oFsm.evtocdID
2183 oFsm.mutexFlowParams.RUnlock()
2184
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002185 if aFlowEntryNo == 0 {
2186 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002187 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2188 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002189 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002190 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002191 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002192 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002193 associationType := 2 // default to UniPPTP
2194 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002195 associationType = 10
2196 }
2197 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002198 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002199 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002200 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002201 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2202 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002203 },
2204 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002205 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2207 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002208 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002209 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002210 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2211 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002213 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2214 }
mpagenkodff5dda2020-08-28 11:52:01 +00002215 //accept also nil as (error) return value for writing to LastTx
2216 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002217 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002218 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002219
2220 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002221 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002222 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002223 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002224 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002226 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2227 }
2228
2229 // Set the EVTOCD ME default params
2230 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002231 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002232 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002233 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2234 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2235 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002236 },
2237 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002238 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002239 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2240 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2241 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002242 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002243 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002244 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2245 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002247 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2248 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002249 //accept also nil as (error) return value for writing to LastTx
2250 // - this avoids misinterpretation of new received OMCI messages
2251 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002252 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002253
2254 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002256 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002257 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002258 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002259 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002260 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002261 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002262 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002263
mpagenko551a4d42020-12-08 18:09:20 +00002264 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302265 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2266 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002267 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002268 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002270 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002271 sliceEvtocdRule := make([]uint8, 16)
2272 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2273 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2274 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2275 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2276 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2277
2278 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2279 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2280 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2281 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2282 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2283
2284 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2285 0<<cTreatTTROffset| // Do not pop any tags
2286 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2287 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2288 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2289
2290 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2291 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2292 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2293 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2294
2295 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002296 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002297 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002298 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002299 },
2300 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002301 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002302 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2303 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2304 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002305 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002306 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002307 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2308 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2311 }
mpagenkodff5dda2020-08-28 11:52:01 +00002312 //accept also nil as (error) return value for writing to LastTx
2313 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002314 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002315 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002316
2317 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002318 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002319 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002321 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002322 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002323 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2324
mpagenkodff5dda2020-08-28 11:52:01 +00002325 }
2326 } else {
2327 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2328 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002329 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2330 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2331 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2332 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302333 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002334 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002335
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302336 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2337 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2338 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
2339 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
2340 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2341 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2342 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2343 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2344 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002345
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302346 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2347 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2348 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2349 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2350 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002351
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302352 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2353 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2354 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2355 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2356 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2357
2358 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2359 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2360 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2361 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2362
2363 } else {
2364 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2365 //As of now only a match and no action can be done on the inner tag .
2366 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2367 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2368 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2369 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2370 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2371 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2372 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2373
2374 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2375 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2376 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2377 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2378 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2379
2380 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2381 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2382 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2383 setVid<<cTreatVidOffset| // Set VID
2384 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2385
2386 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2387 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2388 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2389 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2390 }
mpagenko551a4d42020-12-08 18:09:20 +00002391 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002392 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002393 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002394 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002395 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002396 },
2397 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002398 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2400 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2401 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002402 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002403 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002404 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2405 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002407 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2408 }
mpagenkodff5dda2020-08-28 11:52:01 +00002409 //accept also nil as (error) return value for writing to LastTx
2410 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002411 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002412 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002413
2414 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002415 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002416 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302417 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002418 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302420 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002421 }
2422 } else {
2423 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2424 { // just for local var's
2425 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002427 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002428 sliceEvtocdRule := make([]uint8, 16)
2429 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2430 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2431 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2432 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2433 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2434
2435 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2436 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2437 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2438 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2439 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2440
2441 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2442 0<<cTreatTTROffset| // Do not pop any tags
2443 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2444 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2445 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2446
2447 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2448 0<<cTreatPrioOffset| // vlan prio set to 0
2449 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002450 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002451 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2452
mpagenko551a4d42020-12-08 18:09:20 +00002453 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002454 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002455 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002456 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002457 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002458 },
2459 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002460 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002461 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2462 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2463 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002464 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002465 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002466 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2467 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002469 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2470 }
mpagenkodff5dda2020-08-28 11:52:01 +00002471 //accept also nil as (error) return value for writing to LastTx
2472 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002473 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002474 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002475
2476 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002477 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002478 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002480 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002481 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002482 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2483
mpagenkodff5dda2020-08-28 11:52:01 +00002484 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002485 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002486 { // just for local var's
2487 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002489 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002490 sliceEvtocdRule := make([]uint8, 16)
2491 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2492 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2493 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2494 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2495 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2496
2497 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2498 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2499 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2500 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2501 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2502
2503 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2504 1<<cTreatTTROffset| // pop the prio-tag
2505 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2506 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2507 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2508
mpagenko551a4d42020-12-08 18:09:20 +00002509 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002510 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2511 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2512 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002513 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002514 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002515 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002516
2517 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002518 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002519 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002520 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002521 },
2522 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002523 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002524 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2525 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2526 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002527 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002528 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002529 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2530 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002532 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2533 }
mpagenkodff5dda2020-08-28 11:52:01 +00002534 //accept also nil as (error) return value for writing to LastTx
2535 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002536 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002537 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002538
2539 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002540 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002541 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002543 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002544 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002545 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2546
mpagenkodff5dda2020-08-28 11:52:01 +00002547 }
2548 } //just for local var's
2549 }
2550 }
2551
mpagenkofc4f56e2020-11-04 17:17:49 +00002552 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002554 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002555 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002556 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002557 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002558}
2559
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002560func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002561 oFsm.mutexFlowParams.RLock()
2562 evtocdID := oFsm.evtocdID
2563 oFsm.mutexFlowParams.RUnlock()
2564
mpagenko01e726e2020-10-23 09:45:29 +00002565 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2566 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2567 //transparent transmission was set
2568 //perhaps the config is not needed for removal,
2569 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002571 "device-id": oFsm.deviceID})
2572 sliceEvtocdRule := make([]uint8, 16)
2573 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2574 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2575 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2576 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2577 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2578
2579 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2580 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2581 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2582 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2583 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2584
2585 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2586 0<<cTreatTTROffset| // Do not pop any tags
2587 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2588 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2589 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2590
2591 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2592 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2593 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2594 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2595
2596 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002597 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002598 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002599 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002600 },
2601 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002602 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2604 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2605 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002606 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002607 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002608 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2609 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002611 return
2612 }
mpagenko01e726e2020-10-23 09:45:29 +00002613 //accept also nil as (error) return value for writing to LastTx
2614 // - this avoids misinterpretation of new received OMCI messages
2615 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002616 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002617
2618 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002619 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002620 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002622 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002623 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002624 return
2625 }
2626 } else {
2627 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002628 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002629 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002630 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002631 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302632 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002633
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302634 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2635 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2636 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2637 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2638 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2639 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2640 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2641 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002642
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302643 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2644 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2645 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2646 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2647 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002648
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302649 // delete indication for the indicated Filter
2650 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2651 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2652
2653 } else {
2654 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2655 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2656 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302657 sliceEvtocdRule = make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302658 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2659 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2660 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2661 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2662 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2663
2664 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2665 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2666 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2667 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2668 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2669
2670 // delete indication for the indicated Filter
2671 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2672 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2673 }
mpagenko01e726e2020-10-23 09:45:29 +00002674 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002675 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002676 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002677 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002678 },
2679 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002680 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002681 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2682 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2683 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002684 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002685 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002686 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2687 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002688 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002689 return
2690 }
mpagenko01e726e2020-10-23 09:45:29 +00002691 //accept also nil as (error) return value for writing to LastTx
2692 // - this avoids misinterpretation of new received OMCI messages
2693 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002694 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002695
2696 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002697 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002698 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302699 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2700 log.Fields{"device-id": oFsm.deviceID,
2701 "match-vlan": aRuleParams.MatchVid,
2702 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002703 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002704 return
2705 }
2706 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002707 // VOL-3685
2708 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2709 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2710 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2711 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2712 // later when the flow is being re-installed.
2713 // Of course this is applicable to case only where single service (or single tcont) is in use and
2714 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2715 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2716 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002717 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002718 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002719 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002720 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2721 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002722 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002723 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002724 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002725 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002726 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2727 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2728 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002729 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002730 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002731 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2732 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002734 return
2735 }
mpagenko01e726e2020-10-23 09:45:29 +00002736 //accept also nil as (error) return value for writing to LastTx
2737 // - this avoids misinterpretation of new received OMCI messages
2738 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002739 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002740
2741 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002742 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002743 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002745 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002746 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002747 return
2748 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002749 } else {
2750 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2751 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002752 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002753 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002754 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2756 { // just for local var's
2757 // this defines stacking scenario: untagged->singletagged
2758 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2759 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2760 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2761 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002762 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002763 "device-id": oFsm.deviceID})
2764 sliceEvtocdRule := make([]uint8, 16)
2765 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2766 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2767 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2768 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2769 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002770
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002771 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2772 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2773 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2774 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2775 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002776
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002777 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2778 0<<cTreatTTROffset| // Do not pop any tags
2779 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2780 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2781 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002782
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002783 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2784 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2785 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2786 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002787
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002788 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002789 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002790 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002791 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002792 },
2793 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002794 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2796 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2797 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002798 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002799 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002800 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2801 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002803 return
2804 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002805 //accept also nil as (error) return value for writing to LastTx
2806 // - this avoids misinterpretation of new received OMCI messages
2807 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002808 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002809
2810 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002811 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002812 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002813 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002814 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002815 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002816 return
2817 }
2818 } // just for local var's
2819 { // just for local var's
2820 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002821 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002822 "device-id": oFsm.deviceID})
2823 sliceEvtocdRule := make([]uint8, 16)
2824 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2825 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2826 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2827 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2828 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2829
2830 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2831 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2832 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2833 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2834 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2835
2836 // delete indication for the indicated Filter
2837 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2838 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2839
2840 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002841 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002842 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002843 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844 },
2845 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002846 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002847 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2848 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2849 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002850 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002851 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002852 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2853 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002855 return
2856 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002857 //accept also nil as (error) return value for writing to LastTx
2858 // - this avoids misinterpretation of new received OMCI messages
2859 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002860 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002861
2862 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002863 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002864 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002865 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002866 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002867 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002868 return
2869 }
mpagenko01e726e2020-10-23 09:45:29 +00002870 }
2871 } //just for local var's
2872 }
2873 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002874 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002875 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002877}
2878
dbainbri4d3a0dc2020-12-02 00:33:42 +00002879func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002880 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002881 if oFsm.isCanceled {
2882 // FSM already canceled before entering wait
2883 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2884 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002885 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002886 }
mpagenko7d6bb022021-03-11 15:07:55 +00002887 oFsm.isAwaitingResponse = true
2888 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002889 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302890 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002891 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002892 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002893 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002895 oFsm.mutexIsAwaitingResponse.Lock()
2896 oFsm.isAwaitingResponse = false
2897 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002898 oFsm.mutexPLastTxMeInstance.RLock()
2899 if oFsm.pLastTxMeInstance != nil {
2900 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2901 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2902 }
2903 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002904 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002905 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302906 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002907 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002908 oFsm.mutexIsAwaitingResponse.Lock()
2909 oFsm.isAwaitingResponse = false
2910 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002911 return nil
2912 }
mpagenko7d6bb022021-03-11 15:07:55 +00002913 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002914 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002915 oFsm.mutexIsAwaitingResponse.Lock()
2916 oFsm.isAwaitingResponse = false
2917 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002919 }
2920}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002921
mpagenko551a4d42020-12-08 18:09:20 +00002922func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002923 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002924 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002925 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002926 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002928 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2931 }
2932
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002935 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002936 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2939 }
2940
dbainbri4d3a0dc2020-12-02 00:33:42 +00002941 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002942 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002943 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002944 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2947 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002948 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002949 if errMacBpCdEID != nil {
2950 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2951 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002953 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002954
Mahir Gunyel6781f962021-05-16 23:30:08 -07002955 }
2956 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002957 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2958 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002959 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002960 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002961 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002962 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2963 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2964 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2965 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002966 },
2967 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002968 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2970 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002971 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002972 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002973 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2974 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002975 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002976 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2977 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002978 //accept also nil as (error) return value for writing to LastTx
2979 // - this avoids misinterpretation of new received OMCI messages
2980 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002981 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002982 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002983 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002984 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2986 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002987 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2988 }
2989
2990 // ==> Start creating VTFD for mcast vlan
2991
2992 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2993 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002994 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002995
dbainbri4d3a0dc2020-12-02 00:33:42 +00002996 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002997 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002999 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
3000
3001 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
3002 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
3003 // new vlan associated with a different TP.
3004 vtfdFilterList[0] = uint16(vlanID)
3005
3006 meParams = me.ParamData{
3007 EntityID: mcastVtfdID,
3008 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003009 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
3010 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
3011 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003012 },
3013 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003014 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003015 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3016 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003017 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003018 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003019 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3020 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003022 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3023 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003024 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003025 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003026 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003027 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003028 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003029 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003031 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3032 }
3033
3034 return nil
3035}
3036
dbainbri4d3a0dc2020-12-02 00:33:42 +00003037func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003038 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003039 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003040 logger.Errorw(ctx, "error generrating me instance id",
3041 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003042 return err
3043 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003044 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3045 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003046 meParams := me.ParamData{
3047 EntityID: instID,
3048 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003049 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003050 //Direct reference to the Operation profile
3051 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003052 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003053 },
3054 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003055 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3057 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3058 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003059 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003060 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003061 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3062 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003063 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003064 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3065 oFsm.deviceID, err)
3066 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003067 //accept also nil as (error) return value for writing to LastTx
3068 // - this avoids misinterpretation of new received OMCI messages
3069 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003070 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003071 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003072 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003073 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003074 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003075 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3076 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3077 }
3078 return nil
3079}
3080
dbainbri4d3a0dc2020-12-02 00:33:42 +00003081func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003082 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003083 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003084 logger.Errorw(ctx, "error generating me instance id",
3085 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003086 return err
3087 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003088 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3089 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003090 meParams := me.ParamData{
3091 EntityID: instID,
3092 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003093 me.MulticastOperationsProfile_IgmpVersion: 2,
3094 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003095 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003096 me.MulticastOperationsProfile_ImmediateLeave: 0,
3097 me.MulticastOperationsProfile_Robustness: 2,
3098 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3099 me.MulticastOperationsProfile_QueryInterval: 125,
3100 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3101 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003102 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003103 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003104 },
3105 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003106 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003107 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3108 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3109 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003110 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003111 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003112 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3113 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003114 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003115 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3116 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003117 //accept also nil as (error) return value for writing to LastTx
3118 // - this avoids misinterpretation of new received OMCI messages
3119 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003120 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003121 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003122 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003123 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003124 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003125 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003126 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003127 }
3128 return nil
3129}
3130
dbainbri4d3a0dc2020-12-02 00:33:42 +00003131func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003132 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003133 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003134 logger.Errorw(ctx, "error generating me instance id",
3135 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003136 return err
3137 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003138 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3139 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003140 //TODO check that this is correct
3141 // Table control
3142 //setCtrl = 1
3143 //rowPartId = 0
3144 //test = 0
3145 //rowKey = 0
3146 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003147 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003148 dynamicAccessCL := make([]uint8, 24)
3149 copy(dynamicAccessCL, tableCtrl)
3150 //Multicast GemPortId
3151 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3152 // python version waits for installation of flows, see line 723 onward of
3153 // brcm_openomci_onu_handler.py
3154 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3155 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003156 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003157 //TODO start and end are hardcoded, get from TP
3158 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003159 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003160 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003161 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003162 //imputed group bandwidth
3163 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3164
3165 meParams := me.ParamData{
3166 EntityID: instID,
3167 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003168 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003169 },
3170 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003171 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003172 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3173 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3174 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003175 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003176 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003177 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3178 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003179 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003180 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3181 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003182 //accept also nil as (error) return value for writing to LastTx
3183 // - this avoids misinterpretation of new received OMCI messages
3184 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003185 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003186 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003187 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003188 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003189 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003190 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003191 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003192 }
3193 return nil
3194}
Girish Gowdra26a40922021-01-29 17:14:34 -08003195
khenaidoo42dcdfd2021-10-19 17:34:12 -04003196func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003197 tpID uint8, uniID uint8, gemPortID uint16) error {
3198 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3199 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3200 // I created unique TD ID by flow direction.
3201 // TODO! Traffic descriptor ME ID will check
3202 trafficDescriptorID := gemPortID
3203 if aMeter == nil {
3204 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3205 }
3206 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3207 if err != nil {
3208 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3209 return err
3210 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003211 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003212 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003213 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003214 pbs := trafficShapingInfo.Pbs
3215
3216 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3217 meParams := me.ParamData{
3218 EntityID: trafficDescriptorID,
3219 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003220 me.TrafficDescriptor_Cir: cir,
3221 me.TrafficDescriptor_Pir: pir,
3222 me.TrafficDescriptor_Cbs: cbs,
3223 me.TrafficDescriptor_Pbs: pbs,
3224 me.TrafficDescriptor_ColourMode: 1,
3225 me.TrafficDescriptor_IngressColourMarking: 3,
3226 me.TrafficDescriptor_EgressColourMarking: 3,
3227 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003228 },
3229 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003230 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003231 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3232 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003233 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003234 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003235 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3236 return err
3237 }
3238 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003239 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003240 err = oFsm.waitforOmciResponse(ctx)
3241 if err != nil {
3242 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3243 return err
3244 }
3245
Girish Gowdra09e5f212021-09-30 16:28:36 -07003246 // 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
3247 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003248 if err != nil {
3249 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3250 return err
3251 }
3252 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3253
3254 return nil
3255}
3256
Girish Gowdra09e5f212021-09-30 16:28:36 -07003257func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3258 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3259 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003260 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003261 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003262 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003263 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003264 },
3265 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003266 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003267 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3268 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003269 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003270 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003271 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3272 return err
3273 }
3274 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003275 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003276 err = oFsm.waitforOmciResponse(ctx)
3277 if err != nil {
3278 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3279 return err
3280 }
3281 return nil
3282}
3283
Girish Gowdra26a40922021-01-29 17:14:34 -08003284// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003285func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3286 if oFsm == nil {
3287 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3288 return false
3289 }
mpagenkobb47bc22021-04-20 13:29:09 +00003290 oFsm.mutexFlowParams.Lock()
3291 defer oFsm.mutexFlowParams.Unlock()
3292 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3293 //flow removal is still ongoing/pending
3294 oFsm.signalOnFlowDelete = true
3295 oFsm.flowDeleteChannel = aFlowDeleteChannel
3296 return true
3297 }
3298 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003299}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003300
3301func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3302 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3303 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3304 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3305 log.Fields{"device-id": oFsm.deviceID})
3306 } else {
3307 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3308 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3309 "index": oFsm.numVlanFilterEntries,
3310 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3311 "device-id": oFsm.deviceID})
3312 oFsm.numVlanFilterEntries++
3313 }
3314}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003315
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003316// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3317func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003318 if respChan != nil {
3319 // 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
3320 select {
3321 case *respChan <- err:
3322 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3323 default:
3324 }
3325 }
3326}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003327
3328// PrepareForGarbageCollection - remove references to prepare for garbage collection
3329func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3330 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3331 oFsm.pDeviceHandler = nil
3332 oFsm.pOnuDeviceEntry = nil
3333 oFsm.pOmciCC = nil
3334}