blob: bc927c155b396614946883674866152e2a6d58a1 [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{
bseeniva5f32c452025-07-18 17:30:41 +05302339 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID,
2340 "tags-to-remove": oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove})
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302341 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2342 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2343 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2344 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2345 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002346
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302347 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2348 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2349 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2350 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2351 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002352
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302353 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2354 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2355 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2356 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2357 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2358
2359 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2360 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2361 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2362 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2363
2364 } else {
2365 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2366 //As of now only a match and no action can be done on the inner tag .
2367 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2368 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2369 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2370 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2371 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2372 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2373 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2374
2375 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2376 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2377 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2378 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2379 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2380
2381 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2382 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2383 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2384 setVid<<cTreatVidOffset| // Set VID
2385 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2386
2387 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2388 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2389 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2390 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2391 }
mpagenko551a4d42020-12-08 18:09:20 +00002392 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002393 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002394 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002395 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002396 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002397 },
2398 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002399 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002400 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2401 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2402 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002403 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002404 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002405 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2406 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002407 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002408 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2409 }
mpagenkodff5dda2020-08-28 11:52:01 +00002410 //accept also nil as (error) return value for writing to LastTx
2411 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002412 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002413 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002414
2415 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002416 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002417 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302418 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002419 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002420 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302421 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002422 }
2423 } else {
2424 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2425 { // just for local var's
2426 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002427 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002428 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002429 sliceEvtocdRule := make([]uint8, 16)
2430 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2431 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2432 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2433 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2434 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2435
2436 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2437 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2438 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2439 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2440 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2441
2442 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2443 0<<cTreatTTROffset| // Do not pop any tags
2444 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2445 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2446 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2447
2448 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2449 0<<cTreatPrioOffset| // vlan prio set to 0
2450 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002451 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002452 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2453
mpagenko551a4d42020-12-08 18:09:20 +00002454 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002455 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002456 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002457 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002458 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002459 },
2460 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2463 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2464 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002465 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002466 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002467 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2468 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002469 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002470 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2471 }
mpagenkodff5dda2020-08-28 11:52:01 +00002472 //accept also nil as (error) return value for writing to LastTx
2473 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002474 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002475 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002476
2477 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002478 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002479 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002481 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002483 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2484
mpagenkodff5dda2020-08-28 11:52:01 +00002485 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002486 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002487 { // just for local var's
2488 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002489 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002490 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002491 sliceEvtocdRule := make([]uint8, 16)
2492 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2493 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2494 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2495 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2496 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2497
2498 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2499 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2500 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2501 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2502 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2503
2504 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2505 1<<cTreatTTROffset| // pop the prio-tag
2506 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2507 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2508 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2509
mpagenko551a4d42020-12-08 18:09:20 +00002510 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002511 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2512 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2513 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002514 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002515 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002516 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002517
2518 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002519 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002520 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002521 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002522 },
2523 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002524 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2526 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2527 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002528 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002529 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002530 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2531 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002533 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2534 }
mpagenkodff5dda2020-08-28 11:52:01 +00002535 //accept also nil as (error) return value for writing to LastTx
2536 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002537 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002538 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002539
2540 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002541 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002542 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002543 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002544 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002546 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2547
mpagenkodff5dda2020-08-28 11:52:01 +00002548 }
2549 } //just for local var's
2550 }
2551 }
2552
mpagenkofc4f56e2020-11-04 17:17:49 +00002553 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002554 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002555 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002556 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002557 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002558 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002559}
2560
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002562 oFsm.mutexFlowParams.RLock()
2563 evtocdID := oFsm.evtocdID
2564 oFsm.mutexFlowParams.RUnlock()
2565
mpagenko01e726e2020-10-23 09:45:29 +00002566 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2567 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2568 //transparent transmission was set
2569 //perhaps the config is not needed for removal,
2570 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002572 "device-id": oFsm.deviceID})
2573 sliceEvtocdRule := make([]uint8, 16)
2574 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2575 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2576 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2577 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2578 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2579
2580 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2581 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2582 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2583 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2584 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2585
2586 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2587 0<<cTreatTTROffset| // Do not pop any tags
2588 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2589 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2590 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2591
2592 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2593 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2594 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2595 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2596
2597 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002598 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002599 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002600 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002601 },
2602 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002603 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002604 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2605 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2606 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002607 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002608 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002609 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2610 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002611 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002612 return
2613 }
mpagenko01e726e2020-10-23 09:45:29 +00002614 //accept also nil as (error) return value for writing to LastTx
2615 // - this avoids misinterpretation of new received OMCI messages
2616 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002617 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002618
2619 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002620 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002621 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002622 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002623 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002624 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002625 return
2626 }
2627 } else {
2628 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002629 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002630 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002631 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002632 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302633 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002634
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302635 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2636 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2637 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2638 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2639 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2640 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2641 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2642 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002643
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302644 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2645 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2646 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2647 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2648 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002649
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302650 // delete indication for the indicated Filter
2651 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2652 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2653
2654 } else {
2655 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2656 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2657 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302658 sliceEvtocdRule = make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302659 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2660 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2661 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2662 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2663 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2664
2665 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2666 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2667 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2668 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2669 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2670
2671 // delete indication for the indicated Filter
2672 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2673 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2674 }
mpagenko01e726e2020-10-23 09:45:29 +00002675 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002676 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002677 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002678 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002679 },
2680 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002681 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2683 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2684 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002685 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002686 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002687 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2688 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002690 return
2691 }
mpagenko01e726e2020-10-23 09:45:29 +00002692 //accept also nil as (error) return value for writing to LastTx
2693 // - this avoids misinterpretation of new received OMCI messages
2694 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002695 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002696
2697 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002698 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002699 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302700 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2701 log.Fields{"device-id": oFsm.deviceID,
2702 "match-vlan": aRuleParams.MatchVid,
2703 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002705 return
2706 }
2707 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002708 // VOL-3685
2709 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2710 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2711 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2712 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2713 // later when the flow is being re-installed.
2714 // Of course this is applicable to case only where single service (or single tcont) is in use and
2715 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2716 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2717 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002719 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002720 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002721 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2722 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002723 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002724 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002725 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002726 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002727 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2728 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2729 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002730 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002731 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002732 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2733 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002734 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002735 return
2736 }
mpagenko01e726e2020-10-23 09:45:29 +00002737 //accept also nil as (error) return value for writing to LastTx
2738 // - this avoids misinterpretation of new received OMCI messages
2739 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002740 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002741
2742 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002743 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002744 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002745 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002746 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002747 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002748 return
2749 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002750 } else {
2751 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2752 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002753 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002754 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002755 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002756 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2757 { // just for local var's
2758 // this defines stacking scenario: untagged->singletagged
2759 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2760 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2761 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2762 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002763 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002764 "device-id": oFsm.deviceID})
2765 sliceEvtocdRule := make([]uint8, 16)
2766 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2767 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2768 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2769 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2770 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002771
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002772 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2773 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2774 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2775 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2776 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002777
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002778 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2779 0<<cTreatTTROffset| // Do not pop any tags
2780 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2781 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2782 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002783
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002784 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2785 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2786 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2787 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002788
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002789 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002790 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002791 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002792 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002793 },
2794 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002795 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002796 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2797 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2798 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002799 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002800 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002801 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2802 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002803 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002804 return
2805 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002806 //accept also nil as (error) return value for writing to LastTx
2807 // - this avoids misinterpretation of new received OMCI messages
2808 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002809 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002810
2811 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002812 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002813 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002814 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002815 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002816 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002817 return
2818 }
2819 } // just for local var's
2820 { // just for local var's
2821 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002822 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002823 "device-id": oFsm.deviceID})
2824 sliceEvtocdRule := make([]uint8, 16)
2825 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2826 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2827 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2828 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2829 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2830
2831 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2832 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2833 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2834 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2835 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2836
2837 // delete indication for the indicated Filter
2838 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2839 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2840
2841 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002842 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002844 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 },
2846 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002847 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2849 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2850 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002851 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002852 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002853 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2854 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002856 return
2857 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002858 //accept also nil as (error) return value for writing to LastTx
2859 // - this avoids misinterpretation of new received OMCI messages
2860 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002861 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002862
2863 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002864 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002865 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002869 return
2870 }
mpagenko01e726e2020-10-23 09:45:29 +00002871 }
2872 } //just for local var's
2873 }
2874 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002875 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002876 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002878}
2879
dbainbri4d3a0dc2020-12-02 00:33:42 +00002880func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002881 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002882 if oFsm.isCanceled {
2883 // FSM already canceled before entering wait
2884 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2885 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002886 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002887 }
mpagenko7d6bb022021-03-11 15:07:55 +00002888 oFsm.isAwaitingResponse = true
2889 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002890 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302891 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002892 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002894 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002896 oFsm.mutexIsAwaitingResponse.Lock()
2897 oFsm.isAwaitingResponse = false
2898 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002899 oFsm.mutexPLastTxMeInstance.RLock()
2900 if oFsm.pLastTxMeInstance != nil {
2901 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2902 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2903 }
2904 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002905 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002906 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302907 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002908 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002909 oFsm.mutexIsAwaitingResponse.Lock()
2910 oFsm.isAwaitingResponse = false
2911 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002912 return nil
2913 }
mpagenko7d6bb022021-03-11 15:07:55 +00002914 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002915 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002916 oFsm.mutexIsAwaitingResponse.Lock()
2917 oFsm.isAwaitingResponse = false
2918 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002920 }
2921}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002922
mpagenko551a4d42020-12-08 18:09:20 +00002923func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002924 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002926 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002927 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002928 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002929 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002930 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002931 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2932 }
2933
dbainbri4d3a0dc2020-12-02 00:33:42 +00002934 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002935 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002936 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002937 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002938 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002939 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2940 }
2941
dbainbri4d3a0dc2020-12-02 00:33:42 +00002942 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002943 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002944 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002945 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002946 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002947 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2948 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002950 if errMacBpCdEID != nil {
2951 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2952 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002953 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002954 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002955
Mahir Gunyel6781f962021-05-16 23:30:08 -07002956 }
2957 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002958 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2959 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002960 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002961 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002962 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002963 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2964 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2965 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2966 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002967 },
2968 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002969 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2971 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002972 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002973 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002974 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2975 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002976 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002977 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2978 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002979 //accept also nil as (error) return value for writing to LastTx
2980 // - this avoids misinterpretation of new received OMCI messages
2981 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002982 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002983 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002984 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002985 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2987 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002988 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2989 }
2990
2991 // ==> Start creating VTFD for mcast vlan
2992
2993 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2994 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002995 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002996
dbainbri4d3a0dc2020-12-02 00:33:42 +00002997 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002998 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002999 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003000 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
3001
3002 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
3003 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
3004 // new vlan associated with a different TP.
3005 vtfdFilterList[0] = uint16(vlanID)
3006
3007 meParams = me.ParamData{
3008 EntityID: mcastVtfdID,
3009 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003010 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
3011 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
3012 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003013 },
3014 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003015 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3017 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003018 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003019 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003020 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3021 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003023 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3024 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003025 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003026 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003027 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003028 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003029 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003030 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003032 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3033 }
3034
3035 return nil
3036}
3037
dbainbri4d3a0dc2020-12-02 00:33:42 +00003038func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003039 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003040 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003041 logger.Errorw(ctx, "error generrating me instance id",
3042 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003043 return err
3044 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003045 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3046 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003047 meParams := me.ParamData{
3048 EntityID: instID,
3049 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003050 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003051 //Direct reference to the Operation profile
3052 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003053 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003054 },
3055 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003056 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003057 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3058 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3059 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003060 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003061 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003062 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3063 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003064 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003065 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3066 oFsm.deviceID, err)
3067 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003068 //accept also nil as (error) return value for writing to LastTx
3069 // - this avoids misinterpretation of new received OMCI messages
3070 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003071 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003072 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003074 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003075 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003076 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3077 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3078 }
3079 return nil
3080}
3081
dbainbri4d3a0dc2020-12-02 00:33:42 +00003082func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003084 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003085 logger.Errorw(ctx, "error generating me instance id",
3086 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003087 return err
3088 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003089 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3090 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003091 meParams := me.ParamData{
3092 EntityID: instID,
3093 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003094 me.MulticastOperationsProfile_IgmpVersion: 2,
3095 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003096 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003097 me.MulticastOperationsProfile_ImmediateLeave: 0,
3098 me.MulticastOperationsProfile_Robustness: 2,
3099 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3100 me.MulticastOperationsProfile_QueryInterval: 125,
3101 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3102 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003103 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003104 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003105 },
3106 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003107 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003108 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3109 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3110 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003111 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003112 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003113 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3114 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003115 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003116 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3117 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003118 //accept also nil as (error) return value for writing to LastTx
3119 // - this avoids misinterpretation of new received OMCI messages
3120 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003121 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003122 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003123 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003124 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003125 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003126 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003127 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003128 }
3129 return nil
3130}
3131
dbainbri4d3a0dc2020-12-02 00:33:42 +00003132func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003133 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003134 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003135 logger.Errorw(ctx, "error generating me instance id",
3136 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003137 return err
3138 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003139 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3140 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003141 //TODO check that this is correct
3142 // Table control
3143 //setCtrl = 1
3144 //rowPartId = 0
3145 //test = 0
3146 //rowKey = 0
3147 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003149 dynamicAccessCL := make([]uint8, 24)
3150 copy(dynamicAccessCL, tableCtrl)
3151 //Multicast GemPortId
3152 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3153 // python version waits for installation of flows, see line 723 onward of
3154 // brcm_openomci_onu_handler.py
3155 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3156 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003157 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003158 //TODO start and end are hardcoded, get from TP
3159 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003160 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003161 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003162 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003163 //imputed group bandwidth
3164 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3165
3166 meParams := me.ParamData{
3167 EntityID: instID,
3168 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003169 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003170 },
3171 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003172 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003173 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3174 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3175 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003176 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003177 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003178 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3179 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003180 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003181 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3182 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003183 //accept also nil as (error) return value for writing to LastTx
3184 // - this avoids misinterpretation of new received OMCI messages
3185 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003186 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003187 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003188 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003189 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003190 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003191 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003192 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003193 }
3194 return nil
3195}
Girish Gowdra26a40922021-01-29 17:14:34 -08003196
khenaidoo42dcdfd2021-10-19 17:34:12 -04003197func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003198 tpID uint8, uniID uint8, gemPortID uint16) error {
3199 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3200 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3201 // I created unique TD ID by flow direction.
3202 // TODO! Traffic descriptor ME ID will check
3203 trafficDescriptorID := gemPortID
3204 if aMeter == nil {
3205 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3206 }
3207 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3208 if err != nil {
3209 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3210 return err
3211 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003212 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003213 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003214 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003215 pbs := trafficShapingInfo.Pbs
3216
3217 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3218 meParams := me.ParamData{
3219 EntityID: trafficDescriptorID,
3220 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003221 me.TrafficDescriptor_Cir: cir,
3222 me.TrafficDescriptor_Pir: pir,
3223 me.TrafficDescriptor_Cbs: cbs,
3224 me.TrafficDescriptor_Pbs: pbs,
3225 me.TrafficDescriptor_ColourMode: 1,
3226 me.TrafficDescriptor_IngressColourMarking: 3,
3227 me.TrafficDescriptor_EgressColourMarking: 3,
3228 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003229 },
3230 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003231 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003232 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3233 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003234 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003235 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003236 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3237 return err
3238 }
3239 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003240 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003241 err = oFsm.waitforOmciResponse(ctx)
3242 if err != nil {
3243 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3244 return err
3245 }
3246
Girish Gowdra09e5f212021-09-30 16:28:36 -07003247 // 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
3248 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003249 if err != nil {
3250 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3251 return err
3252 }
3253 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3254
3255 return nil
3256}
3257
Girish Gowdra09e5f212021-09-30 16:28:36 -07003258func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3259 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3260 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003261 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003262 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003263 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003264 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003265 },
3266 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003267 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003268 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3269 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003270 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003271 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003272 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3273 return err
3274 }
3275 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003276 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003277 err = oFsm.waitforOmciResponse(ctx)
3278 if err != nil {
3279 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3280 return err
3281 }
3282 return nil
3283}
3284
Girish Gowdra26a40922021-01-29 17:14:34 -08003285// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003286func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3287 if oFsm == nil {
3288 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3289 return false
3290 }
mpagenkobb47bc22021-04-20 13:29:09 +00003291 oFsm.mutexFlowParams.Lock()
3292 defer oFsm.mutexFlowParams.Unlock()
3293 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3294 //flow removal is still ongoing/pending
3295 oFsm.signalOnFlowDelete = true
3296 oFsm.flowDeleteChannel = aFlowDeleteChannel
3297 return true
3298 }
3299 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003300}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003301
3302func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3303 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3304 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3305 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3306 log.Fields{"device-id": oFsm.deviceID})
3307 } else {
3308 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3309 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3310 "index": oFsm.numVlanFilterEntries,
3311 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3312 "device-id": oFsm.deviceID})
3313 oFsm.numVlanFilterEntries++
3314 }
3315}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003316
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003317// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3318func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003319 if respChan != nil {
3320 // 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
3321 select {
3322 case *respChan <- err:
3323 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3324 default:
3325 }
3326 }
3327}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003328
3329// PrepareForGarbageCollection - remove references to prepare for garbage collection
3330func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3331 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3332 oFsm.pDeviceHandler = nil
3333 oFsm.pOnuDeviceEntry = nil
3334 oFsm.pOmciCC = nil
3335}