blob: b17de4da304a1b02ce9b93bbffcd23f7d93d8dc8 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
Joey Armstronge8c091f2023-01-17 16:56:26 -05002 * Copyright 2020-2023 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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package avcfg provides anig and vlan configuration functionality
18package 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
mpagenko01e726e2020-10-23 09:45:29 +000046 cVtfdTableSize = 12 //as per G.988
47 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 isSuspendedOnAdd bool
140 removeChannel chan bool
141 cookie uint64 //just the last cookie valid for removal
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000142 vlanRuleParams cmn.UniVlanRuleParams
Girish Gowdrae95687a2021-09-08 16:30:58 -0700143 respChan *chan error
mpagenko01e726e2020-10-23 09:45:29 +0000144}
145
mpagenkobb47bc22021-04-20 13:29:09 +0000146//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000148type UniVlanConfigFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000149 pDeviceHandler cmn.IdeviceHandler
150 pOnuDeviceEntry cmn.IonuDeviceEntry
mpagenko01e726e2020-10-23 09:45:29 +0000151 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 pOmciCC *cmn.OmciCC
153 pOnuUniPort *cmn.OnuUniPort
154 pUniTechProf *OnuUniTechProf
155 pOnuDB *devdb.OnuDeviceDB
156 requestEvent cmn.OnuDeviceEvent
mpagenkodff5dda2020-08-28 11:52:01 +0000157 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000158 PAdaptFsm *cmn.AdapterFsm
mpagenkodff5dda2020-08-28 11:52:01 +0000159 acceptIncrementalEvtoOption bool
mpagenkocf48e452021-04-23 09:23:00 +0000160 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000161 isAwaitingResponse bool
162 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000163 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000164 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
Girish Gowdrae95687a2021-09-08 16:30:58 -0700165 actualUniFlowParam cmn.UniVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000166 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000167 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168 NumUniFlows uint8 // expected number of flows should be less than 12
169 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000170 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000171 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000172 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000174 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000175 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000176 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000177 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000178 signalOnFlowDelete bool
179 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000180 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
181 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200182 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
183 // thus notification needs to be sent on chan.
184 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000185}
186
mpagenko01e726e2020-10-23 09:45:29 +0000187//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
188// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000189func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
190 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
191 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530192 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 +0000193 instFsm := &UniVlanConfigFsm{
194 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000195 pOnuDeviceEntry: apOnuDeviceEntry,
196 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000197 pOmciCC: apDevOmciCC,
198 pOnuUniPort: apUniPort,
199 pUniTechProf: apUniTechProf,
200 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000201 requestEvent: aRequestEvent,
202 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000203 NumUniFlows: 0,
204 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000205 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200206 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000207 }
208
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000209 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
210 if instFsm.PAdaptFsm == nil {
211 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000212 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700213 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000214 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000215 return nil
216 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000217 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
218 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000219 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000220 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
221 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
222 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
223 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
224 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
225 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
226 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
227 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
228 Dst: VlanStConfigDone},
229 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
230 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
231 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
232 Dst: VlanStConfigIncrFlow},
233 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
234 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
235 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000236 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000237 {Name: VlanEvTimeoutSimple, Src: []string{
238 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
239 {Name: VlanEvTimeoutMids, Src: []string{
240 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000241 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000242 // exceptional treatment for all states except VlanStResetting
243 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
244 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
245 VlanStRemoveFlow, VlanStCleanupDone},
246 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000247 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000249 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
251 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
252 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000253 },
mpagenkodff5dda2020-08-28 11:52:01 +0000254 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000255 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
256 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
257 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
258 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
259 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
260 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
261 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
262 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
263 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
264 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
265 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000266 },
267 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000268 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000270 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700271 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000272 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000273 return nil
274 }
275
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530276 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, aMeter, respChan)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000278 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return instFsm
280}
281
mpagenko01e726e2020-10-23 09:45:29 +0000282//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000283func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530284 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530286 TpID: aTpID,
287 MatchVid: uint32(aMatchVlan),
288 MatchPcp: uint32(aMatchPcp),
289 SetVid: uint32(aSetVlan),
290 SetPcp: uint32(aSetPcp),
291 InnerCvlan: innerCvlan,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000292 }
293 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +0530294 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 //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 +0000298 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
300 } else {
301 if !oFsm.acceptIncrementalEvtoOption {
302 //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 +0000303 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000304 }
305 }
306
mpagenko01e726e2020-10-23 09:45:29 +0000307 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000308 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.TagsToRemove = 0 //no tag pop action
310 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
311 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000312 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
313 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
314 // might collide with NoMatchVid/CopyPrio(/setVid) setting
315 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000316 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000317 }
318 }
mpagenko01e726e2020-10-23 09:45:29 +0000319
Girish Gowdrae95687a2021-09-08 16:30:58 -0700320 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000321 loFlowParams.CookieSlice = make([]uint64, 0)
322 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300323 if aMeter != nil {
324 loFlowParams.Meter = aMeter
325 }
mpagenko01e726e2020-10-23 09:45:29 +0000326
327 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000329 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000331 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
332 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
333 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
334 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000338 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
339 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000340 //cmp also usage in EVTOCDE create in omci_cc
341 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000342 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000343 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
344
345 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000347 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000349 return err
350 }
351
352 return nil
353}
354
mpagenko7d6bb022021-03-11 15:07:55 +0000355//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000356func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandt12609a12022-03-25 13:23:25 +0000357 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000358 if oFsm == nil {
359 logger.Error(ctx, "no valid UniVlanConfigFsm!")
360 return
361 }
mpagenko7d6bb022021-03-11 15:07:55 +0000362 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000363 oFsm.mutexIsAwaitingResponse.Lock()
364 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000365 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000366 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
367 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
368 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000369 //use channel to indicate that the response waiting shall be aborted
370 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000371 } else {
372 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000373 }
mpagenkocf48e452021-04-23 09:23:00 +0000374
mpagenko7d6bb022021-03-11 15:07:55 +0000375 // 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 +0000376 PAdaptFsm := oFsm.PAdaptFsm
377 if PAdaptFsm != nil {
378 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000379 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000380 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000381 }
mpagenko7d6bb022021-03-11 15:07:55 +0000382 }
383}
384
mpagenko551a4d42020-12-08 18:09:20 +0000385//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000386func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
387 if oFsm == nil {
388 logger.Error(ctx, "no valid UniVlanConfigFsm!")
389 return 0
390 }
mpagenko551a4d42020-12-08 18:09:20 +0000391 //mutex protection is required for possible concurrent access to FSM members
392 oFsm.mutexFlowParams.RLock()
393 defer oFsm.mutexFlowParams.RUnlock()
394 return oFsm.TpIDWaitingFor
395}
396
mpagenko01e726e2020-10-23 09:45:29 +0000397//SetUniFlowParams verifies on existence of flow parameters to be configured,
398// optionally udates the cookie list or appends a new flow if there is space
399// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000400// ignore complexity by now
401// nolint: gocyclo
402func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530403 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 +0000404 if oFsm == nil {
405 logger.Error(ctx, "no valid UniVlanConfigFsm!")
406 return fmt.Errorf("no-valid-UniVlanConfigFsm")
407 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000408 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530409 TpID: aTpID,
410 MatchVid: uint32(aMatchVlan),
411 MatchPcp: uint32(aMatchPcp),
412 SetVid: uint32(aSetVlan),
413 SetPcp: uint32(aSetPcp),
414 InnerCvlan: aInnerCvlan,
mpagenko01e726e2020-10-23 09:45:29 +0000415 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700416 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000417 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530418 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
mpagenko01e726e2020-10-23 09:45:29 +0000419 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
420 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
421 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
422 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
423 } else {
424 if !oFsm.acceptIncrementalEvtoOption {
425 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
426 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
427 }
428 }
429
430 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
431 // no prio/vid filtering requested
432 loRuleParams.TagsToRemove = 0 //no tag pop action
433 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
434 if loRuleParams.SetPcp == cCopyPrioFromInner {
435 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
436 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
437 // might collide with NoMatchVid/CopyPrio(/setVid) setting
438 // this was some precondition setting taken over from py adapter ..
439 loRuleParams.SetPcp = 0
440 }
441 }
442
mpagenkof1d21d12021-06-11 13:14:45 +0000443 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
444 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
445 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
446 oFsm.mutexFlowParams.RLock()
447 if len(oFsm.uniRemoveFlowsSlice) > 0 {
448 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
449 if removeUniFlowParams.vlanRuleParams == loRuleParams {
450 // the flow to add is the same as the one already in progress of deleting
451 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000452 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
453 if flow >= len(oFsm.uniRemoveFlowsSlice) {
454 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
455 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
456 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700457 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000458 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700459 return err
460
mpagenkof582d6a2021-06-18 15:58:10 +0000461 }
mpagenkof1d21d12021-06-11 13:14:45 +0000462 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
463 oFsm.mutexFlowParams.RUnlock()
464 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
465 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
466 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700467 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000468 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700469 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000470 }
471 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000472 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000473 }
474 }
475 }
476 oFsm.mutexFlowParams.RUnlock()
477
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000478 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000479 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000480 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200481 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000482 //mutex protection is required for possible concurrent access to FSM members
483 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000484 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
485 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
486 // countable run time optimization (perhaps with including the hash in kvStore storage?)
487 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000488 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000489 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300490 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
491 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
492 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000493 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000494 var cookieMatch bool
495 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
496 cookieMatch = false
497 for _, cookie := range storedUniFlowParams.CookieSlice {
498 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000500 "device-id": oFsm.deviceID, "cookie": cookie})
501 cookieMatch = true
502 break //found new cookie - no further search for this requested cookie
503 }
504 }
505 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000506 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
507 if delayedCookie != 0 {
508 //a delay for adding the cookie to this rule is requested
509 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
510 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000511 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
512 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
513 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700514 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000515 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700516 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000517 }
mpagenkobc4170a2021-08-17 16:42:10 +0000518 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000519 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000520 } else {
521 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
522 "device-id": oFsm.deviceID, "cookie": newCookie})
523 //as range works with copies of the slice we have to write to the original slice!!
524 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
525 newCookie)
526 flowCookieModify = true
527 }
mpagenko01e726e2020-10-23 09:45:29 +0000528 }
529 } //for all new cookies
530 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000531 }
532 }
mpagenkof1fc3862021-02-16 10:09:52 +0000533 oFsm.mutexFlowParams.Unlock()
534
535 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000536 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
537 if !deleteSuccess {
538 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
539 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700540 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000541 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700542 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000543 }
mpagenkof1fc3862021-02-16 10:09:52 +0000544 requestAppendRule = true //default assumption here is that rule is to be appended
545 flowCookieModify = true //and that the the flow data base is to be updated
546 if delayedCookie != 0 { //it was suspended
547 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
548 }
549 }
550 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
551 if requestAppendRule {
552 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000553 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700554 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000555 loFlowParams.CookieSlice = make([]uint64, 0)
556 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300557 if aMeter != nil {
558 loFlowParams.Meter = aMeter
559 }
mpagenko01e726e2020-10-23 09:45:29 +0000560 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000561 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000563 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
564 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
566 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000567
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000569 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
570 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 oFsm.NumUniFlows++
572 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000573
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000575 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000577 //attention: take care to release the mutexFlowParams when calling the FSM directly -
578 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000579 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
581 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000582 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700584 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000585 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700586 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000587 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000588 }
589 return nil
590 }
mpagenko01e726e2020-10-23 09:45:29 +0000591 // note: theoretical it would be possible to clear the same rule from the remove slice
592 // (for entries that have not yet been started with removal)
593 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
594 // 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 +0000595
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000597 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000599 // this is a restart with a complete new flow, we can re-use the initial flow config control
600 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000601 //attention: take care to release the mutexFlowParams when calling the FSM directly -
602 // synchronous FSM 'event/state' functions may rely on this mutex
603 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000604 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000605 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
606 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
607 }
mpagenko551a4d42020-12-08 18:09:20 +0000608 } else {
609 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000610 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000612 //check introduced after having observed some panic here
613 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000614 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000615 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
616 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700617 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000618 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000620 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700621
622 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000623 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700624 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000625 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000627 //attention: take care to release the mutexFlowParams when calling the FSM directly -
628 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000629 // but it must be released already before calling getTechProfileDone() as it may already be locked
630 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000631 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000633 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000635 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
636
mpagenkobb47bc22021-04-20 13:29:09 +0000637 var fsmErr error
638 if loTechProfDone {
639 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000641 } else {
642 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000643 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000644 }
645 if fsmErr != nil {
646 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
647 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000648 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700649 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000650 }
mpagenko551a4d42020-12-08 18:09:20 +0000651 }
mpagenkobb47bc22021-04-20 13:29:09 +0000652 } else {
653 // if not in the appropriate state a new entry will be automatically considered later
654 // when the configDone state is reached
655 oFsm.mutexFlowParams.Unlock()
656 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000657 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000658 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000659 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000660 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700661 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000662 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700663 return err
mpagenko01e726e2020-10-23 09:45:29 +0000664 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000665 } else {
666 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000667 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700668 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000669 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700670
mpagenko15ff4a52021-03-02 10:09:20 +0000671 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000672 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 //all requested rules really have been configured
674 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000675 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000676 if oFsm.pDeviceHandler != nil {
677 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000678 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000679 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000680 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
681 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000682 }
683 } else {
684 // avoid device reason update as the rule config connected to this flow may still be in progress
685 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000686 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000687 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000688 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000689 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000690 }
691 }
mpagenko01e726e2020-10-23 09:45:29 +0000692
mpagenkof1fc3862021-02-16 10:09:52 +0000693 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000694 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000695 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000696 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000697 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000698 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000700 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000701 }
mpagenko15ff4a52021-03-02 10:09:20 +0000702 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000703 }
704 return nil
705}
706
mpagenkof1d21d12021-06-11 13:14:45 +0000707func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
708 oFsm.mutexFlowParams.Lock()
709 deleteChannel := apRemoveFlowParams.removeChannel
710 apRemoveFlowParams.isSuspendedOnAdd = true
711 oFsm.mutexFlowParams.Unlock()
712
713 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
714 select {
715 case success := <-deleteChannel:
716 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
717 if success {
718 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
719 "device-id": oFsm.deviceID})
720 return nil
721 }
722 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
723 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
724 oFsm.mutexFlowParams.Lock()
725 if apRemoveFlowParams != nil {
726 apRemoveFlowParams.isSuspendedOnAdd = false
727 }
728 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000729 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000730 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000731 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000732 }
mpagenkof1d21d12021-06-11 13:14:45 +0000733}
734
mpagenkof1fc3862021-02-16 10:09:52 +0000735// VOL-3828 flow config sequence workaround ########### start ##########
736func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
737 //assumes mutexFlowParams.Lock() protection from caller!
738 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
739 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000740 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000741 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
742 newCookie := aCookieSlice[0]
743 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
744 for _, cookie := range storedUniFlowParams.CookieSlice {
745 if cookie == newCookie {
746 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
747 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
748 oFsm.delayNewRuleCookie = newCookie
749 return newCookie //found new cookie in some existing rule
750 }
751 } // for all stored cookies of the actual inspected rule
752 } //for all rules
753 }
754 return 0 //no delay requested
755}
mpagenkobc4170a2021-08-17 16:42:10 +0000756func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000757 oFsm.mutexFlowParams.RLock()
758 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
759 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
760 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000761 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000762 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000763 case cookieDeleted = <-oFsm.chCookieDeleted:
764 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
765 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000766 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000767 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
768 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
769 }
770 oFsm.mutexFlowParams.Lock()
771 oFsm.delayNewRuleCookie = 0
772 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000773 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000774}
mpagenkobc4170a2021-08-17 16:42:10 +0000775func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000776 oFsm.mutexFlowParams.Lock()
777 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
778 oFsm.mutexFlowParams.Unlock()
779
mpagenkobc4170a2021-08-17 16:42:10 +0000780 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000781 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000782 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000783 }
mpagenkobc4170a2021-08-17 16:42:10 +0000784 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000785}
786
787//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000788func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000789 flowEntryMatch := false
790 oFsm.mutexFlowParams.Lock()
791 defer oFsm.mutexFlowParams.Unlock()
792 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
793 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
794 flowEntryMatch = true
795 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
796 "device-id": oFsm.deviceID})
797 cookieMatch := false
798 for _, cookie := range storedUniFlowParams.CookieSlice {
799 if cookie == aCookie {
800 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
801 "device-id": oFsm.deviceID, "cookie": cookie})
802 cookieMatch = true
803 break //found new cookie - no further search for this requested cookie
804 }
805 }
806 if !cookieMatch {
807 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
808 "device-id": oFsm.deviceID, "cookie": aCookie})
809 //as range works with copies of the slice we have to write to the original slice!!
810 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
811 aCookie)
812 return true, false //flowModified, NoRuleAppend
813 }
814 break // found rule - no further rule search
815 }
816 }
817 if !flowEntryMatch { //it is a new rule
818 return true, true //flowModified, RuleAppend
819 }
820 return false, false //flowNotModified, NoRuleAppend
821}
822
823// VOL-3828 flow config sequence workaround ########### end ##########
824
mpagenko01e726e2020-10-23 09:45:29 +0000825//RemoveUniFlowParams verifies on existence of flow cookie,
826// if found removes cookie from flow cookie list and if this is empty
827// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700828func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000829 if oFsm == nil {
830 logger.Error(ctx, "no valid UniVlanConfigFsm!")
831 return fmt.Errorf("no-valid-UniVlanConfigFsm")
832 }
mpagenkof1fc3862021-02-16 10:09:52 +0000833 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000834 flowCookieMatch := false
835 //mutex protection is required for possible concurrent access to FSM members
836 oFsm.mutexFlowParams.Lock()
837 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000838remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000839 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
840 for i, cookie := range storedUniFlowParams.CookieSlice {
841 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000842 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000843 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000844 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000845 //remove the cookie from the cookie slice and verify it is getting empty
846 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000847 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700848 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000849 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000850 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000851 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000852 //cut off the requested cookie by slicing out this element
853 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
854 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
855 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000856 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
857 // state transition notification is checked in deviceHandler
858 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000859 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
860 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000861 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000863 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000864 if deletedCookie == oFsm.delayNewRuleCookie {
865 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
866 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
867 //simply use the first one
868 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
869 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
870 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
871 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700872 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000873 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000874 //permanently store the modified flow config for reconcile case and immediately write to KvStore
875 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000876 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000877 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
878 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
879 return err
880 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000881 }
mpagenko01e726e2020-10-23 09:45:29 +0000882 }
mpagenkof1fc3862021-02-16 10:09:52 +0000883 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000884 }
885 }
mpagenko01e726e2020-10-23 09:45:29 +0000886 } //search all flows
887 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000888 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000889 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
890 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000891 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
892 // state transition notification is checked in deviceHandler
893 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000894 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000895 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000896 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700897 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000898 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000899 return nil
900 } //unknown cookie
901
902 return nil
903}
904
mpagenkof582d6a2021-06-18 15:58:10 +0000905// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000906// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000907func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700908 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000909 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000910 var cancelPendingConfig bool = false
911 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
912 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
913 "device-id": oFsm.deviceID})
914 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
915 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
916 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
917 // 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 +0000918 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000919 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
920 log.Fields{"device-id": oFsm.deviceID})
921 cancelPendingConfig = true
922 } else {
923 //create a new element for the removeVlanFlow slice
924 loRemoveParams = uniRemoveVlanFlowParams{
925 vlanRuleParams: aUniFlowParams.VlanRuleParams,
926 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700927 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000928 }
929 loRemoveParams.removeChannel = make(chan bool)
930 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
931 }
932
933 usedTpID := aUniFlowParams.VlanRuleParams.TpID
934 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
935 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
936 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
937 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000938 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
939 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000940 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
941 "device-id": oFsm.deviceID})
942 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000943 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000944 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000945 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000946 }
947 } else {
948 if !cancelPendingConfig {
949 oFsm.updateTechProfileToDelete(ctx, usedTpID)
950 }
951 }
952 //trigger the FSM to remove the relevant rule
953 if cancelPendingConfig {
954 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000956 //call from 'non-configured' state of the rules
957 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
958 //something quite inconsistent detected, perhaps just try to recover with FSM reset
959 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000960 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000961 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
962 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
963 }
964 return false //data base update could not be done, return like cookie not found
965 }
966
967 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
968 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
969 // synchronous FSM 'event/state' functions may rely on this mutex
970 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000971 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000972 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
973 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
974 }
975 oFsm.mutexFlowParams.Lock()
976 return true
977 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000979 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000981 "tp-id": loRemoveParams.vlanRuleParams.TpID,
982 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
983 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
984 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
985 // synchronous FSM 'event/state' functions may rely on this mutex
986 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000987 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000988 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
989 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
990 }
991 oFsm.mutexFlowParams.Lock()
992 } // if not in the appropriate state a new entry will be automatically considered later
993 // when the configDone state is reached
994 return true
995}
996
mpagenkof1d21d12021-06-11 13:14:45 +0000997//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
998// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
999// from the start of the deletion request to avoid to much interference
1000// so when called, there can only be one cookie active for this flow
1001// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001002func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001003 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1004 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001005 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001006removeFromSlice_loop:
1007 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001008 // if UniFlowParams exists, cookieSlice should always have at least one element
1009 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1010 if cookieSliceLen == 1 {
1011 if storedUniFlowParams.CookieSlice[0] == aCookie {
1012 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001013 }
mpagenkof582d6a2021-06-18 15:58:10 +00001014 } else if cookieSliceLen == 0 {
1015 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1016 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1017 return errors.New(errStr)
1018 } else {
1019 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1020 logger.Errorw(ctx, errStr, log.Fields{
1021 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1022 for _, cookie := range storedUniFlowParams.CookieSlice {
1023 if cookie == aCookie {
1024 cookieFound = true
1025 break
1026 }
1027 }
1028 }
1029 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001030 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1031 "device-id": oFsm.deviceID, "cookie": aCookie})
1032 //remove the actual element from the addVlanFlow slice
1033 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1034 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001035 oFsm.NumUniFlows = 0 //no more flows
1036 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001037 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1038 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1039 //request that this profile gets deleted before a new flow add is allowed
1040 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1041 "device-id": oFsm.deviceID})
1042 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001043 oFsm.NumUniFlows--
1044 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1045 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001046 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001047 if !aWasConfigured {
1048 // We did not actually process this flow but was removed before that.
1049 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001050 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001051 }
1052
mpagenkof1d21d12021-06-11 13:14:45 +00001053 //cut off the requested flow by slicing out this element
1054 oFsm.uniVlanFlowParamsSlice = append(
1055 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1056 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1057 "device-id": oFsm.deviceID})
1058 }
1059 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1060 }
1061 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001062 if !cookieFound {
1063 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1064 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1065 return errors.New(errStr)
1066 }
mpagenkodee02a62021-07-21 10:56:10 +00001067 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1068 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001070 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1071 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1072 return err
1073 }
mpagenkof582d6a2021-06-18 15:58:10 +00001074 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001075}
1076
1077// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001078func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1079 //here we have to check, if there are still other flows referencing to the actual ProfileId
1080 // before we can request that this profile gets deleted before a new flow add is allowed
1081 tpIDInOtherFlows := false
1082 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1083 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1084 tpIDInOtherFlows = true
1085 break // search loop can be left
1086 }
1087 }
1088 if tpIDInOtherFlows {
1089 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1090 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1091 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001092 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 +00001093 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001094 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1095 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001096 if oFsm.pUniTechProf != nil {
1097 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001098 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001099 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001100 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001101 }
1102}
1103
mpagenkof1d21d12021-06-11 13:14:45 +00001104func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1105 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001106
1107 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001108 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001109 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001110 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001111 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001112 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001113 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001114 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001115 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001116 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001117 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001119 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 go func(a_pAFsm *cmn.AdapterFsm) {
1121 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001122 }(pConfigVlanStateAFsm)
1123 return
1124 }
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(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001128 }(pConfigVlanStateAFsm)
1129 return
1130 }
1131 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1132 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1133 //should never happen, else: recovery would be needed from outside the FSM
1134}
1135
1136func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1137 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001139 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001140 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001141 //possibly the entry is not valid anymore based on intermediate delete requests
1142 //just a basic protection ...
1143 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1144 oFsm.mutexFlowParams.Unlock()
1145 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1146 "device-id": oFsm.deviceID})
1147 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001148 go func(a_pAFsm *cmn.AdapterFsm) {
1149 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001150 }(pConfigVlanStateAFsm)
1151 return
1152 }
mpagenko9a304ea2020-12-16 15:54:01 +00001153 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1154 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001155 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1156 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001157 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001158 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001159 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1160 // synchronous FSM 'event/state' functions may rely on this mutex
1161 // but it must be released already before calling getTechProfileDone() as it may already be locked
1162 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001163 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001164 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001165 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001166 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001167 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001168
mpagenko9a304ea2020-12-16 15:54:01 +00001169 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001170 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1171 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001172 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001173 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001174 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001175 } else {
1176 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001177 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001178 }
1179 }
mpagenko551a4d42020-12-08 18:09:20 +00001180 }(pConfigVlanStateAFsm, loTechProfDone)
1181 } else {
1182 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1183 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1184 //should never happen, else: recovery would be needed from outside the FSM
1185 return
mpagenkodff5dda2020-08-28 11:52:01 +00001186 }
1187}
1188
dbainbri4d3a0dc2020-12-02 00:33:42 +00001189func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001190 //mutex protection is required for possible concurrent access to FSM members
1191 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001192 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001193 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001194 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001195 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001196 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001197 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001198 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001199 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001200 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001201 go func(a_pAFsm *cmn.AdapterFsm) {
1202 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001203 }(pConfigVlanStateAFsm)
1204 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001205 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1206 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001207 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001209 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001210 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001211 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001212 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001213 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001214 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001215 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001216 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1217 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001218 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001219 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001220 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001221 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1222 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1223 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001224 },
1225 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001226 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001227 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001228 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001229 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1230 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001231 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001232 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001233 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1234 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001235 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001236 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001237 go func(a_pAFsm *cmn.AdapterFsm) {
1238 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001239 }(pConfigVlanStateAFsm)
1240 }
1241 return
1242 }
mpagenkodff5dda2020-08-28 11:52:01 +00001243 //accept also nil as (error) return value for writing to LastTx
1244 // - this avoids misinterpretation of new received OMCI messages
1245 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1246 // send shall return (dual format) error code that can be used here for immediate error treatment
1247 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001248 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001249 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001250 }
1251}
1252
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1254 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001255 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001256 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001257 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001258 //using the first element in the slice because it's the first flow per definition here
1259 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001260 //This is correct passing scenario
1261 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001262 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001263 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1264 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001266 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1267 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001270 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001272 vlanID)
1273 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001275 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001276 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001277 }
1278 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001279 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001280 if oFsm.actualUniFlowParam.Meter != nil {
1281 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001283 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1284 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001286 if errCreateTrafficDescriptor != nil {
1287 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1288 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001290 }
1291 }
1292 }
1293
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001294 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001295 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001296 }
1297 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001298}
1299
dbainbri4d3a0dc2020-12-02 00:33:42 +00001300func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001301
mpagenkof1d21d12021-06-11 13:14:45 +00001302 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001303
mpagenkof1fc3862021-02-16 10:09:52 +00001304 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001305 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001306 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001307 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001308 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001309 }
1310
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001312 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001313 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001314 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1315 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1316 //should never happen, else: recovery would be needed from outside the FSM
1317 return
1318 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001319 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001320 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1321 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001322 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001324 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1325 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001326 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001327 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001328 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001329 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001330 }(pConfigVlanStateBaseFsm)
1331 return
1332 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001333 if oFsm.lastFlowToReconcile {
1334 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1335 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1336 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1337 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1338 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1339 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001340 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1341 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001342 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001343 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001344 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001345 return
1346 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1348 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001349 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001350 // this is a restart with a complete new flow, we can re-use the initial flow config control
1351 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001352 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001353 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001354 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001355 }(pConfigVlanStateBaseFsm)
1356 return
1357 }
1358
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001359 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001360 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001362 //check introduced after having observed some panic in this processing
1363 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001365 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1366 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001367 go func(a_pAFsm *cmn.AdapterFsm) {
1368 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001369 }(pConfigVlanStateAFsm)
1370 return
1371 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001372 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001373 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001374 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001375 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001376 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001377 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1378 // synchronous FSM 'event/state' functions may rely on this mutex
1379 // but it must be released already before calling getTechProfileDone() as it may already be locked
1380 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1381 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001382 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001383 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001384 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001385 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1386
mpagenko9a304ea2020-12-16 15:54:01 +00001387 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001388 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1389 if aTechProfDone {
1390 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001392 } else {
1393 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001394 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001395 }
1396 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001397 return
1398 }
mpagenkof1d21d12021-06-11 13:14:45 +00001399 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001401 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001402 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1403 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001404 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001405 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001406 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001407 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001408 }
1409}
1410
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001412
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001414 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001415 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001416 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1418 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001419 return
1420 }
mpagenko15ff4a52021-03-02 10:09:20 +00001421 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001424 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001425 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001426
Girish Gowdrae95687a2021-09-08 16:30:58 -07001427 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001428 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001430 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001431 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001432 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1433 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1434 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1435 // 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 +00001436 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001437 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1438 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001439 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001440 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001441 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001442 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001443 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001444 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001445 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001446 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001447
mpagenko01e726e2020-10-23 09:45:29 +00001448 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001449 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1450 oFsm.numVlanFilterEntries = 1
1451 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001452 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001453 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001454 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1455 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1456 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001457 },
1458 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001459 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001460 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1461 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001462 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001463 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001464 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001465 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1466 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001467 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001468 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001469 go func(a_pAFsm *cmn.AdapterFsm) {
1470 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001471 }(pConfigVlanStateAFsm)
1472 }
1473 return
1474 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001475 //accept also nil as (error) return value for writing to LastTx
1476 // - this avoids misinterpretation of new received OMCI messages
1477 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1478 // send shall return (dual format) error code that can be used here for immediate error treatment
1479 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001480 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001481 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001482 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001483 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1484 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001485 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001486
dbainbri4d3a0dc2020-12-02 00:33:42 +00001487 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001488 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001489 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001490 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001491 // setVid is assumed to be masked already by the caller to 12 bit
1492 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001493 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001494 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001495
1496 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1497 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1498 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001499 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001500
1501 oFsm.numVlanFilterEntries++
1502 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001503 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001504 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001505 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1506 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1507 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001508 },
1509 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001510 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001511 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1512 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001513 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001514 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001515 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001516 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1517 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001519 return
1520 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001521 //accept also nil as (error) return value for writing to LastTx
1522 // - this avoids misinterpretation of new received OMCI messages
1523 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1524 // send shall return (dual format) error code that can be used here for immediate error treatment
1525 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001526 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001527 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001528 }
1529 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001531 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001532 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001533 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001534 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001536 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001537 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001538 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001539 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001540 return
1541 }
1542 }
mpagenkof1d21d12021-06-11 13:14:45 +00001543
mpagenkof1fc3862021-02-16 10:09:52 +00001544 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001545 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001546 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001547 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001548 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1549 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001550 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001551 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001552 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001553 //This is correct passing scenario
1554 if errEvto == nil {
1555 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001556 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001557 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001558 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001560 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001561 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001562 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001565 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001566 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001567 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 }
1569 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001570 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001571 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001572 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001573 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1574 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001576 if errCreateTrafficDescriptor != nil {
1577 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1578 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001580 }
1581 }
1582 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001583 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001584 }
1585 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001586}
1587
dbainbri4d3a0dc2020-12-02 00:33:42 +00001588func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001589 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001591 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1592 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001594 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1595 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001596 loVlanEntryClear := uint8(0)
1597 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1598 //shallow copy is sufficient as no reference variables are used within struct
1599 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001600 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001601 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001602 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1603 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1604 "device-id": oFsm.deviceID})
1605
1606 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1607 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001608 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001609 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1610 } else {
1611 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1612 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001613 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001614 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1615 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001616 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001617 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001618 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001620 loVlanEntryClear = 1 //full VlanFilter clear request
1621 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001622 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1624 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001625 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001626 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001627 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1628 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001630 return
1631 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001632 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001633 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001634 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001636 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001637 }
mpagenko01e726e2020-10-23 09:45:29 +00001638 } else {
1639 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1640 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001641 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001642 log.Fields{"current vlan list": oFsm.vlanFilterList,
1643 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1644 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1645 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1646 loVlanEntryRmPos = i
1647 break //abort search
1648 }
1649 }
1650 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001652 //valid entry was found - to be eclipsed
1653 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1654 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1655 if i < loVlanEntryRmPos {
1656 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1657 } else if i < (cVtfdTableSize - 1) {
1658 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1659 } else {
1660 vtfdFilterList[i] = 0 //set last byte if needed
1661 }
1662 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001664 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001665 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001666 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001667
mpagenkofc4f56e2020-11-04 17:17:49 +00001668 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001669 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001670 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001671 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1672 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001673 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001674 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001675 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1676 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001677 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001678 return
1679 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001680 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001681 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001682 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001684 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001685 }
mpagenko01e726e2020-10-23 09:45:29 +00001686 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001688 log.Fields{"device-id": oFsm.deviceID})
1689 }
1690 }
1691 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001692 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1693 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001695 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001696 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001697 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001698 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001700 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001701 }(pConfigVlanStateBaseFsm)
1702 return
1703 }
mpagenko01e726e2020-10-23 09:45:29 +00001704 }
1705
mpagenko15ff4a52021-03-02 10:09:20 +00001706 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001707 if loVlanEntryClear == 1 {
1708 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1709 oFsm.numVlanFilterEntries = 0
1710 } else if loVlanEntryClear == 2 {
1711 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1712 // this loop now includes the 0 element on previous last valid entry
1713 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1714 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1715 }
1716 oFsm.numVlanFilterEntries--
1717 }
mpagenko15ff4a52021-03-02 10:09:20 +00001718 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001719 }
1720 }
1721
mpagenkofc4f56e2020-11-04 17:17:49 +00001722 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001724 } else {
1725 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001727 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001728 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001729 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001730 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001731 }(pConfigVlanStateBaseFsm)
1732 }
mpagenkodff5dda2020-08-28 11:52:01 +00001733}
1734
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001736 var tpID uint8
1737 // Extract the tpID
1738 if len(e.Args) > 0 {
1739 tpID = e.Args[0].(uint8)
1740 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1741 } else {
1742 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1743 }
mpagenko01e726e2020-10-23 09:45:29 +00001744 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001745 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001746
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001747 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001748 if pConfigVlanStateAFsm == nil {
1749 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1750 log.Fields{"device-id": oFsm.deviceID})
1751 //would have to be fixed from outside somehow
1752 return
1753 }
1754
mpagenkof1d21d12021-06-11 13:14:45 +00001755 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1756 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001757 //call from 'configured' state of the rule
1758 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1759 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1760 oFsm.mutexFlowParams.Unlock()
1761 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001762 go func(a_pAFsm *cmn.AdapterFsm) {
1763 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001764 }(pConfigVlanStateAFsm)
1765 return
1766 }
mpagenkof1d21d12021-06-11 13:14:45 +00001767 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1768 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1769 oFsm.mutexFlowParams.Unlock()
1770 removeChannel <- true
1771 oFsm.mutexFlowParams.Lock()
1772 }
1773
mpagenkof1fc3862021-02-16 10:09:52 +00001774 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1775 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1776 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1777
Girish Gowdrae95687a2021-09-08 16:30:58 -07001778 // Store the reference to the flow response channel before this entry in the slice is deleted
1779 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1780
mpagenko01e726e2020-10-23 09:45:29 +00001781 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1782 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001783 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001784 "device-id": oFsm.deviceID})
1785 } else {
1786 //cut off the actual flow by slicing out the first element
1787 oFsm.uniRemoveFlowsSlice = append(
1788 oFsm.uniRemoveFlowsSlice[:0],
1789 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001790 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001791 "device-id": oFsm.deviceID})
1792 }
1793 oFsm.mutexFlowParams.Unlock()
1794
mpagenkof1fc3862021-02-16 10:09:52 +00001795 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001796 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001797 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001798 go func(a_pAFsm *cmn.AdapterFsm) {
1799 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001800 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001801
mpagenkobb47bc22021-04-20 13:29:09 +00001802 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001803 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001804 if deletedCookie == oFsm.delayNewRuleCookie {
1805 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1806 select {
1807 case <-oFsm.chCookieDeleted:
1808 logger.Debug(ctx, "flushed CookieDeleted")
1809 default:
1810 }
1811 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1812 }
mpagenkobb47bc22021-04-20 13:29:09 +00001813 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1814 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1815 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 -08001816 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001817 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1818 oFsm.flowDeleteChannel <- true
1819 oFsm.signalOnFlowDelete = false
1820 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001821 }
mpagenkobb47bc22021-04-20 13:29:09 +00001822 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001823
1824 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001825 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001826}
1827
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1829 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001830
mpagenko0f543222021-11-03 16:24:14 +00001831 oFsm.mutexPLastTxMeInstance.Lock()
1832 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1833 oFsm.mutexPLastTxMeInstance.Unlock()
1834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001836 if pConfigVlanStateAFsm != nil {
1837 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001838 fsmAbortMsg := cmn.Message{
1839 Type: cmn.TestMsg,
1840 Data: cmn.TestMessage{
1841 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001842 },
1843 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001844 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001845
mpagenko0f543222021-11-03 16:24:14 +00001846 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1847 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1848
1849 oFsm.mutexFlowParams.RLock()
1850 if oFsm.delayNewRuleCookie != 0 {
1851 // looks like the waiting AddFlow is stuck
1852 oFsm.mutexFlowParams.RUnlock()
1853 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1854 select {
1855 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1856 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001857 }
mpagenko0f543222021-11-03 16:24:14 +00001858 oFsm.mutexFlowParams.RLock()
1859 }
1860 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1861 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1862 if removeUniFlowParams.isSuspendedOnAdd {
1863 removeChannel := removeUniFlowParams.removeChannel
1864 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1865 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1866 oFsm.mutexFlowParams.RUnlock()
1867 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1868 select {
1869 case removeChannel <- false:
1870 default:
1871 }
1872 oFsm.mutexFlowParams.RLock()
1873 }
1874 // Send response on response channel if the caller is waiting on it.
1875 var err error = nil
1876 if !oFsm.isCanceled {
1877 //only if the FSM is not canceled on external request use some error indication for the respChan
1878 // so only at real internal FSM abortion some error code is sent back
1879 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1880 err = fmt.Errorf("internal-error")
1881 }
1882 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1883 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1884 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1885 }
1886 }
1887
1888 if oFsm.pDeviceHandler != nil {
1889 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1890 if !oFsm.isCanceled {
1891 //if the FSM is not canceled on external request use "internal-error" for the respChan
1892 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1893 // Send response on response channel if the caller is waiting on it with according error indication.
1894 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1895 }
1896 //permanently remove possibly stored persistent data
1897 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1898 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1899 } else {
1900 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1901 // no need to remove specific data in this case here
1902 // TODO: cancelation may also abort a running flowAdd activity in which case it would be better
1903 // to also resopnd on the respChan with some error ("config canceled"), but that is a bit hard to decide here
1904 // so just left open by now
1905 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1906 }
1907 }
1908 oFsm.mutexFlowParams.RUnlock()
1909
1910 //try to let the FSM proceed to 'disabled'
1911 // Can't call FSM Event directly, decoupling it
1912 go func(a_pAFsm *cmn.AdapterFsm) {
1913 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1914 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1915 }
1916 }(pConfigVlanStateAFsm)
1917 return
1918 }
1919 oFsm.mutexFlowParams.RUnlock()
1920 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1921 log.Fields{"device-id": oFsm.deviceID})
1922 return
mpagenkodff5dda2020-08-28 11:52:01 +00001923 }
mpagenko0f543222021-11-03 16:24:14 +00001924 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1925 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001926}
1927
dbainbri4d3a0dc2020-12-02 00:33:42 +00001928func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1929 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001930
mpagenkodff5dda2020-08-28 11:52:01 +00001931 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001932 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001934 return
mpagenkodff5dda2020-08-28 11:52:01 +00001935 }
mpagenko0f543222021-11-03 16:24:14 +00001936 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1937 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001938}
1939
dbainbri4d3a0dc2020-12-02 00:33:42 +00001940func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1941 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001942loop:
1943 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001944 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001946 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301948 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001949 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301950 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301952 break loop
1953 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301955
1956 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001957 case cmn.TestMsg:
1958 msg, _ := message.Data.(cmn.TestMessage)
1959 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001961 break loop
1962 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001964 case cmn.OMCI:
1965 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001966 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301967 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301969 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001970 }
1971 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001973}
1974
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001975func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001977 "msgType": msg.OmciMsg.MessageType})
1978
1979 switch msg.OmciMsg.MessageType {
1980 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001981 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00001983 logger.Warnw(ctx, "CreateResponse handling aborted",
1984 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001985 return
1986 }
mpagenkodff5dda2020-08-28 11:52:01 +00001987 } //CreateResponseType
1988 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001989 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001990 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1991 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001992 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001993 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001994 return
1995 }
1996 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1997 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001999 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002000 return
2001 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002003 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002004 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002005 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002006 // possibly force FSM into abort or ignore some errors for some messages?
2007 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2008 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002009 return
2010 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002011 oFsm.mutexPLastTxMeInstance.RLock()
2012 if oFsm.pLastTxMeInstance != nil {
2013 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2014 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2015 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002016 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002017 { // let the MultiEntity config proceed by stopping the wait function
2018 oFsm.mutexPLastTxMeInstance.RUnlock()
2019 oFsm.omciMIdsResponseReceived <- true
2020 return
2021 }
2022 default:
2023 {
2024 logger.Warnw(ctx, "Unsupported ME name received!",
2025 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2026 }
mpagenkodff5dda2020-08-28 11:52:01 +00002027 }
2028 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002029 } else {
2030 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002031 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002032 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002033 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002034 case omci.DeleteResponseType:
2035 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002037 logger.Warnw(ctx, "DeleteResponse handling aborted",
2038 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002039 return
2040 }
2041 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002042 default:
2043 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002044 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002045 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002046 return
2047 }
2048 }
2049}
2050
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002052 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2053 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002055 log.Fields{"device-id": oFsm.deviceID})
2056 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2057 oFsm.deviceID)
2058 }
2059 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2060 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002062 log.Fields{"device-id": oFsm.deviceID})
2063 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2064 oFsm.deviceID)
2065 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002067 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002069 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002070 // possibly force FSM into abort or ignore some errors for some messages?
2071 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2072 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002073 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2074 oFsm.deviceID)
2075 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002076 oFsm.mutexPLastTxMeInstance.RLock()
2077 if oFsm.pLastTxMeInstance != nil {
2078 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2079 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2080 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2081 switch oFsm.pLastTxMeInstance.GetName() {
2082 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2083 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002084 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002085 {
2086 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002087 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002088 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002089 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002090 } else { // let the MultiEntity config proceed by stopping the wait function
2091 oFsm.omciMIdsResponseReceived <- true
2092 }
2093 return nil
2094 }
2095 default:
2096 {
2097 logger.Warnw(ctx, "Unsupported ME name received!",
2098 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002099 }
2100 }
2101 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002102 } else {
2103 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002104 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002105 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002106 return nil
2107}
2108
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002110 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2111 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002113 log.Fields{"device-id": oFsm.deviceID})
2114 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2115 oFsm.deviceID)
2116 }
2117 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2118 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002120 log.Fields{"device-id": oFsm.deviceID})
2121 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2122 oFsm.deviceID)
2123 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002125 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002127 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002128 // possibly force FSM into abort or ignore some errors for some messages?
2129 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2130 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002131 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2132 oFsm.deviceID)
2133 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002134 oFsm.mutexPLastTxMeInstance.RLock()
2135 if oFsm.pLastTxMeInstance != nil {
2136 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2137 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2138 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002139 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002140 { // let the MultiEntity config proceed by stopping the wait function
2141 oFsm.mutexPLastTxMeInstance.RUnlock()
2142 oFsm.omciMIdsResponseReceived <- true
2143 return nil
2144 }
2145 default:
2146 {
2147 logger.Warnw(ctx, "Unsupported ME name received!",
2148 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2149 }
mpagenko01e726e2020-10-23 09:45:29 +00002150 }
2151 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002152 } else {
2153 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002154 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002155 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002156 return nil
2157}
2158
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002160 oFsm.mutexFlowParams.RLock()
2161 evtocdID := oFsm.evtocdID
2162 oFsm.mutexFlowParams.RUnlock()
2163
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002164 if aFlowEntryNo == 0 {
2165 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002166 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2167 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002168 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002169 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002170 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002171 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002172 associationType := 2 // default to UniPPTP
2173 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002174 associationType = 10
2175 }
2176 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002177 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002178 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002179 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002180 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2181 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002182 },
2183 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002184 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002185 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2186 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002187 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002188 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002189 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2190 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002191 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002192 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2193 }
mpagenkodff5dda2020-08-28 11:52:01 +00002194 //accept also nil as (error) return value for writing to LastTx
2195 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002196 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002197 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002198
2199 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002200 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002201 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002203 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002204 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002205 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2206 }
2207
2208 // Set the EVTOCD ME default params
2209 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002210 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002211 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002212 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2213 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2214 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002215 },
2216 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002217 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2219 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2220 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002221 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002222 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002223 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2224 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002225 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002226 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2227 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 //accept also nil as (error) return value for writing to LastTx
2229 // - this avoids misinterpretation of new received OMCI messages
2230 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002231 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002232
2233 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002235 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002236 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002237 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002238 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002239 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002240 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002241 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002242
mpagenko551a4d42020-12-08 18:09:20 +00002243 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302244 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2245 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002246 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002247 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002248 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002249 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002250 sliceEvtocdRule := make([]uint8, 16)
2251 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2252 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2253 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2254 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2255 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2256
2257 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2258 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2259 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2260 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2261 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2262
2263 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2264 0<<cTreatTTROffset| // Do not pop any tags
2265 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2266 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2267 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2268
2269 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2270 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2271 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2272 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2273
2274 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002275 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002276 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002277 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002278 },
2279 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002280 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2282 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2283 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002284 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002285 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002286 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2287 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002289 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2290 }
mpagenkodff5dda2020-08-28 11:52:01 +00002291 //accept also nil as (error) return value for writing to LastTx
2292 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002293 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002294 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002295
2296 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002297 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002298 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002299 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002300 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002301 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002302 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2303
mpagenkodff5dda2020-08-28 11:52:01 +00002304 }
2305 } else {
2306 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2307 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002308 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2309 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2310 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2311 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302312 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002313 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002314
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302315 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2316 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2317 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
2318 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
2319 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2320 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2321 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2322 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2323 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002324
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302325 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2326 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2327 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2328 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2329 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002330
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302331 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2332 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2333 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2334 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2335 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2336
2337 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2338 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2339 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2340 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2341
2342 } else {
2343 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2344 //As of now only a match and no action can be done on the inner tag .
2345 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2346 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2347 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2348 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2349 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2350 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2351 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2352
2353 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2354 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2355 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2356 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2357 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2358
2359 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2360 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2361 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2362 setVid<<cTreatVidOffset| // Set VID
2363 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2364
2365 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2366 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2367 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2368 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2369 }
mpagenko551a4d42020-12-08 18:09:20 +00002370 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002371 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002372 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002373 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002374 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002375 },
2376 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002377 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2379 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2380 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002381 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002382 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002383 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2384 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002385 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002386 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2387 }
mpagenkodff5dda2020-08-28 11:52:01 +00002388 //accept also nil as (error) return value for writing to LastTx
2389 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002390 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002391 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002392
2393 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002394 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002395 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302396 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002397 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002398 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302399 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002400 }
2401 } else {
2402 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2403 { // just for local var's
2404 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002406 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002407 sliceEvtocdRule := make([]uint8, 16)
2408 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2409 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2410 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2411 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2412 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2413
2414 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2415 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2416 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2417 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2418 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2419
2420 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2421 0<<cTreatTTROffset| // Do not pop any tags
2422 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2423 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2424 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2425
2426 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2427 0<<cTreatPrioOffset| // vlan prio set to 0
2428 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002429 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002430 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2431
mpagenko551a4d42020-12-08 18:09:20 +00002432 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002433 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002434 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002435 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002436 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002437 },
2438 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002439 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002440 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2441 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2442 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002443 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002444 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002445 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2446 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002448 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2449 }
mpagenkodff5dda2020-08-28 11:52:01 +00002450 //accept also nil as (error) return value for writing to LastTx
2451 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002452 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002453 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002454
2455 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002456 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002457 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002458 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002459 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002460 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002461 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2462
mpagenkodff5dda2020-08-28 11:52:01 +00002463 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002464 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002465 { // just for local var's
2466 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002467 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002468 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002469 sliceEvtocdRule := make([]uint8, 16)
2470 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2471 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2472 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2473 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2474 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2475
2476 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2477 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2478 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2479 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2480 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2481
2482 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2483 1<<cTreatTTROffset| // pop the prio-tag
2484 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2485 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2486 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2487
mpagenko551a4d42020-12-08 18:09:20 +00002488 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002489 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2490 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2491 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002492 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002493 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002494 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002495
2496 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002497 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002498 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002499 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002500 },
2501 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002502 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2504 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2505 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002506 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002507 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002508 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2509 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002510 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002511 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2512 }
mpagenkodff5dda2020-08-28 11:52:01 +00002513 //accept also nil as (error) return value for writing to LastTx
2514 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002515 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002516 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002517
2518 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002519 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002520 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002522 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002523 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002524 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2525
mpagenkodff5dda2020-08-28 11:52:01 +00002526 }
2527 } //just for local var's
2528 }
2529 }
2530
mpagenkofc4f56e2020-11-04 17:17:49 +00002531 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002532 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002533 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002534 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002535 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002536 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002537}
2538
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002539func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002540 oFsm.mutexFlowParams.RLock()
2541 evtocdID := oFsm.evtocdID
2542 oFsm.mutexFlowParams.RUnlock()
2543
mpagenko01e726e2020-10-23 09:45:29 +00002544 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2545 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2546 //transparent transmission was set
2547 //perhaps the config is not needed for removal,
2548 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002550 "device-id": oFsm.deviceID})
2551 sliceEvtocdRule := make([]uint8, 16)
2552 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2553 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2554 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2555 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2556 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2557
2558 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2559 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2560 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2561 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2562 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2563
2564 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2565 0<<cTreatTTROffset| // Do not pop any tags
2566 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2567 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2568 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2569
2570 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2571 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2572 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2573 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2574
2575 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002576 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002577 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002578 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002579 },
2580 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002581 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2583 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2584 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002585 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002586 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002587 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2588 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002589 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002590 return
2591 }
mpagenko01e726e2020-10-23 09:45:29 +00002592 //accept also nil as (error) return value for writing to LastTx
2593 // - this avoids misinterpretation of new received OMCI messages
2594 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002595 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002596
2597 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002598 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002599 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002600 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002601 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002602 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002603 return
2604 }
2605 } else {
2606 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002607 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002608 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002609 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002610 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302611 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002612
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302613 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2614 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2615 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2616 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2617 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2618 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2619 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2620 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002621
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302622 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2623 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2624 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2625 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2626 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002627
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302628 // delete indication for the indicated Filter
2629 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2630 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2631
2632 } else {
2633 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2634 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2635 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
2636 sliceEvtocdRule := make([]uint8, 16)
2637 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2638 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2639 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2640 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2641 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2642
2643 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2644 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2645 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2646 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2647 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2648
2649 // delete indication for the indicated Filter
2650 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2651 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2652 }
mpagenko01e726e2020-10-23 09:45:29 +00002653 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002654 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002655 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002656 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002657 },
2658 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002659 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002660 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2661 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2662 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002663 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002664 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002665 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2666 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002667 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002668 return
2669 }
mpagenko01e726e2020-10-23 09:45:29 +00002670 //accept also nil as (error) return value for writing to LastTx
2671 // - this avoids misinterpretation of new received OMCI messages
2672 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002673 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002674
2675 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002676 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002677 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302678 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2679 log.Fields{"device-id": oFsm.deviceID,
2680 "match-vlan": aRuleParams.MatchVid,
2681 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002682 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002683 return
2684 }
2685 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002686 // VOL-3685
2687 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2688 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2689 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2690 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2691 // later when the flow is being re-installed.
2692 // Of course this is applicable to case only where single service (or single tcont) is in use and
2693 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2694 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2695 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002696 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002697 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002698 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002699 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2700 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002701 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002702 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002703 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002704 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2706 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2707 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002708 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002709 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002710 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2711 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002712 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002713 return
2714 }
mpagenko01e726e2020-10-23 09:45:29 +00002715 //accept also nil as (error) return value for writing to LastTx
2716 // - this avoids misinterpretation of new received OMCI messages
2717 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002718 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002719
2720 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002721 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002722 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002724 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002726 return
2727 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002728 } else {
2729 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2730 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002731 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002732 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002733 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002734 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2735 { // just for local var's
2736 // this defines stacking scenario: untagged->singletagged
2737 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2738 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2739 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2740 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002741 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002742 "device-id": oFsm.deviceID})
2743 sliceEvtocdRule := make([]uint8, 16)
2744 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2745 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2746 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2747 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2748 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002749
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002750 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2751 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2752 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2753 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2754 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002755
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002756 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2757 0<<cTreatTTROffset| // Do not pop any tags
2758 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2759 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2760 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002761
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002762 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2763 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2764 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2765 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002766
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002767 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002768 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002769 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002770 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002771 },
2772 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002773 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2775 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2776 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002777 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002778 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002779 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2780 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002781 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002782 return
2783 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002784 //accept also nil as (error) return value for writing to LastTx
2785 // - this avoids misinterpretation of new received OMCI messages
2786 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002787 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002788
2789 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002790 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002791 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002792 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002793 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002794 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002795 return
2796 }
2797 } // just for local var's
2798 { // just for local var's
2799 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002801 "device-id": oFsm.deviceID})
2802 sliceEvtocdRule := make([]uint8, 16)
2803 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2804 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2805 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2806 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2807 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2808
2809 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2810 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2811 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2812 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2813 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2814
2815 // delete indication for the indicated Filter
2816 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2817 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2818
2819 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002820 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002821 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002822 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002823 },
2824 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002825 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2827 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2828 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002829 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002830 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002831 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2832 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002834 return
2835 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002836 //accept also nil as (error) return value for writing to LastTx
2837 // - this avoids misinterpretation of new received OMCI messages
2838 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002839 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002840
2841 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002842 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002844 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002847 return
2848 }
mpagenko01e726e2020-10-23 09:45:29 +00002849 }
2850 } //just for local var's
2851 }
2852 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002853 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002854 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002856}
2857
dbainbri4d3a0dc2020-12-02 00:33:42 +00002858func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002859 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002860 if oFsm.isCanceled {
2861 // FSM already canceled before entering wait
2862 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2863 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002864 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002865 }
mpagenko7d6bb022021-03-11 15:07:55 +00002866 oFsm.isAwaitingResponse = true
2867 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002868 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302869 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002870 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002871 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002872 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002873 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002874 oFsm.mutexIsAwaitingResponse.Lock()
2875 oFsm.isAwaitingResponse = false
2876 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002877 oFsm.mutexPLastTxMeInstance.RLock()
2878 if oFsm.pLastTxMeInstance != nil {
2879 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2880 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2881 }
2882 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002883 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002884 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302885 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002886 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", 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()
mpagenkodff5dda2020-08-28 11:52:01 +00002890 return nil
2891 }
mpagenko7d6bb022021-03-11 15:07:55 +00002892 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002893 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002894 oFsm.mutexIsAwaitingResponse.Lock()
2895 oFsm.isAwaitingResponse = false
2896 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002897 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002898 }
2899}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002900
mpagenko551a4d42020-12-08 18:09:20 +00002901func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002902 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002903 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002904 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002905 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002906 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002907 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002908 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002909 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2910 }
2911
dbainbri4d3a0dc2020-12-02 00:33:42 +00002912 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002913 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002914 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002915 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002917 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2918 }
2919
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002921 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002923 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2926 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002928 if errMacBpCdEID != nil {
2929 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2930 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002931 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002932 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002933
Mahir Gunyel6781f962021-05-16 23:30:08 -07002934 }
2935 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002936 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2937 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002939 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002940 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002941 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2942 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2943 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2944 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002945 },
2946 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002947 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002948 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2949 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002950 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002951 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002952 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2953 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002954 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002955 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2956 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002957 //accept also nil as (error) return value for writing to LastTx
2958 // - this avoids misinterpretation of new received OMCI messages
2959 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002960 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002961 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002962 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002963 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2965 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002966 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2967 }
2968
2969 // ==> Start creating VTFD for mcast vlan
2970
2971 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2972 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002973 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002974
dbainbri4d3a0dc2020-12-02 00:33:42 +00002975 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002976 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002977 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002978 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2979
2980 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2981 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2982 // new vlan associated with a different TP.
2983 vtfdFilterList[0] = uint16(vlanID)
2984
2985 meParams = me.ParamData{
2986 EntityID: mcastVtfdID,
2987 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002988 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
2989 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
2990 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002991 },
2992 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002993 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002994 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2995 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002996 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002997 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002998 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2999 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003000 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003001 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3002 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003003 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003004 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003005 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003006 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003007 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003008 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003009 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003010 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3011 }
3012
3013 return nil
3014}
3015
dbainbri4d3a0dc2020-12-02 00:33:42 +00003016func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003018 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003019 logger.Errorw(ctx, "error generrating me instance id",
3020 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003021 return err
3022 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003023 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3024 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003025 meParams := me.ParamData{
3026 EntityID: instID,
3027 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003028 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003029 //Direct reference to the Operation profile
3030 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003031 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003032 },
3033 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003034 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003035 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3036 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3037 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003038 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003039 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003040 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3041 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003042 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003043 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3044 oFsm.deviceID, err)
3045 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003046 //accept also nil as (error) return value for writing to LastTx
3047 // - this avoids misinterpretation of new received OMCI messages
3048 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003049 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003050 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003051 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003052 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003053 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003054 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3055 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3056 }
3057 return nil
3058}
3059
dbainbri4d3a0dc2020-12-02 00:33:42 +00003060func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003061 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003062 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003063 logger.Errorw(ctx, "error generating me instance id",
3064 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003065 return err
3066 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003067 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3068 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003069 meParams := me.ParamData{
3070 EntityID: instID,
3071 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003072 me.MulticastOperationsProfile_IgmpVersion: 2,
3073 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003074 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003075 me.MulticastOperationsProfile_ImmediateLeave: 0,
3076 me.MulticastOperationsProfile_Robustness: 2,
3077 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3078 me.MulticastOperationsProfile_QueryInterval: 125,
3079 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3080 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003081 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003082 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003083 },
3084 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003085 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3087 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3088 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003089 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003090 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003091 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3092 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003093 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003094 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3095 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003096 //accept also nil as (error) return value for writing to LastTx
3097 // - this avoids misinterpretation of new received OMCI messages
3098 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003099 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003100 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003101 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003102 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003103 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003104 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003105 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003106 }
3107 return nil
3108}
3109
dbainbri4d3a0dc2020-12-02 00:33:42 +00003110func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003111 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003112 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003113 logger.Errorw(ctx, "error generating me instance id",
3114 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003115 return err
3116 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003117 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3118 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003119 //TODO check that this is correct
3120 // Table control
3121 //setCtrl = 1
3122 //rowPartId = 0
3123 //test = 0
3124 //rowKey = 0
3125 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003126 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003127 dynamicAccessCL := make([]uint8, 24)
3128 copy(dynamicAccessCL, tableCtrl)
3129 //Multicast GemPortId
3130 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3131 // python version waits for installation of flows, see line 723 onward of
3132 // brcm_openomci_onu_handler.py
3133 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3134 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003135 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003136 //TODO start and end are hardcoded, get from TP
3137 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003139 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003140 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003141 //imputed group bandwidth
3142 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3143
3144 meParams := me.ParamData{
3145 EntityID: instID,
3146 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003147 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003148 },
3149 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003150 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3152 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3153 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003154 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003155 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003156 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3157 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003158 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003159 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3160 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003161 //accept also nil as (error) return value for writing to LastTx
3162 // - this avoids misinterpretation of new received OMCI messages
3163 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003164 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003165 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003166 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003167 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003168 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003169 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003170 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003171 }
3172 return nil
3173}
Girish Gowdra26a40922021-01-29 17:14:34 -08003174
khenaidoo42dcdfd2021-10-19 17:34:12 -04003175func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003176 tpID uint8, uniID uint8, gemPortID uint16) error {
3177 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3178 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3179 // I created unique TD ID by flow direction.
3180 // TODO! Traffic descriptor ME ID will check
3181 trafficDescriptorID := gemPortID
3182 if aMeter == nil {
3183 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3184 }
3185 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3186 if err != nil {
3187 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3188 return err
3189 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003190 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003191 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003192 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003193 pbs := trafficShapingInfo.Pbs
3194
3195 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3196 meParams := me.ParamData{
3197 EntityID: trafficDescriptorID,
3198 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003199 me.TrafficDescriptor_Cir: cir,
3200 me.TrafficDescriptor_Pir: pir,
3201 me.TrafficDescriptor_Cbs: cbs,
3202 me.TrafficDescriptor_Pbs: pbs,
3203 me.TrafficDescriptor_ColourMode: 1,
3204 me.TrafficDescriptor_IngressColourMarking: 3,
3205 me.TrafficDescriptor_EgressColourMarking: 3,
3206 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003207 },
3208 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003209 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003210 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3211 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003212 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003213 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003214 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3215 return err
3216 }
3217 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003218 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003219 err = oFsm.waitforOmciResponse(ctx)
3220 if err != nil {
3221 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3222 return err
3223 }
3224
Girish Gowdra09e5f212021-09-30 16:28:36 -07003225 // 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
3226 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003227 if err != nil {
3228 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3229 return err
3230 }
3231 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3232
3233 return nil
3234}
3235
Girish Gowdra09e5f212021-09-30 16:28:36 -07003236func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3237 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3238 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003239 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003240 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003241 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003242 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003243 },
3244 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003245 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003246 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3247 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003248 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003249 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003250 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3251 return err
3252 }
3253 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003254 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003255 err = oFsm.waitforOmciResponse(ctx)
3256 if err != nil {
3257 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3258 return err
3259 }
3260 return nil
3261}
3262
Girish Gowdra26a40922021-01-29 17:14:34 -08003263// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003264func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3265 if oFsm == nil {
3266 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3267 return false
3268 }
mpagenkobb47bc22021-04-20 13:29:09 +00003269 oFsm.mutexFlowParams.Lock()
3270 defer oFsm.mutexFlowParams.Unlock()
3271 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3272 //flow removal is still ongoing/pending
3273 oFsm.signalOnFlowDelete = true
3274 oFsm.flowDeleteChannel = aFlowDeleteChannel
3275 return true
3276 }
3277 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003278}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003279
3280func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3281 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3282 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3283 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3284 log.Fields{"device-id": oFsm.deviceID})
3285 } else {
3286 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3287 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3288 "index": oFsm.numVlanFilterEntries,
3289 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3290 "device-id": oFsm.deviceID})
3291 oFsm.numVlanFilterEntries++
3292 }
3293}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003294
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003295// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3296func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003297 if respChan != nil {
3298 // 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
3299 select {
3300 case *respChan <- err:
3301 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3302 default:
3303 }
3304 }
3305}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003306
3307// PrepareForGarbageCollection - remove references to prepare for garbage collection
3308func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3309 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3310 oFsm.pDeviceHandler = nil
3311 oFsm.pOnuDeviceEntry = nil
3312 oFsm.pOmciCC = nil
3313}