blob: 9b0b8b94930625edb565b14f95d0e196a5dc3731 [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()
bseeniva34743192025-07-24 14:42:56 +0530999 return true
mpagenkof582d6a2021-06-18 15:58:10 +00001000 } // if not in the appropriate state a new entry will be automatically considered later
1001 // when the configDone state is reached
bseeniva34743192025-07-24 14:42:56 +05301002 // If the FSM is in Disabled or resetted state, push a response on the flow response channel
1003 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkof582d6a2021-06-18 15:58:10 +00001004 return true
1005}
1006
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301007// removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1008//
1009// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1010// from the start of the deletion request to avoid to much interference
1011// so when called, there can only be one cookie active for this flow
1012//
mpagenkof1d21d12021-06-11 13:14:45 +00001013// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001014func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001015 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1016 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001017 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001018removeFromSlice_loop:
1019 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001020 // if UniFlowParams exists, cookieSlice should always have at least one element
1021 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1022 if cookieSliceLen == 1 {
1023 if storedUniFlowParams.CookieSlice[0] == aCookie {
1024 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001025 }
mpagenkof582d6a2021-06-18 15:58:10 +00001026 } else if cookieSliceLen == 0 {
1027 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1028 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1029 return errors.New(errStr)
1030 } else {
1031 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1032 logger.Errorw(ctx, errStr, log.Fields{
1033 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1034 for _, cookie := range storedUniFlowParams.CookieSlice {
1035 if cookie == aCookie {
1036 cookieFound = true
1037 break
1038 }
1039 }
1040 }
1041 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001042 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1043 "device-id": oFsm.deviceID, "cookie": aCookie})
1044 //remove the actual element from the addVlanFlow slice
1045 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1046 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 oFsm.NumUniFlows = 0 //no more flows
1048 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001049 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1050 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1051 //request that this profile gets deleted before a new flow add is allowed
1052 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1053 "device-id": oFsm.deviceID})
1054 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 oFsm.NumUniFlows--
1056 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1057 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001058 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001059 if !aWasConfigured {
1060 // We did not actually process this flow but was removed before that.
1061 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001062 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001063 }
1064
mpagenkof1d21d12021-06-11 13:14:45 +00001065 //cut off the requested flow by slicing out this element
1066 oFsm.uniVlanFlowParamsSlice = append(
1067 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1068 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1069 "device-id": oFsm.deviceID})
1070 }
1071 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1072 }
1073 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001074 if !cookieFound {
1075 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1076 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1077 return errors.New(errStr)
1078 }
mpagenkodee02a62021-07-21 10:56:10 +00001079 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1080 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001081 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001082 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1083 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1084 return err
1085 }
mpagenkof582d6a2021-06-18 15:58:10 +00001086 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001087}
1088
1089// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001090func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1091 //here we have to check, if there are still other flows referencing to the actual ProfileId
1092 // before we can request that this profile gets deleted before a new flow add is allowed
1093 tpIDInOtherFlows := false
1094 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1095 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1096 tpIDInOtherFlows = true
1097 break // search loop can be left
1098 }
1099 }
1100 if tpIDInOtherFlows {
1101 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1102 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1103 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001104 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 +00001105 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001106 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1107 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001108 if oFsm.pUniTechProf != nil {
1109 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001110 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001111 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001112 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001113 }
1114}
1115
mpagenkof1d21d12021-06-11 13:14:45 +00001116func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1117 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001118
1119 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001120 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001121 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001122 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001123 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001125 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001127 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001128 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001129 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001131 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001132 go func(a_pAFsm *cmn.AdapterFsm) {
1133 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001134 }(pConfigVlanStateAFsm)
1135 return
1136 }
mpagenkof1d21d12021-06-11 13:14:45 +00001137 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 go func(a_pAFsm *cmn.AdapterFsm) {
1139 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001140 }(pConfigVlanStateAFsm)
1141 return
1142 }
1143 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1144 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1145 //should never happen, else: recovery would be needed from outside the FSM
1146}
1147
1148func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1149 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001151 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001152 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001153 //possibly the entry is not valid anymore based on intermediate delete requests
1154 //just a basic protection ...
1155 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1156 oFsm.mutexFlowParams.Unlock()
1157 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1158 "device-id": oFsm.deviceID})
1159 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001160 go func(a_pAFsm *cmn.AdapterFsm) {
1161 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001162 }(pConfigVlanStateAFsm)
1163 return
1164 }
mpagenko9a304ea2020-12-16 15:54:01 +00001165 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1166 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001167 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1168 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001169 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001170 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001171 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1172 // synchronous FSM 'event/state' functions may rely on this mutex
1173 // but it must be released already before calling getTechProfileDone() as it may already be locked
1174 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001175 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001176 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001177 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001179 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001180
mpagenko9a304ea2020-12-16 15:54:01 +00001181 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001182 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1183 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001184 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001185 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001186 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001187 } else {
1188 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001189 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001190 }
1191 }
mpagenko551a4d42020-12-08 18:09:20 +00001192 }(pConfigVlanStateAFsm, loTechProfDone)
1193 } else {
1194 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1195 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1196 //should never happen, else: recovery would be needed from outside the FSM
1197 return
mpagenkodff5dda2020-08-28 11:52:01 +00001198 }
1199}
1200
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001202 //mutex protection is required for possible concurrent access to FSM members
1203 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001204 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001205 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001206 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001207 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001209 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001210 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001211 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001212 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001213 go func(a_pAFsm *cmn.AdapterFsm) {
1214 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001215 }(pConfigVlanStateAFsm)
1216 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001217 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1218 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001219 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001221 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001222 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001223 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001224 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001225 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001226 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001227 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001228 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1229 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001230 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001231 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001232 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001233 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1234 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1235 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001236 },
1237 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001239 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001240 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1242 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001243 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001244 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001245 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1246 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001247 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001248 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 go func(a_pAFsm *cmn.AdapterFsm) {
1250 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001251 }(pConfigVlanStateAFsm)
1252 }
1253 return
1254 }
mpagenkodff5dda2020-08-28 11:52:01 +00001255 //accept also nil as (error) return value for writing to LastTx
1256 // - this avoids misinterpretation of new received OMCI messages
1257 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1258 // send shall return (dual format) error code that can be used here for immediate error treatment
1259 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001260 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001261 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001262 }
1263}
1264
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301265//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1267 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001268 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001269 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001270 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001271 //using the first element in the slice because it's the first flow per definition here
1272 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001273 //This is correct passing scenario
1274 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001275 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001276 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1277 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001278 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001279 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1280 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001285 vlanID)
1286 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001287 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001288 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001290 }
1291 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001292 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001293 if oFsm.actualUniFlowParam.Meter != nil {
1294 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001296 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1297 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001298 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001299 if errCreateTrafficDescriptor != nil {
1300 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1301 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001303 }
1304 }
1305 }
1306
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001307 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001309 }
1310 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001311}
1312
dbainbri4d3a0dc2020-12-02 00:33:42 +00001313func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001314
mpagenkof1d21d12021-06-11 13:14:45 +00001315 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001316
mpagenkof1fc3862021-02-16 10:09:52 +00001317 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001318 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001320 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001321 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001322 }
1323
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001324 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001325 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001326 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001327 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1328 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1329 //should never happen, else: recovery would be needed from outside the FSM
1330 return
1331 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001332 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001333 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1334 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001335 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001337 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1338 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001339 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001340 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001341 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001343 }(pConfigVlanStateBaseFsm)
1344 return
1345 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001346 if oFsm.lastFlowToReconcile {
1347 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1348 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1349 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1350 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1351 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1352 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301353 if oFsm.lastFlowToConfigOnReboot {
1354 logger.Debugw(ctx, "rebooting - flow processing finished", log.Fields{
1355 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1356 oFsm.pDeviceHandler.SendChUniVlanConfigFinishedOnReboot(uint16(oFsm.pOnuUniPort.UniID))
1357 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1359 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001360 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001362 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001363 return
1364 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1366 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001367 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001368 // this is a restart with a complete new flow, we can re-use the initial flow config control
1369 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001370 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001371 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001372 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001373 }(pConfigVlanStateBaseFsm)
1374 return
1375 }
1376
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001377 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001378 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001379 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001380 //check introduced after having observed some panic in this processing
1381 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001383 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1384 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001385 go func(a_pAFsm *cmn.AdapterFsm) {
1386 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001387 }(pConfigVlanStateAFsm)
1388 return
1389 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001390 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001391 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001392 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001393 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001394 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001395 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1396 // synchronous FSM 'event/state' functions may rely on this mutex
1397 // but it must be released already before calling getTechProfileDone() as it may already be locked
1398 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1399 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001400 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001401 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001402 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001403 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1404
mpagenko9a304ea2020-12-16 15:54:01 +00001405 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001406 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1407 if aTechProfDone {
1408 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001410 } else {
1411 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001413 }
1414 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001415 return
1416 }
mpagenkof1d21d12021-06-11 13:14:45 +00001417 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001419 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001420 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1421 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001422 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001423 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001424 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001425 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001426 }
1427}
1428
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001430
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001431 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001432 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001433 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001434 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001435 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1436 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001437 return
1438 }
mpagenko15ff4a52021-03-02 10:09:20 +00001439 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001442 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001443 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001444
Girish Gowdrae95687a2021-09-08 16:30:58 -07001445 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001446 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001448 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001449 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001450 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1451 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1452 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1453 // 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 +00001454 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001455 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1456 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001457 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001458 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001459 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001460 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001461 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001462 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001463 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001464 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001465
mpagenko01e726e2020-10-23 09:45:29 +00001466 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001467 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1468 oFsm.numVlanFilterEntries = 1
1469 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001470 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001471 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001472 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1473 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1474 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001475 },
1476 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001477 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001478 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1479 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001480 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001481 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001482 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001483 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1484 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001485 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001486 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001487 go func(a_pAFsm *cmn.AdapterFsm) {
1488 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001489 }(pConfigVlanStateAFsm)
1490 }
1491 return
1492 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001493 //accept also nil as (error) return value for writing to LastTx
1494 // - this avoids misinterpretation of new received OMCI messages
1495 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1496 // send shall return (dual format) error code that can be used here for immediate error treatment
1497 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001498 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001499 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001500 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001501 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1502 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001503 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001504
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001506 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001507 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001508 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001509 // setVid is assumed to be masked already by the caller to 12 bit
1510 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001511 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001512 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001513
1514 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1515 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1516 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001517 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001518
1519 oFsm.numVlanFilterEntries++
1520 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001521 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001522 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001523 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1524 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1525 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001526 },
1527 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001528 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001529 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1530 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001531 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001532 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001533 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001534 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1535 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001536 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001537 return
1538 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001539 //accept also nil as (error) return value for writing to LastTx
1540 // - this avoids misinterpretation of new received OMCI messages
1541 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1542 // send shall return (dual format) error code that can be used here for immediate error treatment
1543 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001544 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001545 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001546 }
1547 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001549 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001550 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001552 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001553 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001554 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001555 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001557 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001558 return
1559 }
1560 }
mpagenkof1d21d12021-06-11 13:14:45 +00001561
mpagenkof1fc3862021-02-16 10:09:52 +00001562 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001563 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001565 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001566 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1567 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001568 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001569 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001570 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001571 //This is correct passing scenario
1572 if errEvto == nil {
1573 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001575 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001576 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001578 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001579 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001580 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001582 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001584 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001585 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001586 }
1587 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001588 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001589 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001591 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1592 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001593 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001594 if errCreateTrafficDescriptor != nil {
1595 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1596 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001597 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001598 }
1599 }
1600 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001602 }
1603 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001604}
1605
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001607 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001609 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1610 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001611
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1613 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001614 loVlanEntryClear := uint8(0)
1615 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1616 //shallow copy is sufficient as no reference variables are used within struct
1617 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001618 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001619 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001620 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1621 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1622 "device-id": oFsm.deviceID})
1623
1624 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1625 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001627 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1628 } else {
1629 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1630 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001631 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001632 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1633 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001635 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001636 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001637 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001638 loVlanEntryClear = 1 //full VlanFilter clear request
1639 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001640 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001641 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1642 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001643 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001644 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001645 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1646 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001647 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001648 return
1649 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001650 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001651 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001652 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001654 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001655 }
mpagenko01e726e2020-10-23 09:45:29 +00001656 } else {
1657 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1658 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001660 log.Fields{"current vlan list": oFsm.vlanFilterList,
1661 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1662 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1663 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1664 loVlanEntryRmPos = i
1665 break //abort search
1666 }
1667 }
1668 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001669 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001670 //valid entry was found - to be eclipsed
1671 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1672 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1673 if i < loVlanEntryRmPos {
1674 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1675 } else if i < (cVtfdTableSize - 1) {
1676 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1677 } else {
1678 vtfdFilterList[i] = 0 //set last byte if needed
1679 }
1680 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001682 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001683 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001685
mpagenkofc4f56e2020-11-04 17:17:49 +00001686 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001687 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001688 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001689 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1690 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001691 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001692 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001693 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1694 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001695 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001696 return
1697 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001698 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001699 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001700 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001702 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001703 }
mpagenko01e726e2020-10-23 09:45:29 +00001704 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001706 log.Fields{"device-id": oFsm.deviceID})
1707 }
1708 }
1709 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001710 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1711 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001713 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001714 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001715 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001716 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001717 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001718 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001719 }(pConfigVlanStateBaseFsm)
1720 return
1721 }
mpagenko01e726e2020-10-23 09:45:29 +00001722 }
1723
mpagenko15ff4a52021-03-02 10:09:20 +00001724 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001725 if loVlanEntryClear == 1 {
1726 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1727 oFsm.numVlanFilterEntries = 0
1728 } else if loVlanEntryClear == 2 {
1729 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1730 // this loop now includes the 0 element on previous last valid entry
1731 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1732 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1733 }
1734 oFsm.numVlanFilterEntries--
1735 }
mpagenko15ff4a52021-03-02 10:09:20 +00001736 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001737 }
1738 }
1739
mpagenkofc4f56e2020-11-04 17:17:49 +00001740 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001741 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001742 } else {
1743 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001744 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001745 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001746 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001747 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001748 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001749 }(pConfigVlanStateBaseFsm)
1750 }
mpagenkodff5dda2020-08-28 11:52:01 +00001751}
1752
dbainbri4d3a0dc2020-12-02 00:33:42 +00001753func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001754 var tpID uint8
1755 // Extract the tpID
1756 if len(e.Args) > 0 {
1757 tpID = e.Args[0].(uint8)
1758 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1759 } else {
1760 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1761 }
mpagenko01e726e2020-10-23 09:45:29 +00001762 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001763 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001764
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001765 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001766 if pConfigVlanStateAFsm == nil {
1767 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1768 log.Fields{"device-id": oFsm.deviceID})
1769 //would have to be fixed from outside somehow
1770 return
1771 }
1772
mpagenkof1d21d12021-06-11 13:14:45 +00001773 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1774 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001775 //call from 'configured' state of the rule
1776 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1777 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1778 oFsm.mutexFlowParams.Unlock()
1779 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001780 go func(a_pAFsm *cmn.AdapterFsm) {
1781 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001782 }(pConfigVlanStateAFsm)
1783 return
1784 }
mpagenkof1d21d12021-06-11 13:14:45 +00001785 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1786 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1787 oFsm.mutexFlowParams.Unlock()
1788 removeChannel <- true
1789 oFsm.mutexFlowParams.Lock()
1790 }
1791
mpagenkof1fc3862021-02-16 10:09:52 +00001792 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1793 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1794 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1795
Girish Gowdrae95687a2021-09-08 16:30:58 -07001796 // Store the reference to the flow response channel before this entry in the slice is deleted
1797 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1798
mpagenko01e726e2020-10-23 09:45:29 +00001799 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1800 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001801 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001802 "device-id": oFsm.deviceID})
1803 } else {
1804 //cut off the actual flow by slicing out the first element
1805 oFsm.uniRemoveFlowsSlice = append(
1806 oFsm.uniRemoveFlowsSlice[:0],
1807 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001808 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001809 "device-id": oFsm.deviceID})
1810 }
1811 oFsm.mutexFlowParams.Unlock()
1812
mpagenkof1fc3862021-02-16 10:09:52 +00001813 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001814 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001815 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001816 go func(a_pAFsm *cmn.AdapterFsm) {
1817 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001818 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001819
mpagenkobb47bc22021-04-20 13:29:09 +00001820 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001821 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001822 if deletedCookie == oFsm.delayNewRuleCookie {
1823 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1824 select {
1825 case <-oFsm.chCookieDeleted:
1826 logger.Debug(ctx, "flushed CookieDeleted")
1827 default:
1828 }
1829 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1830 }
mpagenkobb47bc22021-04-20 13:29:09 +00001831 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1832 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1833 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 -08001834 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001835 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1836 oFsm.flowDeleteChannel <- true
1837 oFsm.signalOnFlowDelete = false
1838 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001839 }
mpagenkobb47bc22021-04-20 13:29:09 +00001840 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001841
1842 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001843 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001844}
1845
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301846//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1848 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001849
mpagenko0f543222021-11-03 16:24:14 +00001850 oFsm.mutexPLastTxMeInstance.Lock()
1851 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1852 oFsm.mutexPLastTxMeInstance.Unlock()
1853
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001855 if pConfigVlanStateAFsm != nil {
1856 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001857 fsmAbortMsg := cmn.Message{
1858 Type: cmn.TestMsg,
1859 Data: cmn.TestMessage{
1860 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001861 },
1862 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001863 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001864
mpagenko0f543222021-11-03 16:24:14 +00001865 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1866 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1867
1868 oFsm.mutexFlowParams.RLock()
1869 if oFsm.delayNewRuleCookie != 0 {
1870 // looks like the waiting AddFlow is stuck
1871 oFsm.mutexFlowParams.RUnlock()
1872 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1873 select {
1874 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1875 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001876 }
mpagenko0f543222021-11-03 16:24:14 +00001877 oFsm.mutexFlowParams.RLock()
1878 }
1879 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1880 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1881 if removeUniFlowParams.isSuspendedOnAdd {
1882 removeChannel := removeUniFlowParams.removeChannel
1883 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1884 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1885 oFsm.mutexFlowParams.RUnlock()
1886 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1887 select {
1888 case removeChannel <- false:
1889 default:
1890 }
1891 oFsm.mutexFlowParams.RLock()
1892 }
1893 // Send response on response channel if the caller is waiting on it.
1894 var err error = nil
1895 if !oFsm.isCanceled {
1896 //only if the FSM is not canceled on external request use some error indication for the respChan
1897 // so only at real internal FSM abortion some error code is sent back
1898 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1899 err = fmt.Errorf("internal-error")
1900 }
1901 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1902 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1903 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1904 }
1905 }
1906
1907 if oFsm.pDeviceHandler != nil {
1908 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1909 if !oFsm.isCanceled {
1910 //if the FSM is not canceled on external request use "internal-error" for the respChan
1911 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1912 // Send response on response channel if the caller is waiting on it with according error indication.
1913 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1914 }
Sridhar Ravindraa9cb0442025-07-21 16:55:05 +05301915 // Do not remove pers uni data during reset of FSM. It will be removed when the device is deleted
1916 //var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1917 //_ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
mpagenko0f543222021-11-03 16:24:14 +00001918 } else {
1919 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1920 // no need to remove specific data in this case here
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +05301921 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1922 // Send response on response channel if the caller is waiting on it with according error indication.
1923 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("config-cancelled"))
1924 }
mpagenko0f543222021-11-03 16:24:14 +00001925 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1926 }
1927 }
1928 oFsm.mutexFlowParams.RUnlock()
1929
1930 //try to let the FSM proceed to 'disabled'
1931 // Can't call FSM Event directly, decoupling it
1932 go func(a_pAFsm *cmn.AdapterFsm) {
1933 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1934 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1935 }
1936 }(pConfigVlanStateAFsm)
1937 return
1938 }
1939 oFsm.mutexFlowParams.RUnlock()
1940 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1941 log.Fields{"device-id": oFsm.deviceID})
1942 return
mpagenkodff5dda2020-08-28 11:52:01 +00001943 }
mpagenko0f543222021-11-03 16:24:14 +00001944 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1945 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001946}
1947
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301948//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1950 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001951
mpagenkodff5dda2020-08-28 11:52:01 +00001952 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001953 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001955 return
mpagenkodff5dda2020-08-28 11:52:01 +00001956 }
mpagenko0f543222021-11-03 16:24:14 +00001957 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1958 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001959}
1960
dbainbri4d3a0dc2020-12-02 00:33:42 +00001961func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1962 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001963loop:
1964 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001965 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001967 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001968 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301969 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301971 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301973 break loop
1974 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301976
1977 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001978 case cmn.TestMsg:
1979 msg, _ := message.Data.(cmn.TestMessage)
1980 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001982 break loop
1983 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001984 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985 case cmn.OMCI:
1986 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301988 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301990 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001991 }
1992 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001994}
1995
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001996func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001998 "msgType": msg.OmciMsg.MessageType})
1999
2000 switch msg.OmciMsg.MessageType {
2001 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00002002 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002004 logger.Warnw(ctx, "CreateResponse handling aborted",
2005 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00002006 return
2007 }
mpagenkodff5dda2020-08-28 11:52:01 +00002008 } //CreateResponseType
2009 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00002010 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00002011 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
2012 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002013 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002014 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002015 return
2016 }
2017 msgObj, msgOk := msgLayer.(*omci.SetResponse)
2018 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002020 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002021 return
2022 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002024 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002026 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002027 // possibly force FSM into abort or ignore some errors for some messages?
2028 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2029 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002030 return
2031 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002032 oFsm.mutexPLastTxMeInstance.RLock()
2033 if oFsm.pLastTxMeInstance != nil {
2034 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2035 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2036 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002037 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002038 { // let the MultiEntity config proceed by stopping the wait function
2039 oFsm.mutexPLastTxMeInstance.RUnlock()
2040 oFsm.omciMIdsResponseReceived <- true
2041 return
2042 }
2043 default:
2044 {
2045 logger.Warnw(ctx, "Unsupported ME name received!",
2046 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2047 }
mpagenkodff5dda2020-08-28 11:52:01 +00002048 }
2049 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002050 } else {
2051 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002052 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002053 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002054 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002055 case omci.DeleteResponseType:
2056 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002058 logger.Warnw(ctx, "DeleteResponse handling aborted",
2059 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002060 return
2061 }
2062 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002063 default:
2064 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002065 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002066 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002067 return
2068 }
2069 }
2070}
2071
dbainbri4d3a0dc2020-12-02 00:33:42 +00002072func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002073 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2074 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002075 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002076 log.Fields{"device-id": oFsm.deviceID})
2077 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2078 oFsm.deviceID)
2079 }
2080 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2081 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002083 log.Fields{"device-id": oFsm.deviceID})
2084 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2085 oFsm.deviceID)
2086 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002087 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002088 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002090 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002091 // possibly force FSM into abort or ignore some errors for some messages?
2092 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2093 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002094 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2095 oFsm.deviceID)
2096 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002097 oFsm.mutexPLastTxMeInstance.RLock()
2098 if oFsm.pLastTxMeInstance != nil {
2099 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2100 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2101 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2102 switch oFsm.pLastTxMeInstance.GetName() {
2103 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2104 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002105 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002106 {
2107 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002108 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002109 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002110 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002111 } else { // let the MultiEntity config proceed by stopping the wait function
2112 oFsm.omciMIdsResponseReceived <- true
2113 }
2114 return nil
2115 }
2116 default:
2117 {
2118 logger.Warnw(ctx, "Unsupported ME name received!",
2119 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002120 }
2121 }
2122 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002123 } else {
2124 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002125 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002126 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002127 return nil
2128}
2129
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002131 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2132 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002134 log.Fields{"device-id": oFsm.deviceID})
2135 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2136 oFsm.deviceID)
2137 }
2138 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2139 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002140 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002141 log.Fields{"device-id": oFsm.deviceID})
2142 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2143 oFsm.deviceID)
2144 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05302146 if msgObj.Result == me.UnknownInstance {
2147 logger.Warnw(ctx, "UniVlanConfigFsm - Unknow Instance",
2148 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
2149 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002151 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002152 // possibly force FSM into abort or ignore some errors for some messages?
2153 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2154 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002155 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2156 oFsm.deviceID)
2157 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002158 oFsm.mutexPLastTxMeInstance.RLock()
2159 if oFsm.pLastTxMeInstance != nil {
2160 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2161 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2162 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002163 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002164 { // let the MultiEntity config proceed by stopping the wait function
2165 oFsm.mutexPLastTxMeInstance.RUnlock()
2166 oFsm.omciMIdsResponseReceived <- true
2167 return nil
2168 }
2169 default:
2170 {
2171 logger.Warnw(ctx, "Unsupported ME name received!",
2172 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2173 }
mpagenko01e726e2020-10-23 09:45:29 +00002174 }
2175 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 } else {
2177 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002178 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002179 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002180 return nil
2181}
2182
dbainbri4d3a0dc2020-12-02 00:33:42 +00002183func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002184 oFsm.mutexFlowParams.RLock()
2185 evtocdID := oFsm.evtocdID
2186 oFsm.mutexFlowParams.RUnlock()
2187
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002188 if aFlowEntryNo == 0 {
2189 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002190 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2191 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002193 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002194 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002195 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002196 associationType := 2 // default to UniPPTP
2197 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002198 associationType = 10
2199 }
2200 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002201 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002202 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002203 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002204 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2205 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002206 },
2207 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002208 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2210 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002211 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002212 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002213 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2214 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002215 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002216 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2217 }
mpagenkodff5dda2020-08-28 11:52:01 +00002218 //accept also nil as (error) return value for writing to LastTx
2219 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002220 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002221 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002222
2223 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002224 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002225 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002227 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002228 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002229 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2230 }
2231
2232 // Set the EVTOCD ME default params
2233 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002234 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002235 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002236 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2237 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2238 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002239 },
2240 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002241 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002242 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2243 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2244 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002245 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002246 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002247 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2248 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002249 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002250 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2251 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002252 //accept also nil as (error) return value for writing to LastTx
2253 // - this avoids misinterpretation of new received OMCI messages
2254 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002255 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002256
2257 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002259 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002261 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002262 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002263 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002264 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002265 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002266
mpagenko551a4d42020-12-08 18:09:20 +00002267 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302268 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2269 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002270 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002271 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002273 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002274 sliceEvtocdRule := make([]uint8, 16)
2275 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2276 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2277 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2278 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2279 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2280
2281 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2282 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2283 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2284 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2285 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2286
2287 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2288 0<<cTreatTTROffset| // Do not pop any tags
2289 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2290 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2291 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2292
2293 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2294 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2295 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2296 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2297
2298 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002299 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002300 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002301 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002302 },
2303 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002304 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2306 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2307 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002308 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002309 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2311 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002312 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002313 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2314 }
mpagenkodff5dda2020-08-28 11:52:01 +00002315 //accept also nil as (error) return value for writing to LastTx
2316 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002317 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002318 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002319
2320 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002321 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002322 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002324 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002326 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2327
mpagenkodff5dda2020-08-28 11:52:01 +00002328 }
2329 } else {
2330 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2331 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002332 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2333 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2334 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2335 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302336 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002337 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002338
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302339 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2340 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2341 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
bseeniva5f32c452025-07-18 17:30:41 +05302342 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID,
2343 "tags-to-remove": oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove})
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302344 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2345 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2346 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2347 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2348 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002349
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302350 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2351 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2352 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2353 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2354 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002355
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302356 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2357 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2358 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2359 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2360 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2361
2362 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2363 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2364 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2365 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2366
2367 } else {
2368 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2369 //As of now only a match and no action can be done on the inner tag .
2370 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2371 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2372 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2373 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2374 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2375 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2376 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2377
2378 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2379 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2380 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2381 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2382 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2383
2384 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2385 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2386 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2387 setVid<<cTreatVidOffset| // Set VID
2388 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2389
2390 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2391 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2392 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2393 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2394 }
mpagenko551a4d42020-12-08 18:09:20 +00002395 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002396 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002397 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002398 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002399 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002400 },
2401 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002402 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2404 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2405 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002406 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002407 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002408 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2409 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002410 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002411 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2412 }
mpagenkodff5dda2020-08-28 11:52:01 +00002413 //accept also nil as (error) return value for writing to LastTx
2414 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002415 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002416 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002417
2418 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002419 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002420 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302421 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002422 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002423 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302424 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002425 }
2426 } else {
2427 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2428 { // just for local var's
2429 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002430 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002431 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002432 sliceEvtocdRule := make([]uint8, 16)
2433 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2434 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2435 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2436 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2437 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2438
2439 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2440 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2441 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2442 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2443 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2444
2445 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2446 0<<cTreatTTROffset| // Do not pop any tags
2447 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2448 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2449 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2450
2451 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2452 0<<cTreatPrioOffset| // vlan prio set to 0
2453 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002454 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002455 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2456
mpagenko551a4d42020-12-08 18:09:20 +00002457 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002458 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002459 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002460 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002461 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002462 },
2463 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002464 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002465 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2466 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2467 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002468 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002469 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002470 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2471 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002472 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002473 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2474 }
mpagenkodff5dda2020-08-28 11:52:01 +00002475 //accept also nil as (error) return value for writing to LastTx
2476 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002477 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002478 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002479
2480 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002481 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002482 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002483 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002484 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002485 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002486 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2487
mpagenkodff5dda2020-08-28 11:52:01 +00002488 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002489 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002490 { // just for local var's
2491 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002493 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002494 sliceEvtocdRule := make([]uint8, 16)
2495 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2496 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2497 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2498 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2499 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2500
2501 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2502 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2503 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2504 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2505 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2506
2507 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2508 1<<cTreatTTROffset| // pop the prio-tag
2509 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2510 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2511 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2512
mpagenko551a4d42020-12-08 18:09:20 +00002513 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002514 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2515 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2516 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002517 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002518 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002519 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002520
2521 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002522 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002523 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002524 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002525 },
2526 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002527 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002528 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2529 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2530 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002531 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002532 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002533 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2534 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002535 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002536 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2537 }
mpagenkodff5dda2020-08-28 11:52:01 +00002538 //accept also nil as (error) return value for writing to LastTx
2539 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002540 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002541 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002542
2543 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002544 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002545 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002547 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002549 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2550
mpagenkodff5dda2020-08-28 11:52:01 +00002551 }
2552 } //just for local var's
2553 }
2554 }
2555
mpagenkofc4f56e2020-11-04 17:17:49 +00002556 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002558 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002559 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002560 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002561 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002562}
2563
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002564func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002565 oFsm.mutexFlowParams.RLock()
2566 evtocdID := oFsm.evtocdID
2567 oFsm.mutexFlowParams.RUnlock()
2568
mpagenko01e726e2020-10-23 09:45:29 +00002569 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2570 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2571 //transparent transmission was set
2572 //perhaps the config is not needed for removal,
2573 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002574 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002575 "device-id": oFsm.deviceID})
2576 sliceEvtocdRule := make([]uint8, 16)
2577 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2578 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2579 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2580 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2581 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2582
2583 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2584 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2585 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2586 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2587 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2588
2589 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2590 0<<cTreatTTROffset| // Do not pop any tags
2591 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2592 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2593 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2594
2595 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2596 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2597 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2598 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2599
2600 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002601 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002602 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002603 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002604 },
2605 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002606 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2608 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2609 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002610 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002611 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002612 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2613 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002615 return
2616 }
mpagenko01e726e2020-10-23 09:45:29 +00002617 //accept also nil as (error) return value for writing to LastTx
2618 // - this avoids misinterpretation of new received OMCI messages
2619 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002620 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002621
2622 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002623 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002624 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002625 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002626 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002627 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002628 return
2629 }
2630 } else {
2631 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002632 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002633 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002634 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002635 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302636 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002637
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302638 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2639 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2640 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2641 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2642 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2643 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2644 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2645 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002646
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302647 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2648 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2649 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2650 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2651 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002652
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302653 // delete indication for the indicated Filter
2654 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2655 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2656
2657 } else {
2658 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2659 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2660 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302661 sliceEvtocdRule = make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302662 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2663 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2664 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2665 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2666 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2667
2668 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2669 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2670 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2671 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2672 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2673
2674 // delete indication for the indicated Filter
2675 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2676 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2677 }
mpagenko01e726e2020-10-23 09:45:29 +00002678 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002679 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002680 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002681 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002682 },
2683 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002684 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2686 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2687 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002688 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002689 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002690 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2691 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002692 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002693 return
2694 }
mpagenko01e726e2020-10-23 09:45:29 +00002695 //accept also nil as (error) return value for writing to LastTx
2696 // - this avoids misinterpretation of new received OMCI messages
2697 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002698 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002699
2700 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002701 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002702 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302703 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2704 log.Fields{"device-id": oFsm.deviceID,
2705 "match-vlan": aRuleParams.MatchVid,
2706 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002707 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002708 return
2709 }
2710 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002711 // VOL-3685
2712 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2713 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2714 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2715 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2716 // later when the flow is being re-installed.
2717 // Of course this is applicable to case only where single service (or single tcont) is in use and
2718 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2719 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2720 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002721 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002722 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002724 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2725 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002726 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002727 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002728 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002729 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002730 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2731 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2732 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002733 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002734 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002735 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2736 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002737 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002738 return
2739 }
mpagenko01e726e2020-10-23 09:45:29 +00002740 //accept also nil as (error) return value for writing to LastTx
2741 // - this avoids misinterpretation of new received OMCI messages
2742 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002743 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002744
2745 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002746 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002747 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002749 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002751 return
2752 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002753 } else {
2754 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2755 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002756 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002758 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002759 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2760 { // just for local var's
2761 // this defines stacking scenario: untagged->singletagged
2762 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2763 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2764 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2765 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002766 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002767 "device-id": oFsm.deviceID})
2768 sliceEvtocdRule := make([]uint8, 16)
2769 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2770 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2771 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2772 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2773 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002774
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002775 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2776 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2777 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2778 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2779 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002780
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002781 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2782 0<<cTreatTTROffset| // Do not pop any tags
2783 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2784 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2785 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002786
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002787 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2788 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2789 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2790 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002791
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002792 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002793 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002794 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002795 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002796 },
2797 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002798 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002799 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2800 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2801 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002802 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002803 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002804 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2805 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002806 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002807 return
2808 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002809 //accept also nil as (error) return value for writing to LastTx
2810 // - this avoids misinterpretation of new received OMCI messages
2811 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002812 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002813
2814 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002815 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002816 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002818 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002820 return
2821 }
2822 } // just for local var's
2823 { // just for local var's
2824 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002825 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002826 "device-id": oFsm.deviceID})
2827 sliceEvtocdRule := make([]uint8, 16)
2828 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2829 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2830 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2831 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2832 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2833
2834 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2835 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2836 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2837 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2838 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2839
2840 // delete indication for the indicated Filter
2841 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2842 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2843
2844 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002845 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002846 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002847 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848 },
2849 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002850 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2852 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2853 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002854 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002855 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002856 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2857 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002858 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002859 return
2860 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002861 //accept also nil as (error) return value for writing to LastTx
2862 // - this avoids misinterpretation of new received OMCI messages
2863 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002864 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002865
2866 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002867 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002868 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002869 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002870 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002871 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002872 return
2873 }
mpagenko01e726e2020-10-23 09:45:29 +00002874 }
2875 } //just for local var's
2876 }
2877 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002878 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002879 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002880 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002881}
2882
dbainbri4d3a0dc2020-12-02 00:33:42 +00002883func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002884 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002885 if oFsm.isCanceled {
2886 // FSM already canceled before entering wait
2887 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2888 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002889 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002890 }
mpagenko7d6bb022021-03-11 15:07:55 +00002891 oFsm.isAwaitingResponse = true
2892 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002893 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302894 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002895 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002896 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002897 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002898 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002899 oFsm.mutexIsAwaitingResponse.Lock()
2900 oFsm.isAwaitingResponse = false
2901 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002902 oFsm.mutexPLastTxMeInstance.RLock()
2903 if oFsm.pLastTxMeInstance != nil {
2904 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2905 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2906 }
2907 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002908 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002909 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302910 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002911 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002912 oFsm.mutexIsAwaitingResponse.Lock()
2913 oFsm.isAwaitingResponse = false
2914 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002915 return nil
2916 }
mpagenko7d6bb022021-03-11 15:07:55 +00002917 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002918 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002919 oFsm.mutexIsAwaitingResponse.Lock()
2920 oFsm.isAwaitingResponse = false
2921 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002923 }
2924}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925
mpagenko551a4d42020-12-08 18:09:20 +00002926func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002928 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002929 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002931 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002932 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002933 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2935 }
2936
dbainbri4d3a0dc2020-12-02 00:33:42 +00002937 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002939 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002940 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002941 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002942 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2943 }
2944
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002947 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002948 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002950 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2951 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002952 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002953 if errMacBpCdEID != nil {
2954 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2955 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002957 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002958
Mahir Gunyel6781f962021-05-16 23:30:08 -07002959 }
2960 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2962 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002963 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002964 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002965 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002966 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2967 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2968 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2969 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002970 },
2971 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002972 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002973 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2974 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002975 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002976 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002977 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2978 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002979 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002980 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2981 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002982 //accept also nil as (error) return value for writing to LastTx
2983 // - this avoids misinterpretation of new received OMCI messages
2984 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002985 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002986 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002987 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2990 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002991 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2992 }
2993
2994 // ==> Start creating VTFD for mcast vlan
2995
2996 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2997 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002998 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002999
dbainbri4d3a0dc2020-12-02 00:33:42 +00003000 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003001 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003002 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003003 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
3004
3005 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
3006 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
3007 // new vlan associated with a different TP.
3008 vtfdFilterList[0] = uint16(vlanID)
3009
3010 meParams = me.ParamData{
3011 EntityID: mcastVtfdID,
3012 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003013 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
3014 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
3015 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003016 },
3017 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003018 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003019 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3020 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003021 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003022 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003023 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3024 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003026 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3027 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003028 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003029 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003030 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003031 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003032 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003033 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003034 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003035 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3036 }
3037
3038 return nil
3039}
3040
dbainbri4d3a0dc2020-12-02 00:33:42 +00003041func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003043 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003044 logger.Errorw(ctx, "error generrating me instance id",
3045 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003046 return err
3047 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003048 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3049 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003050 meParams := me.ParamData{
3051 EntityID: instID,
3052 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003053 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003054 //Direct reference to the Operation profile
3055 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003056 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003057 },
3058 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003059 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3061 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3062 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003063 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003064 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003065 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3066 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003067 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003068 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3069 oFsm.deviceID, err)
3070 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003071 //accept also nil as (error) return value for writing to LastTx
3072 // - this avoids misinterpretation of new received OMCI messages
3073 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003074 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003075 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003076 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003077 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003078 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003079 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3080 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3081 }
3082 return nil
3083}
3084
dbainbri4d3a0dc2020-12-02 00:33:42 +00003085func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003087 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003088 logger.Errorw(ctx, "error generating me instance id",
3089 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003090 return err
3091 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003092 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3093 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003094 meParams := me.ParamData{
3095 EntityID: instID,
3096 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003097 me.MulticastOperationsProfile_IgmpVersion: 2,
3098 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003099 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003100 me.MulticastOperationsProfile_ImmediateLeave: 0,
3101 me.MulticastOperationsProfile_Robustness: 2,
3102 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3103 me.MulticastOperationsProfile_QueryInterval: 125,
3104 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3105 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003106 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003107 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003108 },
3109 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003110 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003111 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3112 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3113 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003114 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003115 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003116 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3117 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003118 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003119 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3120 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003121 //accept also nil as (error) return value for writing to LastTx
3122 // - this avoids misinterpretation of new received OMCI messages
3123 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003124 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003125 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003126 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003127 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003128 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003129 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003130 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003131 }
3132 return nil
3133}
3134
dbainbri4d3a0dc2020-12-02 00:33:42 +00003135func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003136 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003137 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003138 logger.Errorw(ctx, "error generating me instance id",
3139 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003140 return err
3141 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003142 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3143 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003144 //TODO check that this is correct
3145 // Table control
3146 //setCtrl = 1
3147 //rowPartId = 0
3148 //test = 0
3149 //rowKey = 0
3150 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003152 dynamicAccessCL := make([]uint8, 24)
3153 copy(dynamicAccessCL, tableCtrl)
3154 //Multicast GemPortId
3155 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3156 // python version waits for installation of flows, see line 723 onward of
3157 // brcm_openomci_onu_handler.py
3158 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3159 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003160 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003161 //TODO start and end are hardcoded, get from TP
3162 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003163 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003164 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003165 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003166 //imputed group bandwidth
3167 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3168
3169 meParams := me.ParamData{
3170 EntityID: instID,
3171 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003172 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003173 },
3174 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003175 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003176 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3177 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3178 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003179 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003180 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003181 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3182 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003183 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003184 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3185 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003186 //accept also nil as (error) return value for writing to LastTx
3187 // - this avoids misinterpretation of new received OMCI messages
3188 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003189 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003190 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003191 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003192 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003193 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003194 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003195 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003196 }
3197 return nil
3198}
Girish Gowdra26a40922021-01-29 17:14:34 -08003199
khenaidoo42dcdfd2021-10-19 17:34:12 -04003200func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003201 tpID uint8, uniID uint8, gemPortID uint16) error {
3202 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3203 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3204 // I created unique TD ID by flow direction.
3205 // TODO! Traffic descriptor ME ID will check
3206 trafficDescriptorID := gemPortID
3207 if aMeter == nil {
3208 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3209 }
3210 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3211 if err != nil {
3212 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3213 return err
3214 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003215 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003216 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003217 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003218 pbs := trafficShapingInfo.Pbs
3219
3220 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3221 meParams := me.ParamData{
3222 EntityID: trafficDescriptorID,
3223 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003224 me.TrafficDescriptor_Cir: cir,
3225 me.TrafficDescriptor_Pir: pir,
3226 me.TrafficDescriptor_Cbs: cbs,
3227 me.TrafficDescriptor_Pbs: pbs,
3228 me.TrafficDescriptor_ColourMode: 1,
3229 me.TrafficDescriptor_IngressColourMarking: 3,
3230 me.TrafficDescriptor_EgressColourMarking: 3,
3231 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003232 },
3233 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003234 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003235 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3236 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003237 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003238 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003239 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3240 return err
3241 }
3242 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003243 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003244 err = oFsm.waitforOmciResponse(ctx)
3245 if err != nil {
3246 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3247 return err
3248 }
3249
Girish Gowdra09e5f212021-09-30 16:28:36 -07003250 // 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
3251 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003252 if err != nil {
3253 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3254 return err
3255 }
3256 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3257
3258 return nil
3259}
3260
Girish Gowdra09e5f212021-09-30 16:28:36 -07003261func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3262 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3263 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003264 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003265 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003266 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003267 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003268 },
3269 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003270 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003271 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3272 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003273 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003274 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003275 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3276 return err
3277 }
3278 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003279 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003280 err = oFsm.waitforOmciResponse(ctx)
3281 if err != nil {
3282 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3283 return err
3284 }
3285 return nil
3286}
3287
Girish Gowdra26a40922021-01-29 17:14:34 -08003288// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003289func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3290 if oFsm == nil {
3291 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3292 return false
3293 }
mpagenkobb47bc22021-04-20 13:29:09 +00003294 oFsm.mutexFlowParams.Lock()
3295 defer oFsm.mutexFlowParams.Unlock()
3296 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3297 //flow removal is still ongoing/pending
3298 oFsm.signalOnFlowDelete = true
3299 oFsm.flowDeleteChannel = aFlowDeleteChannel
3300 return true
3301 }
3302 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003303}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003304
3305func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3306 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3307 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3308 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3309 log.Fields{"device-id": oFsm.deviceID})
3310 } else {
3311 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3312 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3313 "index": oFsm.numVlanFilterEntries,
3314 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3315 "device-id": oFsm.deviceID})
3316 oFsm.numVlanFilterEntries++
3317 }
3318}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003319
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003320// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3321func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003322 if respChan != nil {
3323 // 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
3324 select {
3325 case *respChan <- err:
3326 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3327 default:
3328 }
3329 }
3330}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003331
3332// PrepareForGarbageCollection - remove references to prepare for garbage collection
3333func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3334 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3335 oFsm.pDeviceHandler = nil
3336 oFsm.pOnuDeviceEntry = nil
3337 oFsm.pOmciCC = nil
3338}