blob: 5b0772d392c7011cc25a9049e046a7b600102fbb [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.
187 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000188}
189
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530190// NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
191//
192// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000193func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
194 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
195 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530196 aCookieSlice []uint64, aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, lastFlowToRec bool, aMeter *of.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000197 instFsm := &UniVlanConfigFsm{
198 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000199 pOnuDeviceEntry: apOnuDeviceEntry,
200 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000201 pOmciCC: apDevOmciCC,
202 pOnuUniPort: apUniPort,
203 pUniTechProf: apUniTechProf,
204 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000205 requestEvent: aRequestEvent,
206 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000207 NumUniFlows: 0,
208 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000209 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200210 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000211 }
212
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000213 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
214 if instFsm.PAdaptFsm == nil {
215 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000216 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700217 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000218 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000219 return nil
220 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000221 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
222 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000223 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000224 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
225 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
226 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
227 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
228 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
229 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
230 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
231 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
232 Dst: VlanStConfigDone},
233 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
234 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
235 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
236 Dst: VlanStConfigIncrFlow},
237 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
238 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
239 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000240 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241 {Name: VlanEvTimeoutSimple, Src: []string{
242 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
243 {Name: VlanEvTimeoutMids, Src: []string{
244 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000245 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000246 // exceptional treatment for all states except VlanStResetting
247 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
248 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +0530249 VlanStRemoveFlow, VlanStCleanupDone, VlanStPreparing},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000251 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000252 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000253 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
255 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
256 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000257 },
mpagenkodff5dda2020-08-28 11:52:01 +0000258 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000259 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
260 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
261 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
262 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
263 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
264 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
265 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
266 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
267 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
268 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
269 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000270 },
271 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000272 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000273 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000274 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700275 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000276 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000277 return nil
278 }
279
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530280 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, aMeter, respChan)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000281 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000282 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000283 return instFsm
284}
285
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530286// initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000287func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530288 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000289 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530290 TpID: aTpID,
291 MatchVid: uint32(aMatchVlan),
292 MatchPcp: uint32(aMatchPcp),
293 SetVid: uint32(aSetVlan),
294 SetPcp: uint32(aSetPcp),
295 InnerCvlan: innerCvlan,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000296 }
297 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +0530298 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299
mpagenko01e726e2020-10-23 09:45:29 +0000300 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301 //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 +0000302 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
304 } else {
305 if !oFsm.acceptIncrementalEvtoOption {
306 //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 +0000307 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000308 }
309 }
310
mpagenko01e726e2020-10-23 09:45:29 +0000311 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000312 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000313 loRuleParams.TagsToRemove = 0 //no tag pop action
314 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
315 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000316 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
317 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
318 // might collide with NoMatchVid/CopyPrio(/setVid) setting
319 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000320 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000321 }
322 }
mpagenko01e726e2020-10-23 09:45:29 +0000323
Girish Gowdrae95687a2021-09-08 16:30:58 -0700324 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000325 loFlowParams.CookieSlice = make([]uint64, 0)
326 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300327 if aMeter != nil {
328 loFlowParams.Meter = aMeter
329 }
mpagenko01e726e2020-10-23 09:45:29 +0000330
331 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000332 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000333 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000334 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000335 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
336 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
337 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
338 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000340
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000341 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000342 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
343 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000344 //cmp also usage in EVTOCDE create in omci_cc
345 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000347 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
348
349 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000350 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000351 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000353 return err
354 }
355
356 return nil
357}
358
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530359// CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000360func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000361 if oFsm == nil {
362 logger.Error(ctx, "no valid UniVlanConfigFsm!")
363 return
364 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530365 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +0000366 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000367 oFsm.mutexIsAwaitingResponse.Lock()
368 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000369 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000370 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
371 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
372 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000373 //use channel to indicate that the response waiting shall be aborted
374 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000375 } else {
376 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000377 }
mpagenkocf48e452021-04-23 09:23:00 +0000378
mpagenko7d6bb022021-03-11 15:07:55 +0000379 // 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 +0000380 PAdaptFsm := oFsm.PAdaptFsm
381 if PAdaptFsm != nil {
382 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000383 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000384 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000385 }
mpagenko7d6bb022021-03-11 15:07:55 +0000386 }
387}
388
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530389// GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000390func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
391 if oFsm == nil {
392 logger.Error(ctx, "no valid UniVlanConfigFsm!")
393 return 0
394 }
mpagenko551a4d42020-12-08 18:09:20 +0000395 //mutex protection is required for possible concurrent access to FSM members
396 oFsm.mutexFlowParams.RLock()
397 defer oFsm.mutexFlowParams.RUnlock()
398 return oFsm.TpIDWaitingFor
399}
400
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530401// SetUniFlowParams verifies on existence of flow parameters to be configured,
mpagenko01e726e2020-10-23 09:45:29 +0000402// optionally udates the cookie list or appends a new flow if there is space
403// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000404// ignore complexity by now
405// nolint: gocyclo
406func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530407 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, aInnerCvlan uint16, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000408 if oFsm == nil {
409 logger.Error(ctx, "no valid UniVlanConfigFsm!")
410 return fmt.Errorf("no-valid-UniVlanConfigFsm")
411 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000412 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530413 TpID: aTpID,
414 MatchVid: uint32(aMatchVlan),
415 MatchPcp: uint32(aMatchPcp),
416 SetVid: uint32(aSetVlan),
417 SetPcp: uint32(aSetPcp),
418 InnerCvlan: aInnerCvlan,
mpagenko01e726e2020-10-23 09:45:29 +0000419 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700420 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000421 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530422 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
mpagenko01e726e2020-10-23 09:45:29 +0000423 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
424 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
425 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
426 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
427 } else {
428 if !oFsm.acceptIncrementalEvtoOption {
429 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
430 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
431 }
432 }
433
434 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
435 // no prio/vid filtering requested
436 loRuleParams.TagsToRemove = 0 //no tag pop action
437 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
438 if loRuleParams.SetPcp == cCopyPrioFromInner {
439 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
440 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
441 // might collide with NoMatchVid/CopyPrio(/setVid) setting
442 // this was some precondition setting taken over from py adapter ..
443 loRuleParams.SetPcp = 0
444 }
445 }
446
mpagenkof1d21d12021-06-11 13:14:45 +0000447 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
448 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
449 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
450 oFsm.mutexFlowParams.RLock()
451 if len(oFsm.uniRemoveFlowsSlice) > 0 {
452 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
453 if removeUniFlowParams.vlanRuleParams == loRuleParams {
454 // the flow to add is the same as the one already in progress of deleting
455 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000456 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
457 if flow >= len(oFsm.uniRemoveFlowsSlice) {
458 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
459 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
460 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700461 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000462 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700463 return err
464
mpagenkof582d6a2021-06-18 15:58:10 +0000465 }
mpagenkof1d21d12021-06-11 13:14:45 +0000466 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
467 oFsm.mutexFlowParams.RUnlock()
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +0530468 if err = oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +0000469 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
470 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700471 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000472 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700473 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000474 }
475 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000476 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000477 }
478 }
479 }
480 oFsm.mutexFlowParams.RUnlock()
481
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000482 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000483 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000484 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200485 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000486 //mutex protection is required for possible concurrent access to FSM members
487 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000488 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
489 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
490 // countable run time optimization (perhaps with including the hash in kvStore storage?)
491 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000492 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000493 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300494 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
495 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
496 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000497 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000498 var cookieMatch bool
499 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
500 cookieMatch = false
501 for _, cookie := range storedUniFlowParams.CookieSlice {
502 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000503 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000504 "device-id": oFsm.deviceID, "cookie": cookie})
505 cookieMatch = true
506 break //found new cookie - no further search for this requested cookie
507 }
508 }
509 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000510 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
511 if delayedCookie != 0 {
512 //a delay for adding the cookie to this rule is requested
513 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
514 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000515 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
516 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
517 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700518 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000519 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700520 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000521 }
mpagenkobc4170a2021-08-17 16:42:10 +0000522 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000523 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000524 } else {
525 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
526 "device-id": oFsm.deviceID, "cookie": newCookie})
527 //as range works with copies of the slice we have to write to the original slice!!
528 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
529 newCookie)
530 flowCookieModify = true
531 }
mpagenko01e726e2020-10-23 09:45:29 +0000532 }
533 } //for all new cookies
534 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000535 }
536 }
mpagenkof1fc3862021-02-16 10:09:52 +0000537 oFsm.mutexFlowParams.Unlock()
538
539 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000540 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
541 if !deleteSuccess {
542 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
543 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700544 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000545 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700546 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000547 }
mpagenkof1fc3862021-02-16 10:09:52 +0000548 requestAppendRule = true //default assumption here is that rule is to be appended
549 flowCookieModify = true //and that the the flow data base is to be updated
550 if delayedCookie != 0 { //it was suspended
551 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
552 }
553 }
554 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
555 if requestAppendRule {
556 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000557 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700558 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000559 loFlowParams.CookieSlice = make([]uint64, 0)
560 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300561 if aMeter != nil {
562 loFlowParams.Meter = aMeter
563 }
mpagenko01e726e2020-10-23 09:45:29 +0000564 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000565 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000566 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000567 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
568 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
570 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000573 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
574 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 oFsm.NumUniFlows++
576 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000577
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000579 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000581 //attention: take care to release the mutexFlowParams when calling the FSM directly -
582 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000583 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000584 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
585 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000586 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000587 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700588 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000589 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700590 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000591 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000592 }
593 return nil
594 }
mpagenko01e726e2020-10-23 09:45:29 +0000595 // note: theoretical it would be possible to clear the same rule from the remove slice
596 // (for entries that have not yet been started with removal)
597 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
598 // 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 +0000599
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000600 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000601 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000603 // this is a restart with a complete new flow, we can re-use the initial flow config control
604 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000605 //attention: take care to release the mutexFlowParams when calling the FSM directly -
606 // synchronous FSM 'event/state' functions may rely on this mutex
607 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000608 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000609 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
610 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
611 }
mpagenko551a4d42020-12-08 18:09:20 +0000612 } else {
613 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000614 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000616 //check introduced after having observed some panic here
617 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000619 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
620 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700621 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000622 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700623 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000624 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625
626 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000627 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700628 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000629 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700630 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000631 //attention: take care to release the mutexFlowParams when calling the FSM directly -
632 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000633 // but it must be released already before calling getTechProfileDone() as it may already be locked
634 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000635 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000636 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000637 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000639 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
640
mpagenkobb47bc22021-04-20 13:29:09 +0000641 var fsmErr error
642 if loTechProfDone {
643 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000645 } else {
646 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000647 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000648 }
649 if fsmErr != nil {
650 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
651 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000652 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700653 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000654 }
mpagenko551a4d42020-12-08 18:09:20 +0000655 }
mpagenkobb47bc22021-04-20 13:29:09 +0000656 } else {
657 // if not in the appropriate state a new entry will be automatically considered later
658 // when the configDone state is reached
659 oFsm.mutexFlowParams.Unlock()
660 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000661 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000663 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000664 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000666 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700667 return err
mpagenko01e726e2020-10-23 09:45:29 +0000668 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000669 } else {
670 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000671 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000673 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700674
mpagenko15ff4a52021-03-02 10:09:20 +0000675 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000676 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000677 //all requested rules really have been configured
678 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000679 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 if oFsm.pDeviceHandler != nil {
681 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000682 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000683 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
685 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000686 }
687 } else {
688 // avoid device reason update as the rule config connected to this flow may still be in progress
689 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000691 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000692 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000693 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000694 }
695 }
mpagenko01e726e2020-10-23 09:45:29 +0000696
mpagenkof1fc3862021-02-16 10:09:52 +0000697 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000698 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000699 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000700 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000701 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000702 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000703 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000704 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000705 }
mpagenko15ff4a52021-03-02 10:09:20 +0000706 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000707 }
708 return nil
709}
710
mpagenkof1d21d12021-06-11 13:14:45 +0000711func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
712 oFsm.mutexFlowParams.Lock()
713 deleteChannel := apRemoveFlowParams.removeChannel
714 apRemoveFlowParams.isSuspendedOnAdd = true
715 oFsm.mutexFlowParams.Unlock()
716
717 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
718 select {
719 case success := <-deleteChannel:
720 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
721 if success {
722 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
723 "device-id": oFsm.deviceID})
724 return nil
725 }
726 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
727 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
728 oFsm.mutexFlowParams.Lock()
729 if apRemoveFlowParams != nil {
730 apRemoveFlowParams.isSuspendedOnAdd = false
731 }
732 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000733 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000734 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000735 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000736 }
mpagenkof1d21d12021-06-11 13:14:45 +0000737}
738
mpagenkof1fc3862021-02-16 10:09:52 +0000739// VOL-3828 flow config sequence workaround ########### start ##########
740func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
741 //assumes mutexFlowParams.Lock() protection from caller!
742 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
743 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000744 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000745 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
746 newCookie := aCookieSlice[0]
747 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
748 for _, cookie := range storedUniFlowParams.CookieSlice {
749 if cookie == newCookie {
750 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
751 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
752 oFsm.delayNewRuleCookie = newCookie
753 return newCookie //found new cookie in some existing rule
754 }
755 } // for all stored cookies of the actual inspected rule
756 } //for all rules
757 }
758 return 0 //no delay requested
759}
mpagenkobc4170a2021-08-17 16:42:10 +0000760func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000761 oFsm.mutexFlowParams.RLock()
762 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
763 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
764 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000765 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000766 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000767 case cookieDeleted = <-oFsm.chCookieDeleted:
768 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
769 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000770 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000771 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
772 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
773 }
774 oFsm.mutexFlowParams.Lock()
775 oFsm.delayNewRuleCookie = 0
776 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000777 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000778}
mpagenkobc4170a2021-08-17 16:42:10 +0000779func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000780 oFsm.mutexFlowParams.Lock()
781 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
782 oFsm.mutexFlowParams.Unlock()
783
mpagenkobc4170a2021-08-17 16:42:10 +0000784 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000785 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000786 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000787 }
mpagenkobc4170a2021-08-17 16:42:10 +0000788 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000789}
790
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530791// returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000792func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000793 flowEntryMatch := false
794 oFsm.mutexFlowParams.Lock()
795 defer oFsm.mutexFlowParams.Unlock()
796 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
797 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
798 flowEntryMatch = true
799 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
800 "device-id": oFsm.deviceID})
801 cookieMatch := false
802 for _, cookie := range storedUniFlowParams.CookieSlice {
803 if cookie == aCookie {
804 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
805 "device-id": oFsm.deviceID, "cookie": cookie})
806 cookieMatch = true
807 break //found new cookie - no further search for this requested cookie
808 }
809 }
810 if !cookieMatch {
811 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
812 "device-id": oFsm.deviceID, "cookie": aCookie})
813 //as range works with copies of the slice we have to write to the original slice!!
814 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
815 aCookie)
816 return true, false //flowModified, NoRuleAppend
817 }
818 break // found rule - no further rule search
819 }
820 }
821 if !flowEntryMatch { //it is a new rule
822 return true, true //flowModified, RuleAppend
823 }
824 return false, false //flowNotModified, NoRuleAppend
825}
826
827// VOL-3828 flow config sequence workaround ########### end ##########
828
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530829// RemoveUniFlowParams verifies on existence of flow cookie,
mpagenko01e726e2020-10-23 09:45:29 +0000830// if found removes cookie from flow cookie list and if this is empty
831// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700832func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000833 if oFsm == nil {
834 logger.Error(ctx, "no valid UniVlanConfigFsm!")
835 return fmt.Errorf("no-valid-UniVlanConfigFsm")
836 }
mpagenkof1fc3862021-02-16 10:09:52 +0000837 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000838 flowCookieMatch := false
839 //mutex protection is required for possible concurrent access to FSM members
840 oFsm.mutexFlowParams.Lock()
841 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000842remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000843 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
844 for i, cookie := range storedUniFlowParams.CookieSlice {
845 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000846 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000847 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000848 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000849 //remove the cookie from the cookie slice and verify it is getting empty
850 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000851 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700852 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000853 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000854 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000855 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000856 //cut off the requested cookie by slicing out this element
857 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
858 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
859 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000860 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
861 // state transition notification is checked in deviceHandler
862 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000863 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
864 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000865 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000866 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000867 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000868 if deletedCookie == oFsm.delayNewRuleCookie {
869 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
870 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
871 //simply use the first one
872 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
873 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
874 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
875 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700876 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000877 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000878 //permanently store the modified flow config for reconcile case and immediately write to KvStore
879 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000880 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000881 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
882 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
883 return err
884 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000885 }
mpagenko01e726e2020-10-23 09:45:29 +0000886 }
mpagenkof1fc3862021-02-16 10:09:52 +0000887 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000888 }
889 }
mpagenko01e726e2020-10-23 09:45:29 +0000890 } //search all flows
891 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000892 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000893 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
894 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000895 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
896 // state transition notification is checked in deviceHandler
897 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000898 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000899 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000900 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700901 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000902 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000903 return nil
904 } //unknown cookie
905
906 return nil
907}
908
mpagenkof582d6a2021-06-18 15:58:10 +0000909// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000910// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000911func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700912 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000913 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000914 var cancelPendingConfig bool = false
915 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
916 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
917 "device-id": oFsm.deviceID})
918 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
919 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
920 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
921 // 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 +0000922 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000923 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
924 log.Fields{"device-id": oFsm.deviceID})
925 cancelPendingConfig = true
926 } else {
927 //create a new element for the removeVlanFlow slice
928 loRemoveParams = uniRemoveVlanFlowParams{
929 vlanRuleParams: aUniFlowParams.VlanRuleParams,
930 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700931 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000932 }
933 loRemoveParams.removeChannel = make(chan bool)
934 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
935 }
936
937 usedTpID := aUniFlowParams.VlanRuleParams.TpID
938 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
939 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
940 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
941 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000942 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
943 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000944 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
945 "device-id": oFsm.deviceID})
946 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000947 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000948 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000949 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000950 }
951 } else {
952 if !cancelPendingConfig {
953 oFsm.updateTechProfileToDelete(ctx, usedTpID)
954 }
955 }
956 //trigger the FSM to remove the relevant rule
957 if cancelPendingConfig {
958 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000959 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000960 //call from 'non-configured' state of the rules
961 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
962 //something quite inconsistent detected, perhaps just try to recover with FSM reset
963 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000964 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000965 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
966 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
967 }
968 return false //data base update could not be done, return like cookie not found
969 }
970
971 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
972 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
973 // synchronous FSM 'event/state' functions may rely on this mutex
974 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000976 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
977 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
978 }
979 oFsm.mutexFlowParams.Lock()
980 return true
981 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000983 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000985 "tp-id": loRemoveParams.vlanRuleParams.TpID,
986 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
987 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
988 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
989 // synchronous FSM 'event/state' functions may rely on this mutex
990 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000991 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000992 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
993 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
994 }
995 oFsm.mutexFlowParams.Lock()
996 } // if not in the appropriate state a new entry will be automatically considered later
997 // when the configDone state is reached
998 return true
999}
1000
praneeth kumar nalmas3947c582023-12-13 15:38:50 +05301001// removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1002//
1003// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1004// from the start of the deletion request to avoid to much interference
1005// so when called, there can only be one cookie active for this flow
1006//
mpagenkof1d21d12021-06-11 13:14:45 +00001007// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001008func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001009 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1010 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001011 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001012removeFromSlice_loop:
1013 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001014 // if UniFlowParams exists, cookieSlice should always have at least one element
1015 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1016 if cookieSliceLen == 1 {
1017 if storedUniFlowParams.CookieSlice[0] == aCookie {
1018 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001019 }
mpagenkof582d6a2021-06-18 15:58:10 +00001020 } else if cookieSliceLen == 0 {
1021 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1022 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1023 return errors.New(errStr)
1024 } else {
1025 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1026 logger.Errorw(ctx, errStr, log.Fields{
1027 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1028 for _, cookie := range storedUniFlowParams.CookieSlice {
1029 if cookie == aCookie {
1030 cookieFound = true
1031 break
1032 }
1033 }
1034 }
1035 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001036 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1037 "device-id": oFsm.deviceID, "cookie": aCookie})
1038 //remove the actual element from the addVlanFlow slice
1039 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1040 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 oFsm.NumUniFlows = 0 //no more flows
1042 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001043 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1044 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1045 //request that this profile gets deleted before a new flow add is allowed
1046 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1047 "device-id": oFsm.deviceID})
1048 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001049 oFsm.NumUniFlows--
1050 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1051 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001052 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001053 if !aWasConfigured {
1054 // We did not actually process this flow but was removed before that.
1055 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001056 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001057 }
1058
mpagenkof1d21d12021-06-11 13:14:45 +00001059 //cut off the requested flow by slicing out this element
1060 oFsm.uniVlanFlowParamsSlice = append(
1061 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1062 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1063 "device-id": oFsm.deviceID})
1064 }
1065 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1066 }
1067 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001068 if !cookieFound {
1069 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1070 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1071 return errors.New(errStr)
1072 }
mpagenkodee02a62021-07-21 10:56:10 +00001073 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1074 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001075 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001076 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1077 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1078 return err
1079 }
mpagenkof582d6a2021-06-18 15:58:10 +00001080 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001081}
1082
1083// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001084func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1085 //here we have to check, if there are still other flows referencing to the actual ProfileId
1086 // before we can request that this profile gets deleted before a new flow add is allowed
1087 tpIDInOtherFlows := false
1088 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1089 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1090 tpIDInOtherFlows = true
1091 break // search loop can be left
1092 }
1093 }
1094 if tpIDInOtherFlows {
1095 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1096 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1097 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001098 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 +00001099 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001100 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1101 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001102 if oFsm.pUniTechProf != nil {
1103 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001104 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001105 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001106 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001107 }
1108}
1109
mpagenkof1d21d12021-06-11 13:14:45 +00001110func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1111 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001112
1113 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001114 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001115 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001116 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001117 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001119 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001121 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001122 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001123 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001125 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 go func(a_pAFsm *cmn.AdapterFsm) {
1127 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001128 }(pConfigVlanStateAFsm)
1129 return
1130 }
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(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001134 }(pConfigVlanStateAFsm)
1135 return
1136 }
1137 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1138 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1139 //should never happen, else: recovery would be needed from outside the FSM
1140}
1141
1142func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1143 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001144 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001145 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001146 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001147 //possibly the entry is not valid anymore based on intermediate delete requests
1148 //just a basic protection ...
1149 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1150 oFsm.mutexFlowParams.Unlock()
1151 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1152 "device-id": oFsm.deviceID})
1153 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001154 go func(a_pAFsm *cmn.AdapterFsm) {
1155 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001156 }(pConfigVlanStateAFsm)
1157 return
1158 }
mpagenko9a304ea2020-12-16 15:54:01 +00001159 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1160 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001161 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1162 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001163 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001164 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001165 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1166 // synchronous FSM 'event/state' functions may rely on this mutex
1167 // but it must be released already before calling getTechProfileDone() as it may already be locked
1168 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001169 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001170 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001171 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001173 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001174
mpagenko9a304ea2020-12-16 15:54:01 +00001175 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001176 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1177 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001178 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001179 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001180 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001181 } else {
1182 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001183 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001184 }
1185 }
mpagenko551a4d42020-12-08 18:09:20 +00001186 }(pConfigVlanStateAFsm, loTechProfDone)
1187 } else {
1188 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1189 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1190 //should never happen, else: recovery would be needed from outside the FSM
1191 return
mpagenkodff5dda2020-08-28 11:52:01 +00001192 }
1193}
1194
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001196 //mutex protection is required for possible concurrent access to FSM members
1197 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001198 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001199 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001200 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001201 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001203 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001204 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001206 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001207 go func(a_pAFsm *cmn.AdapterFsm) {
1208 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001209 }(pConfigVlanStateAFsm)
1210 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001211 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1212 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001213 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001214 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001215 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001216 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001217 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001218 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001219 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001220 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001221 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001222 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1223 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001224 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001225 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001226 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001227 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1228 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1229 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001230 },
1231 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001232 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001233 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001234 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001235 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1236 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001237 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001238 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001239 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1240 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001242 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001243 go func(a_pAFsm *cmn.AdapterFsm) {
1244 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001245 }(pConfigVlanStateAFsm)
1246 }
1247 return
1248 }
mpagenkodff5dda2020-08-28 11:52:01 +00001249 //accept also nil as (error) return value for writing to LastTx
1250 // - this avoids misinterpretation of new received OMCI messages
1251 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1252 // send shall return (dual format) error code that can be used here for immediate error treatment
1253 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001254 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001255 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001256 }
1257}
1258
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301259//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001260func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1261 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001262 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001263 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001264 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001265 //using the first element in the slice because it's the first flow per definition here
1266 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001267 //This is correct passing scenario
1268 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001269 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001270 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1271 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001273 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1274 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001279 vlanID)
1280 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001282 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001284 }
1285 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001286 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001287 if oFsm.actualUniFlowParam.Meter != nil {
1288 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001290 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1291 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001293 if errCreateTrafficDescriptor != nil {
1294 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1295 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001296 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001297 }
1298 }
1299 }
1300
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001301 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001302 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001303 }
1304 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001305}
1306
dbainbri4d3a0dc2020-12-02 00:33:42 +00001307func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001308
mpagenkof1d21d12021-06-11 13:14:45 +00001309 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001310
mpagenkof1fc3862021-02-16 10:09:52 +00001311 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001312 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001313 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001314 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001315 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001316 }
1317
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001319 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001320 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001321 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1322 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1323 //should never happen, else: recovery would be needed from outside the FSM
1324 return
1325 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001326 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001327 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1328 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001329 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001330 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001331 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1332 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001333 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001334 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001335 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001336 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001337 }(pConfigVlanStateBaseFsm)
1338 return
1339 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001340 if oFsm.lastFlowToReconcile {
1341 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1342 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1343 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1344 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1345 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1346 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1348 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001349 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001351 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001352 return
1353 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1355 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001356 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001357 // this is a restart with a complete new flow, we can re-use the initial flow config control
1358 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001359 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001360 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001362 }(pConfigVlanStateBaseFsm)
1363 return
1364 }
1365
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001366 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001367 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001369 //check introduced after having observed some panic in this processing
1370 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001372 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1373 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 go func(a_pAFsm *cmn.AdapterFsm) {
1375 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001376 }(pConfigVlanStateAFsm)
1377 return
1378 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001379 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001380 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001381 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001382 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001383 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001384 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1385 // synchronous FSM 'event/state' functions may rely on this mutex
1386 // but it must be released already before calling getTechProfileDone() as it may already be locked
1387 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1388 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001389 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001390 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001392 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1393
mpagenko9a304ea2020-12-16 15:54:01 +00001394 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001395 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1396 if aTechProfDone {
1397 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001398 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001399 } else {
1400 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001401 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001402 }
1403 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001404 return
1405 }
mpagenkof1d21d12021-06-11 13:14:45 +00001406 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001408 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001409 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1410 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001411 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001412 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001413 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001414 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001415 }
1416}
1417
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001419
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001421 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001423 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001424 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1425 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001426 return
1427 }
mpagenko15ff4a52021-03-02 10:09:20 +00001428 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001430 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001431 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001432 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001433
Girish Gowdrae95687a2021-09-08 16:30:58 -07001434 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001435 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001437 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001438 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001439 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1440 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1441 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1442 // 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 +00001443 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001444 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1445 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001446 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001447 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001448 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001449 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001450 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001451 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001452 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001453 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001454
mpagenko01e726e2020-10-23 09:45:29 +00001455 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001456 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1457 oFsm.numVlanFilterEntries = 1
1458 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001459 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001460 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001461 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1462 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1463 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001464 },
1465 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001466 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1468 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001469 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001470 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001471 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001472 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1473 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001474 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001475 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001476 go func(a_pAFsm *cmn.AdapterFsm) {
1477 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001478 }(pConfigVlanStateAFsm)
1479 }
1480 return
1481 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001482 //accept also nil as (error) return value for writing to LastTx
1483 // - this avoids misinterpretation of new received OMCI messages
1484 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1485 // send shall return (dual format) error code that can be used here for immediate error treatment
1486 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001487 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001488 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001489 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001490 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1491 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001492 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001493
dbainbri4d3a0dc2020-12-02 00:33:42 +00001494 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001495 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001496 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001497 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001498 // setVid is assumed to be masked already by the caller to 12 bit
1499 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001500 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001501 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001502
1503 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1504 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1505 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001506 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001507
1508 oFsm.numVlanFilterEntries++
1509 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001510 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001511 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001512 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1513 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1514 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001515 },
1516 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001517 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1519 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001520 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001521 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001522 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001523 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1524 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001525 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001526 return
1527 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001528 //accept also nil as (error) return value for writing to LastTx
1529 // - this avoids misinterpretation of new received OMCI messages
1530 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1531 // send shall return (dual format) error code that can be used here for immediate error treatment
1532 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001533 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001534 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001535 }
1536 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001538 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001539 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001541 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001543 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001544 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001546 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001547 return
1548 }
1549 }
mpagenkof1d21d12021-06-11 13:14:45 +00001550
mpagenkof1fc3862021-02-16 10:09:52 +00001551 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001552 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001553 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001554 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001555 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1556 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001557 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001558 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001559 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001560 //This is correct passing scenario
1561 if errEvto == nil {
1562 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001563 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001564 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001565 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001567 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001568 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001569 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001571 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001573 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001575 }
1576 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001577 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001578 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001580 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1581 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001583 if errCreateTrafficDescriptor != nil {
1584 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1585 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001586 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001587 }
1588 }
1589 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001591 }
1592 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001593}
1594
dbainbri4d3a0dc2020-12-02 00:33:42 +00001595func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001596 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001598 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1599 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001600
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001601 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1602 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001603 loVlanEntryClear := uint8(0)
1604 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1605 //shallow copy is sufficient as no reference variables are used within struct
1606 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001607 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001609 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1610 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1611 "device-id": oFsm.deviceID})
1612
1613 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1614 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001616 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1617 } else {
1618 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1619 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001621 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1622 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001624 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001625 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001626 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001627 loVlanEntryClear = 1 //full VlanFilter clear request
1628 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001629 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001630 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1631 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001632 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001633 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001634 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1635 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001636 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001637 return
1638 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001639 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001640 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001641 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001643 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001644 }
mpagenko01e726e2020-10-23 09:45:29 +00001645 } else {
1646 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1647 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001649 log.Fields{"current vlan list": oFsm.vlanFilterList,
1650 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1651 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1652 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1653 loVlanEntryRmPos = i
1654 break //abort search
1655 }
1656 }
1657 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001658 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001659 //valid entry was found - to be eclipsed
1660 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1661 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1662 if i < loVlanEntryRmPos {
1663 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1664 } else if i < (cVtfdTableSize - 1) {
1665 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1666 } else {
1667 vtfdFilterList[i] = 0 //set last byte if needed
1668 }
1669 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001670 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001671 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001672 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001674
mpagenkofc4f56e2020-11-04 17:17:49 +00001675 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001676 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001677 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001678 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1679 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001680 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001681 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001682 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1683 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001685 return
1686 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001687 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001688 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001689 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001691 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001692 }
mpagenko01e726e2020-10-23 09:45:29 +00001693 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001695 log.Fields{"device-id": oFsm.deviceID})
1696 }
1697 }
1698 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1700 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001701 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001702 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001704 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001705 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001706 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001707 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001708 }(pConfigVlanStateBaseFsm)
1709 return
1710 }
mpagenko01e726e2020-10-23 09:45:29 +00001711 }
1712
mpagenko15ff4a52021-03-02 10:09:20 +00001713 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001714 if loVlanEntryClear == 1 {
1715 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1716 oFsm.numVlanFilterEntries = 0
1717 } else if loVlanEntryClear == 2 {
1718 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1719 // this loop now includes the 0 element on previous last valid entry
1720 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1721 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1722 }
1723 oFsm.numVlanFilterEntries--
1724 }
mpagenko15ff4a52021-03-02 10:09:20 +00001725 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001726 }
1727 }
1728
mpagenkofc4f56e2020-11-04 17:17:49 +00001729 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001731 } else {
1732 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001734 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001735 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001736 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001737 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001738 }(pConfigVlanStateBaseFsm)
1739 }
mpagenkodff5dda2020-08-28 11:52:01 +00001740}
1741
dbainbri4d3a0dc2020-12-02 00:33:42 +00001742func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001743 var tpID uint8
1744 // Extract the tpID
1745 if len(e.Args) > 0 {
1746 tpID = e.Args[0].(uint8)
1747 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1748 } else {
1749 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1750 }
mpagenko01e726e2020-10-23 09:45:29 +00001751 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001752 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001753
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001754 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001755 if pConfigVlanStateAFsm == nil {
1756 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1757 log.Fields{"device-id": oFsm.deviceID})
1758 //would have to be fixed from outside somehow
1759 return
1760 }
1761
mpagenkof1d21d12021-06-11 13:14:45 +00001762 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1763 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001764 //call from 'configured' state of the rule
1765 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1766 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1767 oFsm.mutexFlowParams.Unlock()
1768 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001769 go func(a_pAFsm *cmn.AdapterFsm) {
1770 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001771 }(pConfigVlanStateAFsm)
1772 return
1773 }
mpagenkof1d21d12021-06-11 13:14:45 +00001774 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1775 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1776 oFsm.mutexFlowParams.Unlock()
1777 removeChannel <- true
1778 oFsm.mutexFlowParams.Lock()
1779 }
1780
mpagenkof1fc3862021-02-16 10:09:52 +00001781 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1782 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1783 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1784
Girish Gowdrae95687a2021-09-08 16:30:58 -07001785 // Store the reference to the flow response channel before this entry in the slice is deleted
1786 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1787
mpagenko01e726e2020-10-23 09:45:29 +00001788 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1789 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001791 "device-id": oFsm.deviceID})
1792 } else {
1793 //cut off the actual flow by slicing out the first element
1794 oFsm.uniRemoveFlowsSlice = append(
1795 oFsm.uniRemoveFlowsSlice[:0],
1796 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001798 "device-id": oFsm.deviceID})
1799 }
1800 oFsm.mutexFlowParams.Unlock()
1801
mpagenkof1fc3862021-02-16 10:09:52 +00001802 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001803 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001804 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001805 go func(a_pAFsm *cmn.AdapterFsm) {
1806 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001807 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001808
mpagenkobb47bc22021-04-20 13:29:09 +00001809 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001810 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001811 if deletedCookie == oFsm.delayNewRuleCookie {
1812 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1813 select {
1814 case <-oFsm.chCookieDeleted:
1815 logger.Debug(ctx, "flushed CookieDeleted")
1816 default:
1817 }
1818 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1819 }
mpagenkobb47bc22021-04-20 13:29:09 +00001820 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1821 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1822 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 -08001823 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001824 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1825 oFsm.flowDeleteChannel <- true
1826 oFsm.signalOnFlowDelete = false
1827 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001828 }
mpagenkobb47bc22021-04-20 13:29:09 +00001829 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001830
1831 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001832 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001833}
1834
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301835//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1837 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001838
mpagenko0f543222021-11-03 16:24:14 +00001839 oFsm.mutexPLastTxMeInstance.Lock()
1840 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1841 oFsm.mutexPLastTxMeInstance.Unlock()
1842
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001843 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001844 if pConfigVlanStateAFsm != nil {
1845 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001846 fsmAbortMsg := cmn.Message{
1847 Type: cmn.TestMsg,
1848 Data: cmn.TestMessage{
1849 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001850 },
1851 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001853
mpagenko0f543222021-11-03 16:24:14 +00001854 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1855 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1856
1857 oFsm.mutexFlowParams.RLock()
1858 if oFsm.delayNewRuleCookie != 0 {
1859 // looks like the waiting AddFlow is stuck
1860 oFsm.mutexFlowParams.RUnlock()
1861 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1862 select {
1863 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1864 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001865 }
mpagenko0f543222021-11-03 16:24:14 +00001866 oFsm.mutexFlowParams.RLock()
1867 }
1868 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1869 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1870 if removeUniFlowParams.isSuspendedOnAdd {
1871 removeChannel := removeUniFlowParams.removeChannel
1872 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1873 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1874 oFsm.mutexFlowParams.RUnlock()
1875 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1876 select {
1877 case removeChannel <- false:
1878 default:
1879 }
1880 oFsm.mutexFlowParams.RLock()
1881 }
1882 // Send response on response channel if the caller is waiting on it.
1883 var err error = nil
1884 if !oFsm.isCanceled {
1885 //only if the FSM is not canceled on external request use some error indication for the respChan
1886 // so only at real internal FSM abortion some error code is sent back
1887 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1888 err = fmt.Errorf("internal-error")
1889 }
1890 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1891 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1892 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1893 }
1894 }
1895
1896 if oFsm.pDeviceHandler != nil {
1897 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1898 if !oFsm.isCanceled {
1899 //if the FSM is not canceled on external request use "internal-error" for the respChan
1900 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1901 // Send response on response channel if the caller is waiting on it with according error indication.
1902 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1903 }
1904 //permanently remove possibly stored persistent data
1905 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1906 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1907 } else {
1908 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1909 // no need to remove specific data in this case here
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +05301910 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1911 // Send response on response channel if the caller is waiting on it with according error indication.
1912 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("config-cancelled"))
1913 }
mpagenko0f543222021-11-03 16:24:14 +00001914 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1915 }
1916 }
1917 oFsm.mutexFlowParams.RUnlock()
1918
1919 //try to let the FSM proceed to 'disabled'
1920 // Can't call FSM Event directly, decoupling it
1921 go func(a_pAFsm *cmn.AdapterFsm) {
1922 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1923 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1924 }
1925 }(pConfigVlanStateAFsm)
1926 return
1927 }
1928 oFsm.mutexFlowParams.RUnlock()
1929 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1930 log.Fields{"device-id": oFsm.deviceID})
1931 return
mpagenkodff5dda2020-08-28 11:52:01 +00001932 }
mpagenko0f543222021-11-03 16:24:14 +00001933 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1934 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001935}
1936
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05301937//nolint:unparam
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1939 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001940
mpagenkodff5dda2020-08-28 11:52:01 +00001941 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001942 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001943 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001944 return
mpagenkodff5dda2020-08-28 11:52:01 +00001945 }
mpagenko0f543222021-11-03 16:24:14 +00001946 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1947 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001948}
1949
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1951 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001952loop:
1953 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001954 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001956 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001957 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301958 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301960 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301962 break loop
1963 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301965
1966 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001967 case cmn.TestMsg:
1968 msg, _ := message.Data.(cmn.TestMessage)
1969 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001971 break loop
1972 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974 case cmn.OMCI:
1975 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301977 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301979 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001980 }
1981 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001983}
1984
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001985func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001987 "msgType": msg.OmciMsg.MessageType})
1988
1989 switch msg.OmciMsg.MessageType {
1990 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001991 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00001993 logger.Warnw(ctx, "CreateResponse handling aborted",
1994 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001995 return
1996 }
mpagenkodff5dda2020-08-28 11:52:01 +00001997 } //CreateResponseType
1998 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001999 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00002000 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
2001 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002003 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002004 return
2005 }
2006 msgObj, msgOk := msgLayer.(*omci.SetResponse)
2007 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002009 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002010 return
2011 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002013 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002015 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002016 // possibly force FSM into abort or ignore some errors for some messages?
2017 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2018 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002019 return
2020 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002021 oFsm.mutexPLastTxMeInstance.RLock()
2022 if oFsm.pLastTxMeInstance != nil {
2023 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2024 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2025 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002026 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002027 { // let the MultiEntity config proceed by stopping the wait function
2028 oFsm.mutexPLastTxMeInstance.RUnlock()
2029 oFsm.omciMIdsResponseReceived <- true
2030 return
2031 }
2032 default:
2033 {
2034 logger.Warnw(ctx, "Unsupported ME name received!",
2035 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2036 }
mpagenkodff5dda2020-08-28 11:52:01 +00002037 }
2038 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002039 } else {
2040 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002041 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002042 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002043 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002044 case omci.DeleteResponseType:
2045 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002047 logger.Warnw(ctx, "DeleteResponse handling aborted",
2048 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002049 return
2050 }
2051 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002052 default:
2053 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002055 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002056 return
2057 }
2058 }
2059}
2060
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002062 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2063 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002065 log.Fields{"device-id": oFsm.deviceID})
2066 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2067 oFsm.deviceID)
2068 }
2069 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2070 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002072 log.Fields{"device-id": oFsm.deviceID})
2073 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2074 oFsm.deviceID)
2075 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002076 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002077 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002078 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002079 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002080 // possibly force FSM into abort or ignore some errors for some messages?
2081 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2082 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002083 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2084 oFsm.deviceID)
2085 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002086 oFsm.mutexPLastTxMeInstance.RLock()
2087 if oFsm.pLastTxMeInstance != nil {
2088 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2089 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2090 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2091 switch oFsm.pLastTxMeInstance.GetName() {
2092 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2093 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002094 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002095 {
2096 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002097 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002098 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002099 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002100 } else { // let the MultiEntity config proceed by stopping the wait function
2101 oFsm.omciMIdsResponseReceived <- true
2102 }
2103 return nil
2104 }
2105 default:
2106 {
2107 logger.Warnw(ctx, "Unsupported ME name received!",
2108 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002109 }
2110 }
2111 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002112 } else {
2113 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002114 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002115 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002116 return nil
2117}
2118
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002120 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2121 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002123 log.Fields{"device-id": oFsm.deviceID})
2124 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2125 oFsm.deviceID)
2126 }
2127 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2128 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002130 log.Fields{"device-id": oFsm.deviceID})
2131 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2132 oFsm.deviceID)
2133 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05302135 if msgObj.Result == me.UnknownInstance {
2136 logger.Warnw(ctx, "UniVlanConfigFsm - Unknow Instance",
2137 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
2138 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002139 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002140 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002141 // possibly force FSM into abort or ignore some errors for some messages?
2142 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2143 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002144 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2145 oFsm.deviceID)
2146 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002147 oFsm.mutexPLastTxMeInstance.RLock()
2148 if oFsm.pLastTxMeInstance != nil {
2149 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2150 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2151 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002152 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002153 { // let the MultiEntity config proceed by stopping the wait function
2154 oFsm.mutexPLastTxMeInstance.RUnlock()
2155 oFsm.omciMIdsResponseReceived <- true
2156 return nil
2157 }
2158 default:
2159 {
2160 logger.Warnw(ctx, "Unsupported ME name received!",
2161 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2162 }
mpagenko01e726e2020-10-23 09:45:29 +00002163 }
2164 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002165 } else {
2166 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002167 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002168 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002169 return nil
2170}
2171
dbainbri4d3a0dc2020-12-02 00:33:42 +00002172func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002173 oFsm.mutexFlowParams.RLock()
2174 evtocdID := oFsm.evtocdID
2175 oFsm.mutexFlowParams.RUnlock()
2176
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002177 if aFlowEntryNo == 0 {
2178 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002179 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2180 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002182 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002183 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002184 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 associationType := 2 // default to UniPPTP
2186 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002187 associationType = 10
2188 }
2189 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002190 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002191 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002192 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002193 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2194 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002195 },
2196 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002197 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002198 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2199 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002200 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002201 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002202 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2203 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002204 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002205 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2206 }
mpagenkodff5dda2020-08-28 11:52:01 +00002207 //accept also nil as (error) return value for writing to LastTx
2208 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002209 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002210 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002211
2212 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002213 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002214 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002216 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002217 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002218 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2219 }
2220
2221 // Set the EVTOCD ME default params
2222 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002223 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002224 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002225 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2226 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2227 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 },
2229 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002230 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2232 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2233 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002234 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002235 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002236 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2237 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002239 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2240 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002241 //accept also nil as (error) return value for writing to LastTx
2242 // - this avoids misinterpretation of new received OMCI messages
2243 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002244 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002245
2246 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002247 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002248 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002249 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002250 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002251 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002252 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002253 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002254 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002255
mpagenko551a4d42020-12-08 18:09:20 +00002256 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302257 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2258 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002259 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002260 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002262 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002263 sliceEvtocdRule := make([]uint8, 16)
2264 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2265 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2266 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2267 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2268 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2269
2270 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2271 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2272 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2273 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2274 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2275
2276 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2277 0<<cTreatTTROffset| // Do not pop any tags
2278 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2279 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2280 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2281
2282 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2283 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2284 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2285 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2286
2287 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002288 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002289 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002290 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002291 },
2292 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002293 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2295 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2296 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002297 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002298 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002299 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2300 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002302 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2303 }
mpagenkodff5dda2020-08-28 11:52:01 +00002304 //accept also nil as (error) return value for writing to LastTx
2305 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002306 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002307 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002308
2309 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002311 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002313 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002315 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2316
mpagenkodff5dda2020-08-28 11:52:01 +00002317 }
2318 } else {
2319 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2320 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002321 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2322 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2323 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2324 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302325 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002326 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002327
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302328 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2329 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2330 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
2331 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
2332 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2333 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2334 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2335 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2336 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002337
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302338 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2339 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2340 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2341 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2342 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002343
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302344 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2345 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2346 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2347 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2348 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2349
2350 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2351 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2352 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2353 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2354
2355 } else {
2356 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2357 //As of now only a match and no action can be done on the inner tag .
2358 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2359 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2360 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2361 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2362 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2363 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2364 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2365
2366 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2367 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2368 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2369 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2370 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2371
2372 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2373 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2374 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2375 setVid<<cTreatVidOffset| // Set VID
2376 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2377
2378 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2379 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2380 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2381 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2382 }
mpagenko551a4d42020-12-08 18:09:20 +00002383 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002384 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002385 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002386 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002387 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002388 },
2389 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002390 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2392 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2393 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002394 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002395 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002396 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2397 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002399 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2400 }
mpagenkodff5dda2020-08-28 11:52:01 +00002401 //accept also nil as (error) return value for writing to LastTx
2402 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002403 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002404 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002405
2406 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002407 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002408 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302409 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002410 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002411 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302412 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002413 }
2414 } else {
2415 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2416 { // just for local var's
2417 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002418 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002419 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002420 sliceEvtocdRule := make([]uint8, 16)
2421 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2422 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2423 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2424 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2425 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2426
2427 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2428 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2429 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2430 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2431 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2432
2433 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2434 0<<cTreatTTROffset| // Do not pop any tags
2435 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2436 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2437 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2438
2439 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2440 0<<cTreatPrioOffset| // vlan prio set to 0
2441 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002442 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002443 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2444
mpagenko551a4d42020-12-08 18:09:20 +00002445 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002446 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002447 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002448 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002449 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002450 },
2451 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002452 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2454 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2455 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002456 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002457 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002458 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2459 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002461 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2462 }
mpagenkodff5dda2020-08-28 11:52:01 +00002463 //accept also nil as (error) return value for writing to LastTx
2464 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002465 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002466 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002467
2468 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002469 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002470 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002471 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002472 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002473 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002474 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2475
mpagenkodff5dda2020-08-28 11:52:01 +00002476 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002477 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002478 { // just for local var's
2479 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002481 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002482 sliceEvtocdRule := make([]uint8, 16)
2483 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2484 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2485 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2486 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2487 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2488
2489 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2490 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2491 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2492 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2493 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2494
2495 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2496 1<<cTreatTTROffset| // pop the prio-tag
2497 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2498 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2499 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2500
mpagenko551a4d42020-12-08 18:09:20 +00002501 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002502 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2503 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2504 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002505 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002506 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002507 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002508
2509 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002510 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002511 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002512 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002513 },
2514 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002515 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002516 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2517 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2518 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002519 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002520 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002521 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2522 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002524 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2525 }
mpagenkodff5dda2020-08-28 11:52:01 +00002526 //accept also nil as (error) return value for writing to LastTx
2527 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002528 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002529 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002530
2531 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002532 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002533 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002534 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002535 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002537 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2538
mpagenkodff5dda2020-08-28 11:52:01 +00002539 }
2540 } //just for local var's
2541 }
2542 }
2543
mpagenkofc4f56e2020-11-04 17:17:49 +00002544 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002546 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002548 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002549 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002550}
2551
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002553 oFsm.mutexFlowParams.RLock()
2554 evtocdID := oFsm.evtocdID
2555 oFsm.mutexFlowParams.RUnlock()
2556
mpagenko01e726e2020-10-23 09:45:29 +00002557 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2558 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2559 //transparent transmission was set
2560 //perhaps the config is not needed for removal,
2561 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002562 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002563 "device-id": oFsm.deviceID})
2564 sliceEvtocdRule := make([]uint8, 16)
2565 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2566 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2567 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2568 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2569 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2570
2571 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2572 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2573 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2574 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2575 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2576
2577 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2578 0<<cTreatTTROffset| // Do not pop any tags
2579 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2580 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2581 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2582
2583 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2584 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2585 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2586 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2587
2588 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002589 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002590 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002591 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002592 },
2593 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002594 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2596 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2597 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002598 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002599 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002600 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2601 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002602 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002603 return
2604 }
mpagenko01e726e2020-10-23 09:45:29 +00002605 //accept also nil as (error) return value for writing to LastTx
2606 // - this avoids misinterpretation of new received OMCI messages
2607 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002608 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002609
2610 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002611 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002612 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002613 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002614 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002615 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002616 return
2617 }
2618 } else {
2619 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002620 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002621 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002622 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002623 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302624 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002625
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302626 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2627 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2628 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2629 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2630 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2631 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2632 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2633 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002634
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302635 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2636 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2637 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2638 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2639 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002640
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302641 // delete indication for the indicated Filter
2642 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2643 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2644
2645 } else {
2646 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2647 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2648 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
Akash Reddy Kankanala92dfdf82025-03-23 22:07:09 +05302649 sliceEvtocdRule = make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302650 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2651 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2652 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2653 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2654 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2655
2656 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2657 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2658 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2659 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2660 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2661
2662 // delete indication for the indicated Filter
2663 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2664 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2665 }
mpagenko01e726e2020-10-23 09:45:29 +00002666 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002667 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002668 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002669 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002670 },
2671 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002672 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2674 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2675 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002676 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002677 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002678 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2679 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002680 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002681 return
2682 }
mpagenko01e726e2020-10-23 09:45:29 +00002683 //accept also nil as (error) return value for writing to LastTx
2684 // - this avoids misinterpretation of new received OMCI messages
2685 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002686 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002687
2688 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002689 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002690 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302691 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2692 log.Fields{"device-id": oFsm.deviceID,
2693 "match-vlan": aRuleParams.MatchVid,
2694 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002696 return
2697 }
2698 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002699 // VOL-3685
2700 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2701 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2702 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2703 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2704 // later when the flow is being re-installed.
2705 // Of course this is applicable to case only where single service (or single tcont) is in use and
2706 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2707 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2708 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002709 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002710 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002711 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002712 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2713 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002714 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002715 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002716 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002717 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2719 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2720 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002721 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002722 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002723 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2724 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002726 return
2727 }
mpagenko01e726e2020-10-23 09:45:29 +00002728 //accept also nil as (error) return value for writing to LastTx
2729 // - this avoids misinterpretation of new received OMCI messages
2730 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002731 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002732
2733 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002734 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002735 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002737 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002738 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002739 return
2740 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002741 } else {
2742 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2743 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002745 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002746 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002747 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2748 { // just for local var's
2749 // this defines stacking scenario: untagged->singletagged
2750 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2751 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2752 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2753 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 "device-id": oFsm.deviceID})
2756 sliceEvtocdRule := make([]uint8, 16)
2757 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2758 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2759 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2760 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2761 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002762
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002763 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2764 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2765 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2766 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2767 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002768
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002769 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2770 0<<cTreatTTROffset| // Do not pop any tags
2771 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2772 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2773 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002774
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002775 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2776 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2777 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2778 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002779
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002780 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002781 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002782 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002783 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002784 },
2785 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002786 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2788 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2789 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002790 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002791 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002792 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2793 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002795 return
2796 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002797 //accept also nil as (error) return value for writing to LastTx
2798 // - this avoids misinterpretation of new received OMCI messages
2799 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002800 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002801
2802 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002803 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002804 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002806 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002807 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002808 return
2809 }
2810 } // just for local var's
2811 { // just for local var's
2812 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002813 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002814 "device-id": oFsm.deviceID})
2815 sliceEvtocdRule := make([]uint8, 16)
2816 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2817 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2818 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2819 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2820 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2821
2822 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2823 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2824 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2825 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2826 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2827
2828 // delete indication for the indicated Filter
2829 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2830 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2831
2832 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002833 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002834 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002835 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002836 },
2837 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002838 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2840 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2841 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002842 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002843 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002844 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2845 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002847 return
2848 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002849 //accept also nil as (error) return value for writing to LastTx
2850 // - this avoids misinterpretation of new received OMCI messages
2851 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002852 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002853
2854 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002855 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002856 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002858 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860 return
2861 }
mpagenko01e726e2020-10-23 09:45:29 +00002862 }
2863 } //just for local var's
2864 }
2865 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002866 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002867 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002868 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002869}
2870
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002872 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002873 if oFsm.isCanceled {
2874 // FSM already canceled before entering wait
2875 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2876 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002877 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002878 }
mpagenko7d6bb022021-03-11 15:07:55 +00002879 oFsm.isAwaitingResponse = true
2880 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002881 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302882 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002883 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002884 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002885 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002886 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002887 oFsm.mutexIsAwaitingResponse.Lock()
2888 oFsm.isAwaitingResponse = false
2889 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002890 oFsm.mutexPLastTxMeInstance.RLock()
2891 if oFsm.pLastTxMeInstance != nil {
2892 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2893 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2894 }
2895 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002896 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002897 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302898 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002899 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002900 oFsm.mutexIsAwaitingResponse.Lock()
2901 oFsm.isAwaitingResponse = false
2902 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002903 return nil
2904 }
mpagenko7d6bb022021-03-11 15:07:55 +00002905 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002906 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002907 oFsm.mutexIsAwaitingResponse.Lock()
2908 oFsm.isAwaitingResponse = false
2909 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002910 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002911 }
2912}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002913
mpagenko551a4d42020-12-08 18:09:20 +00002914func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002916 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002917 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002918 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002919 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002920 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002921 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002922 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2923 }
2924
dbainbri4d3a0dc2020-12-02 00:33:42 +00002925 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002926 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002927 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002928 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002929 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2931 }
2932
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002935 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002936 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2939 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002941 if errMacBpCdEID != nil {
2942 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2943 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002945 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946
Mahir Gunyel6781f962021-05-16 23:30:08 -07002947 }
2948 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002949 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2950 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002951 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002952 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002954 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2955 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2956 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2957 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002958 },
2959 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002960 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002961 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2962 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002963 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002964 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002965 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2966 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002967 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002968 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2969 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002970 //accept also nil as (error) return value for writing to LastTx
2971 // - this avoids misinterpretation of new received OMCI messages
2972 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002973 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002974 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002975 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002976 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2978 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002979 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2980 }
2981
2982 // ==> Start creating VTFD for mcast vlan
2983
2984 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2985 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002986 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002987
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002989 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002990 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002991 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2992
2993 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2994 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2995 // new vlan associated with a different TP.
2996 vtfdFilterList[0] = uint16(vlanID)
2997
2998 meParams = me.ParamData{
2999 EntityID: mcastVtfdID,
3000 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003001 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
3002 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
3003 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003004 },
3005 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003006 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003007 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3008 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003009 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003010 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003011 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3012 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003013 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003014 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3015 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003016 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003017 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003018 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003019 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003020 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003021 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003023 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3024 }
3025
3026 return nil
3027}
3028
dbainbri4d3a0dc2020-12-02 00:33:42 +00003029func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003030 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003031 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003032 logger.Errorw(ctx, "error generrating me instance id",
3033 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003034 return err
3035 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003036 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3037 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003038 meParams := me.ParamData{
3039 EntityID: instID,
3040 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003041 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003042 //Direct reference to the Operation profile
3043 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003044 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003045 },
3046 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003047 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003048 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3049 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3050 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003051 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003052 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003053 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3054 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003055 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003056 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3057 oFsm.deviceID, err)
3058 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003059 //accept also nil as (error) return value for writing to LastTx
3060 // - this avoids misinterpretation of new received OMCI messages
3061 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003062 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003063 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003064 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003065 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003066 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003067 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3068 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3069 }
3070 return nil
3071}
3072
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003074 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003075 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003076 logger.Errorw(ctx, "error generating me instance id",
3077 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003078 return err
3079 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003080 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3081 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003082 meParams := me.ParamData{
3083 EntityID: instID,
3084 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003085 me.MulticastOperationsProfile_IgmpVersion: 2,
3086 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003087 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003088 me.MulticastOperationsProfile_ImmediateLeave: 0,
3089 me.MulticastOperationsProfile_Robustness: 2,
3090 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3091 me.MulticastOperationsProfile_QueryInterval: 125,
3092 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3093 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003094 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003095 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003096 },
3097 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003098 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003099 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3100 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3101 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003102 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003103 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003104 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3105 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003106 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003107 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3108 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003109 //accept also nil as (error) return value for writing to LastTx
3110 // - this avoids misinterpretation of new received OMCI messages
3111 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003112 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003113 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003114 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003115 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003116 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003117 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003118 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003119 }
3120 return nil
3121}
3122
dbainbri4d3a0dc2020-12-02 00:33:42 +00003123func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003124 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003125 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003126 logger.Errorw(ctx, "error generating me instance id",
3127 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003128 return err
3129 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003130 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3131 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003132 //TODO check that this is correct
3133 // Table control
3134 //setCtrl = 1
3135 //rowPartId = 0
3136 //test = 0
3137 //rowKey = 0
3138 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003139 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003140 dynamicAccessCL := make([]uint8, 24)
3141 copy(dynamicAccessCL, tableCtrl)
3142 //Multicast GemPortId
3143 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3144 // python version waits for installation of flows, see line 723 onward of
3145 // brcm_openomci_onu_handler.py
3146 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3147 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003149 //TODO start and end are hardcoded, get from TP
3150 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003152 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003153 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003154 //imputed group bandwidth
3155 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3156
3157 meParams := me.ParamData{
3158 EntityID: instID,
3159 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003160 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003161 },
3162 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003163 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003164 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3165 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3166 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003167 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003168 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003169 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3170 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003172 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3173 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003174 //accept also nil as (error) return value for writing to LastTx
3175 // - this avoids misinterpretation of new received OMCI messages
3176 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003177 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003178 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003179 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003180 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003181 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003182 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003183 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003184 }
3185 return nil
3186}
Girish Gowdra26a40922021-01-29 17:14:34 -08003187
khenaidoo42dcdfd2021-10-19 17:34:12 -04003188func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003189 tpID uint8, uniID uint8, gemPortID uint16) error {
3190 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3191 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3192 // I created unique TD ID by flow direction.
3193 // TODO! Traffic descriptor ME ID will check
3194 trafficDescriptorID := gemPortID
3195 if aMeter == nil {
3196 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3197 }
3198 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3199 if err != nil {
3200 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3201 return err
3202 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003203 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003204 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003205 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003206 pbs := trafficShapingInfo.Pbs
3207
3208 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3209 meParams := me.ParamData{
3210 EntityID: trafficDescriptorID,
3211 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003212 me.TrafficDescriptor_Cir: cir,
3213 me.TrafficDescriptor_Pir: pir,
3214 me.TrafficDescriptor_Cbs: cbs,
3215 me.TrafficDescriptor_Pbs: pbs,
3216 me.TrafficDescriptor_ColourMode: 1,
3217 me.TrafficDescriptor_IngressColourMarking: 3,
3218 me.TrafficDescriptor_EgressColourMarking: 3,
3219 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003220 },
3221 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003222 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003223 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3224 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003225 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003226 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003227 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3228 return err
3229 }
3230 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003231 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003232 err = oFsm.waitforOmciResponse(ctx)
3233 if err != nil {
3234 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3235 return err
3236 }
3237
Girish Gowdra09e5f212021-09-30 16:28:36 -07003238 // 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
3239 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003240 if err != nil {
3241 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3242 return err
3243 }
3244 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3245
3246 return nil
3247}
3248
Girish Gowdra09e5f212021-09-30 16:28:36 -07003249func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3250 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3251 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003252 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003253 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003254 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003255 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003256 },
3257 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003258 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003259 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3260 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003261 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003262 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003263 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3264 return err
3265 }
3266 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003267 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003268 err = oFsm.waitforOmciResponse(ctx)
3269 if err != nil {
3270 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3271 return err
3272 }
3273 return nil
3274}
3275
Girish Gowdra26a40922021-01-29 17:14:34 -08003276// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003277func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3278 if oFsm == nil {
3279 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3280 return false
3281 }
mpagenkobb47bc22021-04-20 13:29:09 +00003282 oFsm.mutexFlowParams.Lock()
3283 defer oFsm.mutexFlowParams.Unlock()
3284 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3285 //flow removal is still ongoing/pending
3286 oFsm.signalOnFlowDelete = true
3287 oFsm.flowDeleteChannel = aFlowDeleteChannel
3288 return true
3289 }
3290 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003291}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003292
3293func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3294 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3295 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3296 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3297 log.Fields{"device-id": oFsm.deviceID})
3298 } else {
3299 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3300 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3301 "index": oFsm.numVlanFilterEntries,
3302 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3303 "device-id": oFsm.deviceID})
3304 oFsm.numVlanFilterEntries++
3305 }
3306}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003307
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003308// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3309func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003310 if respChan != nil {
3311 // 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
3312 select {
3313 case *respChan <- err:
3314 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3315 default:
3316 }
3317 }
3318}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003319
3320// PrepareForGarbageCollection - remove references to prepare for garbage collection
3321func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3322 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3323 oFsm.pDeviceHandler = nil
3324 oFsm.pOnuDeviceEntry = nil
3325 oFsm.pOmciCC = nil
3326}