blob: 4a690f7f35a59edcc45387f2a6e7fb8bc105f348 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
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"
31 "github.com/opencord/voltha-protos/v5/go/voltha"
ozgecanetsia82b91a62021-05-21 18:54:49 +030032
mpagenko01e726e2020-10-23 09:45:29 +000033 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000034 "github.com/looplab/fsm"
35 "github.com/opencord/omci-lib-go"
36 me "github.com/opencord/omci-lib-go/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040037 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
39 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
khenaidoo7d3c5582021-08-11 18:09:44 -040040 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000041)
42
43const (
44 // internal predefined values
45 cDefaultDownstreamMode = 0
46 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000047 cVtfdTableSize = 12 //as per G.988
48 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000049)
50
51const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000052 // internal offsets for requestEvent according to definition in onu_device_entry::cmn.OnuDeviceEvent
mpagenkof1fc3862021-02-16 10:09:52 +000053 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000054 cDeviceEventOffsetAddNoKvStore = cmn.OmciVlanFilterAddDoneNoKvStore - cmn.OmciVlanFilterAddDone
55 cDeviceEventOffsetRemoveWithKvStore = cmn.OmciVlanFilterRemDone - cmn.OmciVlanFilterAddDone
56 cDeviceEventOffsetRemoveNoKvStore = cmn.OmciVlanFilterRemDoneNoKvStore - cmn.OmciVlanFilterAddDone
mpagenkof1fc3862021-02-16 10:09:52 +000057)
58
59const (
mpagenkodff5dda2020-08-28 11:52:01 +000060 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
61 cFilterPrioOffset = 28
62 cFilterVidOffset = 15
63 cFilterTpidOffset = 12
64 cFilterEtherTypeOffset = 0
65 cTreatTTROffset = 30
66 cTreatPrioOffset = 16
67 cTreatVidOffset = 3
68 cTreatTpidOffset = 0
69)
70const (
71 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
72 cFilterOuterOffset = 0
73 cFilterInnerOffset = 4
74 cTreatOuterOffset = 8
75 cTreatInnerOffset = 12
76)
77const (
78 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
79 cPrioIgnoreTag uint32 = 15
80 cPrioDefaultFilter uint32 = 14
81 cPrioDoNotFilter uint32 = 8
82 cDoNotFilterVid uint32 = 4096
83 cDoNotFilterTPID uint32 = 0
84 cDoNotFilterEtherType uint32 = 0
85 cDoNotAddPrio uint32 = 15
86 cCopyPrioFromInner uint32 = 8
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
mpagenko01e726e2020-10-23 09:45:29 +0000143}
144
mpagenkobb47bc22021-04-20 13:29:09 +0000145//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
146// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000147type UniVlanConfigFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000148 pDeviceHandler cmn.IdeviceHandler
149 pOnuDeviceEntry cmn.IonuDeviceEntry
mpagenko01e726e2020-10-23 09:45:29 +0000150 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000151 pOmciCC *cmn.OmciCC
152 pOnuUniPort *cmn.OnuUniPort
153 pUniTechProf *OnuUniTechProf
154 pOnuDB *devdb.OnuDeviceDB
155 requestEvent cmn.OnuDeviceEvent
mpagenkodff5dda2020-08-28 11:52:01 +0000156 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000157 PAdaptFsm *cmn.AdapterFsm
mpagenkodff5dda2020-08-28 11:52:01 +0000158 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000159 clearPersistency 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
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000165 actualUniVlanConfigRule cmn.UniVlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300166 actualUniVlanConfigMeter *voltha.OfpMeterConfig
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000167 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000168 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000169 NumUniFlows uint8 // expected number of flows should be less than 12
170 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000171 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000173 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000174 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000175 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000176 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000177 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000178 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000179 signalOnFlowDelete bool
180 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000181 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
182 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200183 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
184 // thus notification needs to be sent on chan.
185 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000186}
187
mpagenko01e726e2020-10-23 09:45:29 +0000188//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
189// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000190func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
191 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
192 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300193 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000194 instFsm := &UniVlanConfigFsm{
195 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000196 pOnuDeviceEntry: apOnuDeviceEntry,
197 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000198 pOmciCC: apDevOmciCC,
199 pOnuUniPort: apUniPort,
200 pUniTechProf: apUniTechProf,
201 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000202 requestEvent: aRequestEvent,
203 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000204 NumUniFlows: 0,
205 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000206 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000207 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200208 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000209 }
210
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000211 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
212 if instFsm.PAdaptFsm == nil {
213 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000214 "device-id": instFsm.deviceID})
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})
mpagenkodff5dda2020-08-28 11:52:01 +0000271 return nil
272 }
273
ozgecanetsia82b91a62021-05-21 18:54:49 +0300274 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000275
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000277 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000278 return instFsm
279}
280
mpagenko01e726e2020-10-23 09:45:29 +0000281//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000282func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300283 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000284 loRuleParams := cmn.UniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000285 TpID: aTpID,
286 MatchVid: uint32(aMatchVlan),
287 SetVid: uint32(aSetVlan),
288 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000289 }
290 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000291 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
292 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000293
mpagenko01e726e2020-10-23 09:45:29 +0000294 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000295 //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 +0000296 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
298 } else {
299 if !oFsm.acceptIncrementalEvtoOption {
300 //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 +0000301 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000302 }
303 }
304
mpagenko01e726e2020-10-23 09:45:29 +0000305 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000306 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000307 loRuleParams.TagsToRemove = 0 //no tag pop action
308 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
309 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
311 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
312 // might collide with NoMatchVid/CopyPrio(/setVid) setting
313 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000314 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000315 }
316 }
mpagenko01e726e2020-10-23 09:45:29 +0000317
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000318 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams}
mpagenko01e726e2020-10-23 09:45:29 +0000319 loFlowParams.CookieSlice = make([]uint64, 0)
320 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300321 if aMeter != nil {
322 loFlowParams.Meter = aMeter
323 }
mpagenko01e726e2020-10-23 09:45:29 +0000324
325 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000326 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000327 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000329 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
330 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
331 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
332 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000333 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000334
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000336 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
337 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000338 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000339 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
340
341 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000342 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000343 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000344 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000345 return err
346 }
347
348 return nil
349}
350
mpagenko7d6bb022021-03-11 15:07:55 +0000351//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000352func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000353 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000354 oFsm.mutexIsAwaitingResponse.Lock()
355 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000356 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000357 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
358 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
359 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000360 //use channel to indicate that the response waiting shall be aborted
361 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000362 } else {
363 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000364 }
mpagenkocf48e452021-04-23 09:23:00 +0000365
mpagenko7d6bb022021-03-11 15:07:55 +0000366 // 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 +0000367 PAdaptFsm := oFsm.PAdaptFsm
368 if PAdaptFsm != nil {
369 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000370 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000371 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000372 }
mpagenko7d6bb022021-03-11 15:07:55 +0000373 }
374}
375
mpagenko551a4d42020-12-08 18:09:20 +0000376//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
377func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
378 //mutex protection is required for possible concurrent access to FSM members
379 oFsm.mutexFlowParams.RLock()
380 defer oFsm.mutexFlowParams.RUnlock()
381 return oFsm.TpIDWaitingFor
382}
383
mpagenko2418ab02020-11-12 12:58:06 +0000384//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
385func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
386 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000387 oFsm.mutexFlowParams.Lock()
388 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000389 oFsm.clearPersistency = aClear
390}
391
mpagenko01e726e2020-10-23 09:45:29 +0000392//SetUniFlowParams verifies on existence of flow parameters to be configured,
393// optionally udates the cookie list or appends a new flow if there is space
394// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000395// ignore complexity by now
396// nolint: gocyclo
397func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300398 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000399 loRuleParams := cmn.UniVlanRuleParams{
mpagenko01e726e2020-10-23 09:45:29 +0000400 TpID: aTpID,
401 MatchVid: uint32(aMatchVlan),
402 SetVid: uint32(aSetVlan),
403 SetPcp: uint32(aSetPcp),
404 }
405 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
406 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
407 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000408 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
409 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
410 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
411 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
412 } else {
413 if !oFsm.acceptIncrementalEvtoOption {
414 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
415 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
416 }
417 }
418
419 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
420 // no prio/vid filtering requested
421 loRuleParams.TagsToRemove = 0 //no tag pop action
422 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
423 if loRuleParams.SetPcp == cCopyPrioFromInner {
424 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
425 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
426 // might collide with NoMatchVid/CopyPrio(/setVid) setting
427 // this was some precondition setting taken over from py adapter ..
428 loRuleParams.SetPcp = 0
429 }
430 }
431
mpagenkof1d21d12021-06-11 13:14:45 +0000432 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
433 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
434 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
435 oFsm.mutexFlowParams.RLock()
436 if len(oFsm.uniRemoveFlowsSlice) > 0 {
437 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
438 if removeUniFlowParams.vlanRuleParams == loRuleParams {
439 // the flow to add is the same as the one already in progress of deleting
440 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000441 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
442 if flow >= len(oFsm.uniRemoveFlowsSlice) {
443 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
444 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
445 oFsm.mutexFlowParams.RUnlock()
446 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
447 }
mpagenkof1d21d12021-06-11 13:14:45 +0000448 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
449 oFsm.mutexFlowParams.RUnlock()
450 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
451 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
452 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
453 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
454 }
455 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000456 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000457 }
458 }
459 }
460 oFsm.mutexFlowParams.RUnlock()
461
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000462 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000463 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000464 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200465 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000466 //mutex protection is required for possible concurrent access to FSM members
467 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000468 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
469 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
470 // countable run time optimization (perhaps with including the hash in kvStore storage?)
471 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000472 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000473 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300474 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
475 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
476 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000477 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000478 var cookieMatch bool
479 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
480 cookieMatch = false
481 for _, cookie := range storedUniFlowParams.CookieSlice {
482 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000483 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000484 "device-id": oFsm.deviceID, "cookie": cookie})
485 cookieMatch = true
486 break //found new cookie - no further search for this requested cookie
487 }
488 }
489 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000490 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
491 if delayedCookie != 0 {
492 //a delay for adding the cookie to this rule is requested
493 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
494 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000495 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
496 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
497 "device-id": oFsm.deviceID, "cookie": delayedCookie})
498 return fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
499 }
mpagenkobc4170a2021-08-17 16:42:10 +0000500 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000501 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000502 } else {
503 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
504 "device-id": oFsm.deviceID, "cookie": newCookie})
505 //as range works with copies of the slice we have to write to the original slice!!
506 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
507 newCookie)
508 flowCookieModify = true
509 }
mpagenko01e726e2020-10-23 09:45:29 +0000510 }
511 } //for all new cookies
512 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000513 }
514 }
mpagenkof1fc3862021-02-16 10:09:52 +0000515 oFsm.mutexFlowParams.Unlock()
516
517 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000518 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
519 if !deleteSuccess {
520 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
521 "device-id": oFsm.deviceID, "cookie": delayedCookie})
522 return fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
523 }
mpagenkof1fc3862021-02-16 10:09:52 +0000524 requestAppendRule = true //default assumption here is that rule is to be appended
525 flowCookieModify = true //and that the the flow data base is to be updated
526 if delayedCookie != 0 { //it was suspended
527 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
528 }
529 }
530 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
531 if requestAppendRule {
532 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000533 if oFsm.NumUniFlows < cMaxAllowedFlows {
534 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams}
mpagenko01e726e2020-10-23 09:45:29 +0000535 loFlowParams.CookieSlice = make([]uint64, 0)
536 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300537 if aMeter != nil {
538 loFlowParams.Meter = aMeter
539 }
mpagenko01e726e2020-10-23 09:45:29 +0000540 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000541 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000542 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000543 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
544 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000545 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
546 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000547
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000548 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000549 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
550 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000551 oFsm.NumUniFlows++
552 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000553
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000554 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000555 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000556 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000557 //attention: take care to release the mutexFlowParams when calling the FSM directly -
558 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000559 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
561 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000562 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000564 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000565 }
566 return nil
567 }
mpagenko01e726e2020-10-23 09:45:29 +0000568 // note: theoretical it would be possible to clear the same rule from the remove slice
569 // (for entries that have not yet been started with removal)
570 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
571 // 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 +0000572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000574 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000576 // this is a restart with a complete new flow, we can re-use the initial flow config control
577 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000578 //attention: take care to release the mutexFlowParams when calling the FSM directly -
579 // synchronous FSM 'event/state' functions may rely on this mutex
580 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000582 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
583 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
584 }
mpagenko551a4d42020-12-08 18:09:20 +0000585 } else {
586 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000587 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000589 //check introduced after having observed some panic here
590 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000591 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000592 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
593 oFsm.mutexFlowParams.Unlock()
594 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
595 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow].VlanRuleParams
597 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +0000598 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000599 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000600 oFsm.TpIDWaitingFor = tpID
mpagenko45cc6a32021-07-23 10:06:57 +0000601 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000602 //attention: take care to release the mutexFlowParams when calling the FSM directly -
603 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000604 // but it must be released already before calling getTechProfileDone() as it may already be locked
605 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000606 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000607 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000608 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000610 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
611
mpagenkobb47bc22021-04-20 13:29:09 +0000612 var fsmErr error
613 if loTechProfDone {
614 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000615 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000616 } else {
617 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000618 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000619 }
620 if fsmErr != nil {
621 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
622 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
623 }
mpagenko551a4d42020-12-08 18:09:20 +0000624 }
mpagenkobb47bc22021-04-20 13:29:09 +0000625 } else {
626 // if not in the appropriate state a new entry will be automatically considered later
627 // when the configDone state is reached
628 oFsm.mutexFlowParams.Unlock()
629 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000630 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000631 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000633 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000634 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
635 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000636 } else {
637 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000638 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000639 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000641 //all requested rules really have been configured
642 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000643 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000644 if oFsm.pDeviceHandler != nil {
645 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000647 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000648 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
649 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000650 }
651 } else {
652 // avoid device reason update as the rule config connected to this flow may still be in progress
653 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000655 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000657 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000658 }
659 }
mpagenko01e726e2020-10-23 09:45:29 +0000660
mpagenkof1fc3862021-02-16 10:09:52 +0000661 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000662 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000663 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000664 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000665 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000666 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000667 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000668 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000669 }
mpagenko15ff4a52021-03-02 10:09:20 +0000670 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000671 }
672 return nil
673}
674
mpagenkof1d21d12021-06-11 13:14:45 +0000675func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
676 oFsm.mutexFlowParams.Lock()
677 deleteChannel := apRemoveFlowParams.removeChannel
678 apRemoveFlowParams.isSuspendedOnAdd = true
679 oFsm.mutexFlowParams.Unlock()
680
681 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
682 select {
683 case success := <-deleteChannel:
684 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
685 if success {
686 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
687 "device-id": oFsm.deviceID})
688 return nil
689 }
690 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
691 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
692 oFsm.mutexFlowParams.Lock()
693 if apRemoveFlowParams != nil {
694 apRemoveFlowParams.isSuspendedOnAdd = false
695 }
696 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000697 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000698 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000699 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000700 }
mpagenkof1d21d12021-06-11 13:14:45 +0000701}
702
mpagenkof1fc3862021-02-16 10:09:52 +0000703// VOL-3828 flow config sequence workaround ########### start ##########
704func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
705 //assumes mutexFlowParams.Lock() protection from caller!
706 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
707 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000708 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000709 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
710 newCookie := aCookieSlice[0]
711 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
712 for _, cookie := range storedUniFlowParams.CookieSlice {
713 if cookie == newCookie {
714 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
715 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
716 oFsm.delayNewRuleCookie = newCookie
717 return newCookie //found new cookie in some existing rule
718 }
719 } // for all stored cookies of the actual inspected rule
720 } //for all rules
721 }
722 return 0 //no delay requested
723}
mpagenkobc4170a2021-08-17 16:42:10 +0000724func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000725 oFsm.mutexFlowParams.RLock()
726 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
727 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
728 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000729 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000730 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000731 case cookieDeleted = <-oFsm.chCookieDeleted:
732 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
733 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000734 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000735 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
736 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
737 }
738 oFsm.mutexFlowParams.Lock()
739 oFsm.delayNewRuleCookie = 0
740 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000741 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000742}
mpagenkobc4170a2021-08-17 16:42:10 +0000743func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000744 oFsm.mutexFlowParams.Lock()
745 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
746 oFsm.mutexFlowParams.Unlock()
747
mpagenkobc4170a2021-08-17 16:42:10 +0000748 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000749 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000750 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000751 }
mpagenkobc4170a2021-08-17 16:42:10 +0000752 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000753}
754
755//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000756func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000757 flowEntryMatch := false
758 oFsm.mutexFlowParams.Lock()
759 defer oFsm.mutexFlowParams.Unlock()
760 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
761 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
762 flowEntryMatch = true
763 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
764 "device-id": oFsm.deviceID})
765 cookieMatch := false
766 for _, cookie := range storedUniFlowParams.CookieSlice {
767 if cookie == aCookie {
768 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
769 "device-id": oFsm.deviceID, "cookie": cookie})
770 cookieMatch = true
771 break //found new cookie - no further search for this requested cookie
772 }
773 }
774 if !cookieMatch {
775 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
776 "device-id": oFsm.deviceID, "cookie": aCookie})
777 //as range works with copies of the slice we have to write to the original slice!!
778 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
779 aCookie)
780 return true, false //flowModified, NoRuleAppend
781 }
782 break // found rule - no further rule search
783 }
784 }
785 if !flowEntryMatch { //it is a new rule
786 return true, true //flowModified, RuleAppend
787 }
788 return false, false //flowNotModified, NoRuleAppend
789}
790
791// VOL-3828 flow config sequence workaround ########### end ##########
792
mpagenko01e726e2020-10-23 09:45:29 +0000793//RemoveUniFlowParams verifies on existence of flow cookie,
794// if found removes cookie from flow cookie list and if this is empty
795// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000796func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000797 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000798 flowCookieMatch := false
799 //mutex protection is required for possible concurrent access to FSM members
800 oFsm.mutexFlowParams.Lock()
801 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000802remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000803 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
804 for i, cookie := range storedUniFlowParams.CookieSlice {
805 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000806 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000807 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000808 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000809 //remove the cookie from the cookie slice and verify it is getting empty
810 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000811 // had to shift content to function due to sca complexity
812 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenkodee02a62021-07-21 10:56:10 +0000813 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000814 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000815 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000816 //cut off the requested cookie by slicing out this element
817 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
818 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
819 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000820 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
821 // state transition notification is checked in deviceHandler
822 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000823 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
824 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000825 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000827 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000828 if deletedCookie == oFsm.delayNewRuleCookie {
829 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
830 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
831 //simply use the first one
832 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
833 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
834 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
835 }
mpagenkodee02a62021-07-21 10:56:10 +0000836 //permanently store the modified flow config for reconcile case and immediately write to KvStore
837 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000838 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000839 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
840 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
841 return err
842 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000843 }
mpagenko01e726e2020-10-23 09:45:29 +0000844 }
mpagenkof1fc3862021-02-16 10:09:52 +0000845 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000846 }
847 }
mpagenko01e726e2020-10-23 09:45:29 +0000848 } //search all flows
849 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000850 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000851 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
852 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000853 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
854 // state transition notification is checked in deviceHandler
855 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000856 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000858 }
mpagenko01e726e2020-10-23 09:45:29 +0000859 return nil
860 } //unknown cookie
861
862 return nil
863}
864
mpagenkof582d6a2021-06-18 15:58:10 +0000865// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000866// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000867func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000868 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64) bool {
869 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000870 var cancelPendingConfig bool = false
871 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
872 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
873 "device-id": oFsm.deviceID})
874 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
875 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
876 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
877 // 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 +0000878 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000879 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
880 log.Fields{"device-id": oFsm.deviceID})
881 cancelPendingConfig = true
882 } else {
883 //create a new element for the removeVlanFlow slice
884 loRemoveParams = uniRemoveVlanFlowParams{
885 vlanRuleParams: aUniFlowParams.VlanRuleParams,
886 cookie: aCookie,
887 }
888 loRemoveParams.removeChannel = make(chan bool)
889 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
890 }
891
892 usedTpID := aUniFlowParams.VlanRuleParams.TpID
893 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
894 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
895 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
896 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000897 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
898 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000899 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
900 "device-id": oFsm.deviceID})
901 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000902 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000903 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000904 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000905 }
906 } else {
907 if !cancelPendingConfig {
908 oFsm.updateTechProfileToDelete(ctx, usedTpID)
909 }
910 }
911 //trigger the FSM to remove the relevant rule
912 if cancelPendingConfig {
913 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000914 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000915 //call from 'non-configured' state of the rules
916 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
917 //something quite inconsistent detected, perhaps just try to recover with FSM reset
918 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000919 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000920 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
921 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
922 }
923 return false //data base update could not be done, return like cookie not found
924 }
925
926 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
927 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
928 // synchronous FSM 'event/state' functions may rely on this mutex
929 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000930 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000931 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
932 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
933 }
934 oFsm.mutexFlowParams.Lock()
935 return true
936 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000937 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000938 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000939 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000940 "tp-id": loRemoveParams.vlanRuleParams.TpID,
941 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
942 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
943 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
944 // synchronous FSM 'event/state' functions may rely on this mutex
945 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000946 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000947 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
948 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
949 }
950 oFsm.mutexFlowParams.Lock()
951 } // if not in the appropriate state a new entry will be automatically considered later
952 // when the configDone state is reached
953 return true
954}
955
mpagenkof1d21d12021-06-11 13:14:45 +0000956//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
957// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
958// from the start of the deletion request to avoid to much interference
959// so when called, there can only be one cookie active for this flow
960// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000961func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000962 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
963 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000964 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000965removeFromSlice_loop:
966 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000967 // if UniFlowParams exists, cookieSlice should always have at least one element
968 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
969 if cookieSliceLen == 1 {
970 if storedUniFlowParams.CookieSlice[0] == aCookie {
971 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +0000972 }
mpagenkof582d6a2021-06-18 15:58:10 +0000973 } else if cookieSliceLen == 0 {
974 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
975 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
976 return errors.New(errStr)
977 } else {
978 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
979 logger.Errorw(ctx, errStr, log.Fields{
980 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
981 for _, cookie := range storedUniFlowParams.CookieSlice {
982 if cookie == aCookie {
983 cookieFound = true
984 break
985 }
986 }
987 }
988 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +0000989 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
990 "device-id": oFsm.deviceID, "cookie": aCookie})
991 //remove the actual element from the addVlanFlow slice
992 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
993 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000994 oFsm.NumUniFlows = 0 //no more flows
995 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +0000996 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
997 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
998 //request that this profile gets deleted before a new flow add is allowed
999 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1000 "device-id": oFsm.deviceID})
1001 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001002 oFsm.NumUniFlows--
1003 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1004 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001005 }
1006 //cut off the requested flow by slicing out this element
1007 oFsm.uniVlanFlowParamsSlice = append(
1008 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1009 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1010 "device-id": oFsm.deviceID})
1011 }
1012 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1013 }
1014 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001015 if !cookieFound {
1016 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1017 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1018 return errors.New(errStr)
1019 }
mpagenkodee02a62021-07-21 10:56:10 +00001020 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1021 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001022 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001023 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1024 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1025 return err
1026 }
mpagenkof582d6a2021-06-18 15:58:10 +00001027 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001028}
1029
1030// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001031func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1032 //here we have to check, if there are still other flows referencing to the actual ProfileId
1033 // before we can request that this profile gets deleted before a new flow add is allowed
1034 tpIDInOtherFlows := false
1035 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1036 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1037 tpIDInOtherFlows = true
1038 break // search loop can be left
1039 }
1040 }
1041 if tpIDInOtherFlows {
1042 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1043 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1044 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001045 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 +00001046 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001047 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1048 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001049 if oFsm.pUniTechProf != nil {
1050 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001051 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001052 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001053 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001054 }
1055}
1056
mpagenkof1d21d12021-06-11 13:14:45 +00001057func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1058 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001059
1060 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001061 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001062 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001063 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001064 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001065 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001066 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001067 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001068 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001069 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001070 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001071 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001072 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 go func(a_pAFsm *cmn.AdapterFsm) {
1074 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001075 }(pConfigVlanStateAFsm)
1076 return
1077 }
mpagenkof1d21d12021-06-11 13:14:45 +00001078 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001079 go func(a_pAFsm *cmn.AdapterFsm) {
1080 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001081 }(pConfigVlanStateAFsm)
1082 return
1083 }
1084 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1085 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1086 //should never happen, else: recovery would be needed from outside the FSM
1087}
1088
1089func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1090 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001091 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001092 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001093 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001094 //possibly the entry is not valid anymore based on intermediate delete requests
1095 //just a basic protection ...
1096 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1097 oFsm.mutexFlowParams.Unlock()
1098 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1099 "device-id": oFsm.deviceID})
1100 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001101 go func(a_pAFsm *cmn.AdapterFsm) {
1102 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001103 }(pConfigVlanStateAFsm)
1104 return
1105 }
mpagenko9a304ea2020-12-16 15:54:01 +00001106 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1107 //store the actual rule that shall be worked upon in the following transient states
1108 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001109 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
mpagenko9a304ea2020-12-16 15:54:01 +00001110 tpID := oFsm.actualUniVlanConfigRule.TpID
1111 oFsm.TpIDWaitingFor = tpID
Girish Gowdra24dd1132021-07-06 15:25:40 -07001112 //cmp also usage in EVTOCDE create in omci_cc
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
mpagenko45cc6a32021-07-23 10:06:57 +00001114 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1115 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1116 // synchronous FSM 'event/state' functions may rely on this mutex
1117 // but it must be released already before calling getTechProfileDone() as it may already be locked
1118 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001119 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001121 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001122 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001123 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001124
mpagenko9a304ea2020-12-16 15:54:01 +00001125 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1127 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001128 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001129 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001131 } else {
1132 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001133 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001134 }
1135 }
mpagenko551a4d42020-12-08 18:09:20 +00001136 }(pConfigVlanStateAFsm, loTechProfDone)
1137 } else {
1138 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1139 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1140 //should never happen, else: recovery would be needed from outside the FSM
1141 return
mpagenkodff5dda2020-08-28 11:52:01 +00001142 }
1143}
1144
dbainbri4d3a0dc2020-12-02 00:33:42 +00001145func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001146 //mutex protection is required for possible concurrent access to FSM members
1147 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001148 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001149 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001150 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001151 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001152 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001153 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001154 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001155 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001156 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001157 go func(a_pAFsm *cmn.AdapterFsm) {
1158 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001159 }(pConfigVlanStateAFsm)
1160 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001161 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1162 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001163 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001164 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001165 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001166 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001167 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001168 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001169 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001170 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001171 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001172 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1173 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001174 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001175 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001176 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001177 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1178 "ForwardOperation": uint8(0x10), //VID investigation
1179 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001180 },
1181 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001182 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001183 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001184 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001185 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1186 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001187 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001188 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001189 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1190 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001191 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001192 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001193 go func(a_pAFsm *cmn.AdapterFsm) {
1194 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001195 }(pConfigVlanStateAFsm)
1196 }
1197 return
1198 }
mpagenkodff5dda2020-08-28 11:52:01 +00001199 //accept also nil as (error) return value for writing to LastTx
1200 // - this avoids misinterpretation of new received OMCI messages
1201 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1202 // send shall return (dual format) error code that can be used here for immediate error treatment
1203 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001204 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001205 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001206 }
1207}
1208
dbainbri4d3a0dc2020-12-02 00:33:42 +00001209func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1210 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001211 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001212 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001213 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001214 //using the first element in the slice because it's the first flow per definition here
1215 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001216 //This is correct passing scenario
1217 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001218 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001219 tpID := oFsm.actualUniVlanConfigRule.TpID
1220 vlanID := oFsm.actualUniVlanConfigRule.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001221 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001222 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1223 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001224 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001227 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001228 vlanID)
1229 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001231 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001233 }
1234 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001235 //If this first flow contains a meter, then create TD for related gems.
1236 if oFsm.actualUniVlanConfigMeter != nil {
1237 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001238 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001239 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1240 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001242 if errCreateTrafficDescriptor != nil {
1243 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1244 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001245 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001246 }
1247 }
1248 }
1249
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001250 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001251 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001252 }
1253 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001254}
1255
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001257
mpagenkof1d21d12021-06-11 13:14:45 +00001258 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001259
mpagenkof1fc3862021-02-16 10:09:52 +00001260 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001261 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
1263 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001264 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001265 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001266 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1267 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1268 //should never happen, else: recovery would be needed from outside the FSM
1269 return
1270 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001271 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001272 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1273 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001274 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001276 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1277 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001278 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001279 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001280 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001282 }(pConfigVlanStateBaseFsm)
1283 return
1284 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001285 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1286 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001287 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001288 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 oFsm.pOnuDeviceEntry.SetReconcilingFlows(false)
1290 oFsm.pOnuDeviceEntry.SetChReconcilingFlowsFinished(true)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001291 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001292 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001294 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001295 return
1296 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1298 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001299 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001300 // this is a restart with a complete new flow, we can re-use the initial flow config control
1301 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001302 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001303 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001304 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001305 }(pConfigVlanStateBaseFsm)
1306 return
1307 }
1308
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001309 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001310 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001311 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001312 //check introduced after having observed some panic in this processing
1313 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001314 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001315 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1316 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 go func(a_pAFsm *cmn.AdapterFsm) {
1318 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001319 }(pConfigVlanStateAFsm)
1320 return
1321 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow].VlanRuleParams
1323 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +00001324 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001325 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001326 oFsm.TpIDWaitingFor = tpID
mpagenko45cc6a32021-07-23 10:06:57 +00001327 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1328 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1329 // synchronous FSM 'event/state' functions may rely on this mutex
1330 // but it must be released already before calling getTechProfileDone() as it may already be locked
1331 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1332 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001334 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001336 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1337
mpagenko9a304ea2020-12-16 15:54:01 +00001338 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001339 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1340 if aTechProfDone {
1341 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001343 } else {
1344 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001345 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001346 }
1347 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001348 return
1349 }
mpagenkof1d21d12021-06-11 13:14:45 +00001350 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001352 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001353 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1354 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001355 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001356 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001357 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001359 }
1360}
1361
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001363
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001365 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001367 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1369 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001370 return
1371 }
mpagenko15ff4a52021-03-02 10:09:20 +00001372 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001373 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001375 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001376 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001377
mpagenko9a304ea2020-12-16 15:54:01 +00001378 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001379 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001380 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001381 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001382 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001383 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1384 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1385 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1386 // 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 +00001387 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001388 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1389 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001391 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001392 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001393 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001394 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001396 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001397 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001398
mpagenko01e726e2020-10-23 09:45:29 +00001399 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001400 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1401 oFsm.numVlanFilterEntries = 1
1402 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001403 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001404 Attributes: me.AttributeValueMap{
1405 "VlanFilterList": vtfdFilterList,
1406 "ForwardOperation": uint8(0x10), //VID investigation
1407 "NumberOfEntries": oFsm.numVlanFilterEntries,
1408 },
1409 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001410 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1412 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001413 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001414 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001415 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001416 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1417 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001418 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001419 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 go func(a_pAFsm *cmn.AdapterFsm) {
1421 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001422 }(pConfigVlanStateAFsm)
1423 }
1424 return
1425 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001426 //accept also nil as (error) return value for writing to LastTx
1427 // - this avoids misinterpretation of new received OMCI messages
1428 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1429 // send shall return (dual format) error code that can be used here for immediate error treatment
1430 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001431 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001432 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001433 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001434 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1435 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001436 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001437
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001439 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001440 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001441 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001442 // setVid is assumed to be masked already by the caller to 12 bit
1443 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001444 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001445 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001446
1447 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1448 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1449 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001450 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001451
1452 oFsm.numVlanFilterEntries++
1453 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001454 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001455 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001456 "VlanFilterList": vtfdFilterList,
1457 "ForwardOperation": uint8(0x10), //VID investigation
1458 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001459 },
1460 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001461 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001462 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1463 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001464 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001465 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001466 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001467 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1468 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001469 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001470 return
1471 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001472 //accept also nil as (error) return value for writing to LastTx
1473 // - this avoids misinterpretation of new received OMCI messages
1474 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1475 // send shall return (dual format) error code that can be used here for immediate error treatment
1476 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001477 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001478 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001479 }
1480 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001482 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001483 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001485 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001486 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001487 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001488 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001489 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001490 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001491 return
1492 }
1493 }
mpagenkof1d21d12021-06-11 13:14:45 +00001494
mpagenkof1fc3862021-02-16 10:09:52 +00001495 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001496 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001497 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001498 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001499 tpID := oFsm.actualUniVlanConfigRule.TpID
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001500 ConfiguredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001501 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001502 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001503 errEvto := oFsm.performConfigEvtocdEntries(ctx, ConfiguredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001504 //This is correct passing scenario
1505 if errEvto == nil {
1506 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001507 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001508 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001509 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001510 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001511 "techProfile": tpID, "gemPort": gemPort,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001512 "vlanID": vlanID, "ConfiguredUniFlow": ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001513 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001515 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001517 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001518 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001519 }
1520 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001521 //If this incremental flow contains a meter, then create TD for related gems.
1522 if oFsm.actualUniVlanConfigMeter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001523 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001524 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1525 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001526 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001527 if errCreateTrafficDescriptor != nil {
1528 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1529 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001530 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001531 }
1532 }
1533 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001534 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001535 }
1536 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001537}
1538
dbainbri4d3a0dc2020-12-02 00:33:42 +00001539func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001540 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001542 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1543 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001544
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1546 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001547 loVlanEntryClear := uint8(0)
1548 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1549 //shallow copy is sufficient as no reference variables are used within struct
1550 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001551 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001553 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1554 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1555 "device-id": oFsm.deviceID})
1556
1557 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1558 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001560 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1561 } else {
1562 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1563 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001565 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1566 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001568 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001569 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001570 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001571 loVlanEntryClear = 1 //full VlanFilter clear request
1572 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001573 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1575 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001576 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001577 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001578 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1579 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001580 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001581 return
1582 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001583 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001584 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001585 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001587 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001588 }
mpagenko01e726e2020-10-23 09:45:29 +00001589 } else {
1590 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1591 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001593 log.Fields{"current vlan list": oFsm.vlanFilterList,
1594 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1595 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1596 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1597 loVlanEntryRmPos = i
1598 break //abort search
1599 }
1600 }
1601 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001602 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001603 //valid entry was found - to be eclipsed
1604 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1605 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1606 if i < loVlanEntryRmPos {
1607 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1608 } else if i < (cVtfdTableSize - 1) {
1609 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1610 } else {
1611 vtfdFilterList[i] = 0 //set last byte if needed
1612 }
1613 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001614 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001615 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001616 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001618
mpagenkofc4f56e2020-11-04 17:17:49 +00001619 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001620 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001621 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001622 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1623 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001624 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001625 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001626 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1627 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001629 return
1630 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001631 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001632 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001633 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001636 }
mpagenko01e726e2020-10-23 09:45:29 +00001637 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001639 log.Fields{"device-id": oFsm.deviceID})
1640 }
1641 }
1642 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001643 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1644 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001646 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001648 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001649 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001650 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001651 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001652 }(pConfigVlanStateBaseFsm)
1653 return
1654 }
mpagenko01e726e2020-10-23 09:45:29 +00001655 }
1656
mpagenko15ff4a52021-03-02 10:09:20 +00001657 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001658 if loVlanEntryClear == 1 {
1659 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1660 oFsm.numVlanFilterEntries = 0
1661 } else if loVlanEntryClear == 2 {
1662 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1663 // this loop now includes the 0 element on previous last valid entry
1664 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1665 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1666 }
1667 oFsm.numVlanFilterEntries--
1668 }
mpagenko15ff4a52021-03-02 10:09:20 +00001669 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001670 }
1671 }
1672
mpagenkofc4f56e2020-11-04 17:17:49 +00001673 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001675 } else {
1676 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001677 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001678 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001679 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001680 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001682 }(pConfigVlanStateBaseFsm)
1683 }
mpagenkodff5dda2020-08-28 11:52:01 +00001684}
1685
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001687 var tpID uint8
1688 // Extract the tpID
1689 if len(e.Args) > 0 {
1690 tpID = e.Args[0].(uint8)
1691 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1692 } else {
1693 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1694 }
mpagenko01e726e2020-10-23 09:45:29 +00001695 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001696 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001697
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001698 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001699 if pConfigVlanStateAFsm == nil {
1700 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1701 log.Fields{"device-id": oFsm.deviceID})
1702 //would have to be fixed from outside somehow
1703 return
1704 }
1705
mpagenkof1d21d12021-06-11 13:14:45 +00001706 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1707 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001708 //call from 'configured' state of the rule
1709 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1710 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1711 oFsm.mutexFlowParams.Unlock()
1712 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001713 go func(a_pAFsm *cmn.AdapterFsm) {
1714 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001715 }(pConfigVlanStateAFsm)
1716 return
1717 }
mpagenkof1d21d12021-06-11 13:14:45 +00001718 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1719 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1720 oFsm.mutexFlowParams.Unlock()
1721 removeChannel <- true
1722 oFsm.mutexFlowParams.Lock()
1723 }
1724
mpagenkof1fc3862021-02-16 10:09:52 +00001725 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1726 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1727 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1728
mpagenko01e726e2020-10-23 09:45:29 +00001729 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1730 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001732 "device-id": oFsm.deviceID})
1733 } else {
1734 //cut off the actual flow by slicing out the first element
1735 oFsm.uniRemoveFlowsSlice = append(
1736 oFsm.uniRemoveFlowsSlice[:0],
1737 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001739 "device-id": oFsm.deviceID})
1740 }
1741 oFsm.mutexFlowParams.Unlock()
1742
mpagenkof1fc3862021-02-16 10:09:52 +00001743 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001744 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001745 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001746 go func(a_pAFsm *cmn.AdapterFsm) {
1747 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001748 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001749
mpagenkobb47bc22021-04-20 13:29:09 +00001750 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001751 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001752 if deletedCookie == oFsm.delayNewRuleCookie {
1753 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1754 select {
1755 case <-oFsm.chCookieDeleted:
1756 logger.Debug(ctx, "flushed CookieDeleted")
1757 default:
1758 }
1759 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1760 }
mpagenkobb47bc22021-04-20 13:29:09 +00001761 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1762 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1763 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 -08001764 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001765 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1766 oFsm.flowDeleteChannel <- true
1767 oFsm.signalOnFlowDelete = false
1768 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001769 }
mpagenkobb47bc22021-04-20 13:29:09 +00001770 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001771}
1772
dbainbri4d3a0dc2020-12-02 00:33:42 +00001773func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1774 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001775
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001776 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001777 if pConfigVlanStateAFsm != nil {
1778 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001779 fsmAbortMsg := cmn.Message{
1780 Type: cmn.TestMsg,
1781 Data: cmn.TestMessage{
1782 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001783 },
1784 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001785 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001786
mpagenko9a304ea2020-12-16 15:54:01 +00001787 //try to restart the FSM to 'disabled'
1788 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001789 go func(a_pAFsm *cmn.AdapterFsm) {
1790 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1791 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001792 }
1793 }(pConfigVlanStateAFsm)
1794 }
1795}
1796
dbainbri4d3a0dc2020-12-02 00:33:42 +00001797func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1798 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001799 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001800 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001801 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001802
1803 oFsm.mutexFlowParams.RLock()
1804 if oFsm.delayNewRuleCookie != 0 {
1805 // looks like the waiting AddFlow is stuck
1806 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +00001807 oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
mpagenkof1d21d12021-06-11 13:14:45 +00001808 oFsm.mutexFlowParams.RLock()
1809 }
1810 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1811 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1812 if removeUniFlowParams.isSuspendedOnAdd {
1813 removeChannel := removeUniFlowParams.removeChannel
1814 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1815 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1816 oFsm.mutexFlowParams.RUnlock()
1817 removeChannel <- false
1818 oFsm.mutexFlowParams.RLock()
1819 }
1820 }
1821 }
1822
mpagenkodff5dda2020-08-28 11:52:01 +00001823 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001824 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1825 // current code removes the complete FSM including all flow/rule configuration done so far
1826 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1827 // maybe a more sophisticated approach is possible without clearing the data
1828 if oFsm.clearPersistency {
1829 //permanently remove possibly stored persistent data
1830 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001831 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1832 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001833 }
1834 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001836 }
mpagenko9a304ea2020-12-16 15:54:01 +00001837 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001838 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001840 return
mpagenkodff5dda2020-08-28 11:52:01 +00001841 }
mpagenkof1d21d12021-06-11 13:14:45 +00001842 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001843}
1844
dbainbri4d3a0dc2020-12-02 00:33:42 +00001845func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1846 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001847loop:
1848 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001849 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001850 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001851 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001852 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301853 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301855 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001856 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301857 break loop
1858 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001859 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301860
1861 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001862 case cmn.TestMsg:
1863 msg, _ := message.Data.(cmn.TestMessage)
1864 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001865 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001866 break loop
1867 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001869 case cmn.OMCI:
1870 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301872 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301874 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001875 }
1876 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001877 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001878}
1879
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001880func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001882 "msgType": msg.OmciMsg.MessageType})
1883
1884 switch msg.OmciMsg.MessageType {
1885 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001886 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001887 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1888 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001889 return
1890 }
mpagenkodff5dda2020-08-28 11:52:01 +00001891 } //CreateResponseType
1892 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001893 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001894 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1895 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001897 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001898 return
1899 }
1900 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1901 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001903 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001904 return
1905 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001907 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001909 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001910 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1911 return
1912 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001913 oFsm.mutexPLastTxMeInstance.RLock()
1914 if oFsm.pLastTxMeInstance != nil {
1915 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1916 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1917 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001918 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001919 { // let the MultiEntity config proceed by stopping the wait function
1920 oFsm.mutexPLastTxMeInstance.RUnlock()
1921 oFsm.omciMIdsResponseReceived <- true
1922 return
1923 }
1924 default:
1925 {
1926 logger.Warnw(ctx, "Unsupported ME name received!",
1927 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1928 }
mpagenkodff5dda2020-08-28 11:52:01 +00001929 }
1930 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001931 } else {
1932 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001933 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001934 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001935 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001936 case omci.DeleteResponseType:
1937 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1939 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001940 return
1941 }
1942 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001943 default:
1944 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001946 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001947 return
1948 }
1949 }
1950}
1951
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001953 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1954 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001955 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001956 log.Fields{"device-id": oFsm.deviceID})
1957 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1958 oFsm.deviceID)
1959 }
1960 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1961 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001963 log.Fields{"device-id": oFsm.deviceID})
1964 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1965 oFsm.deviceID)
1966 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001968 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001970 "Error": msgObj.Result})
1971 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1972 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1973 oFsm.deviceID)
1974 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001975 oFsm.mutexPLastTxMeInstance.RLock()
1976 if oFsm.pLastTxMeInstance != nil {
1977 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1978 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1979 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1980 switch oFsm.pLastTxMeInstance.GetName() {
1981 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1982 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03001983 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001984 {
1985 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001986 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001987 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001988 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001989 } else { // let the MultiEntity config proceed by stopping the wait function
1990 oFsm.omciMIdsResponseReceived <- true
1991 }
1992 return nil
1993 }
1994 default:
1995 {
1996 logger.Warnw(ctx, "Unsupported ME name received!",
1997 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001998 }
1999 }
2000 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002001 } else {
2002 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002003 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002004 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002005 return nil
2006}
2007
dbainbri4d3a0dc2020-12-02 00:33:42 +00002008func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002009 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2010 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002012 log.Fields{"device-id": oFsm.deviceID})
2013 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2014 oFsm.deviceID)
2015 }
2016 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2017 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002018 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002019 log.Fields{"device-id": oFsm.deviceID})
2020 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2021 oFsm.deviceID)
2022 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002024 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002025 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002026 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2027 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2028 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2029 oFsm.deviceID)
2030 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002031 oFsm.mutexPLastTxMeInstance.RLock()
2032 if oFsm.pLastTxMeInstance != nil {
2033 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2034 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2035 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002036 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002037 { // let the MultiEntity config proceed by stopping the wait function
2038 oFsm.mutexPLastTxMeInstance.RUnlock()
2039 oFsm.omciMIdsResponseReceived <- true
2040 return nil
2041 }
2042 default:
2043 {
2044 logger.Warnw(ctx, "Unsupported ME name received!",
2045 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2046 }
mpagenko01e726e2020-10-23 09:45:29 +00002047 }
2048 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002049 } else {
2050 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002051 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002052 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002053 return nil
2054}
2055
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002057 oFsm.mutexFlowParams.RLock()
2058 evtocdID := oFsm.evtocdID
2059 oFsm.mutexFlowParams.RUnlock()
2060
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002061 if aFlowEntryNo == 0 {
2062 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002063 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2064 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002065 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002066 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002067 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002068 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002069 associationType := 2 // default to UniPPTP
2070 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002071 associationType = 10
2072 }
2073 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002074 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002075 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002076 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002077 "AssociationType": uint8(associationType),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002078 "AssociatedMePointer": oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002079 },
2080 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002081 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2083 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002084 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002085 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002086 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2087 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002088 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002089 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2090 }
mpagenkodff5dda2020-08-28 11:52:01 +00002091 //accept also nil as (error) return value for writing to LastTx
2092 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002093 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002094 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002095
2096 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002097 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002098 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002100 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002101 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002102 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2103 }
2104
2105 // Set the EVTOCD ME default params
2106 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002107 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002108 Attributes: me.AttributeValueMap{
2109 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2110 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2111 "DownstreamMode": uint8(cDefaultDownstreamMode),
2112 },
2113 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002114 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002115 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2116 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2117 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002118 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002119 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002120 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2121 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002122 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002123 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2124 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002125 //accept also nil as (error) return value for writing to LastTx
2126 // - this avoids misinterpretation of new received OMCI messages
2127 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002128 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002129
2130 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002131 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002132 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002134 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002135 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002136 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002137 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002138 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002139
mpagenko551a4d42020-12-08 18:09:20 +00002140 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002141 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002142 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002143 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002144 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002145 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002146 sliceEvtocdRule := make([]uint8, 16)
2147 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2148 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2149 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2150 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2151 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2152
2153 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2154 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2155 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2156 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2157 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2158
2159 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2160 0<<cTreatTTROffset| // Do not pop any tags
2161 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2162 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2163 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2164
2165 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2166 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2167 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2168 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2169
2170 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002171 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002172 Attributes: me.AttributeValueMap{
2173 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2174 },
2175 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002177 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2178 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2179 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002180 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002181 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002182 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2183 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002185 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2186 }
mpagenkodff5dda2020-08-28 11:52:01 +00002187 //accept also nil as (error) return value for writing to LastTx
2188 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002189 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002191
2192 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002193 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002194 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002196 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002198 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2199
mpagenkodff5dda2020-08-28 11:52:01 +00002200 }
2201 } else {
2202 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2203 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002204 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2205 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2206 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2207 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002208 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002209 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002210 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002211 sliceEvtocdRule := make([]uint8, 16)
2212 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2213 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2214 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2215 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2216 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2217
2218 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002219 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2220 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002221 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2222 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2223
2224 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002225 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002226 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2227 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2228 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2229
2230 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002231 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2232 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002233 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002234 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002235
2236 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002237 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002238 Attributes: me.AttributeValueMap{
2239 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2240 },
2241 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002242 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002243 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2244 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2245 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002246 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002247 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002248 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2249 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002250 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002251 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2252 }
mpagenkodff5dda2020-08-28 11:52:01 +00002253 //accept also nil as (error) return value for writing to LastTx
2254 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002255 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002256 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002257
2258 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002259 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002260 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002261 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002262 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002263 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002264 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002265 }
2266 } else {
2267 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2268 { // just for local var's
2269 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002270 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002271 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002272 sliceEvtocdRule := make([]uint8, 16)
2273 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2274 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2275 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2276 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2277 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2278
2279 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2280 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2281 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2282 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2283 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2284
2285 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2286 0<<cTreatTTROffset| // Do not pop any tags
2287 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2288 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2289 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2290
2291 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2292 0<<cTreatPrioOffset| // vlan prio set to 0
2293 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002294 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002295 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2296
mpagenko551a4d42020-12-08 18:09:20 +00002297 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002298 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002299 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002300 Attributes: me.AttributeValueMap{
2301 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2302 },
2303 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002304 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002305 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2306 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2307 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002308 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002309 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2311 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002312 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002313 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2314 }
mpagenkodff5dda2020-08-28 11:52:01 +00002315 //accept also nil as (error) return value for writing to LastTx
2316 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002317 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002318 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002319
2320 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002321 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002322 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002324 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002325 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002326 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2327
mpagenkodff5dda2020-08-28 11:52:01 +00002328 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002329 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002330 { // just for local var's
2331 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002333 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002334 sliceEvtocdRule := make([]uint8, 16)
2335 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2336 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2337 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2338 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2339 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2340
2341 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2342 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2343 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2344 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2345 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2346
2347 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2348 1<<cTreatTTROffset| // pop the prio-tag
2349 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2350 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2351 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2352
mpagenko551a4d42020-12-08 18:09:20 +00002353 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002354 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2355 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2356 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002357 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002358 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002359 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002360
2361 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002362 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002363 Attributes: me.AttributeValueMap{
2364 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2365 },
2366 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002367 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002368 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2369 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2370 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002371 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002372 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002373 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2374 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002375 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002376 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2377 }
mpagenkodff5dda2020-08-28 11:52:01 +00002378 //accept also nil as (error) return value for writing to LastTx
2379 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002380 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002381 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002382
2383 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002384 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002385 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002387 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002388 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002389 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2390
mpagenkodff5dda2020-08-28 11:52:01 +00002391 }
2392 } //just for local var's
2393 }
2394 }
2395
mpagenkofc4f56e2020-11-04 17:17:49 +00002396 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002397 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002398 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002400 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002401 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002402}
2403
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002404func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002405 oFsm.mutexFlowParams.RLock()
2406 evtocdID := oFsm.evtocdID
2407 oFsm.mutexFlowParams.RUnlock()
2408
mpagenko01e726e2020-10-23 09:45:29 +00002409 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2410 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2411 //transparent transmission was set
2412 //perhaps the config is not needed for removal,
2413 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002414 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002415 "device-id": oFsm.deviceID})
2416 sliceEvtocdRule := make([]uint8, 16)
2417 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2418 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2419 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2420 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2421 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2422
2423 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2424 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2425 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2426 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2427 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2428
2429 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2430 0<<cTreatTTROffset| // Do not pop any tags
2431 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2432 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2433 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2434
2435 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2436 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2437 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2438 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2439
2440 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002441 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002442 Attributes: me.AttributeValueMap{
2443 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2444 },
2445 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002446 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002447 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2448 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2449 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002450 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002451 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002452 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2453 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002454 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002455 return
2456 }
mpagenko01e726e2020-10-23 09:45:29 +00002457 //accept also nil as (error) return value for writing to LastTx
2458 // - this avoids misinterpretation of new received OMCI messages
2459 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002460 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002461
2462 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002463 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002464 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002466 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002467 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002468 return
2469 }
2470 } else {
2471 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002472 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002473 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002474 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002475 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002476 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002477 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2478 sliceEvtocdRule := make([]uint8, 16)
2479 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2480 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2481 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2482 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2483 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2484
2485 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2486 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2487 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2488 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2489 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2490
2491 // delete indication for the indicated Filter
2492 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2493 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2494
2495 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002496 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002497 Attributes: me.AttributeValueMap{
2498 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2499 },
2500 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002501 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002502 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2503 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2504 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002505 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002506 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002507 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2508 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002509 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002510 return
2511 }
mpagenko01e726e2020-10-23 09:45:29 +00002512 //accept also nil as (error) return value for writing to LastTx
2513 // - this avoids misinterpretation of new received OMCI messages
2514 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002515 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002516
2517 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002518 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002519 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002520 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002521 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002522 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002523 return
2524 }
2525 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002526 // VOL-3685
2527 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2528 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2529 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2530 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2531 // later when the flow is being re-installed.
2532 // Of course this is applicable to case only where single service (or single tcont) is in use and
2533 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2534 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2535 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002536 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002537 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002538 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002539 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2540 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002541 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002542 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002543 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002544 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2546 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2547 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002548 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002549 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002550 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2551 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002552 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002553 return
2554 }
mpagenko01e726e2020-10-23 09:45:29 +00002555 //accept also nil as (error) return value for writing to LastTx
2556 // - this avoids misinterpretation of new received OMCI messages
2557 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002558 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002559
2560 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002561 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002562 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002563 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002564 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002565 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002566 return
2567 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002568 } else {
2569 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2570 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002572 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002573 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002574 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2575 { // just for local var's
2576 // this defines stacking scenario: untagged->singletagged
2577 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2578 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2579 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2580 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002581 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002582 "device-id": oFsm.deviceID})
2583 sliceEvtocdRule := make([]uint8, 16)
2584 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2585 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2586 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2587 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2588 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002589
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002590 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2591 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2592 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2593 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2594 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002595
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002596 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2597 0<<cTreatTTROffset| // Do not pop any tags
2598 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2599 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2600 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002601
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002602 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2603 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2604 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2605 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002606
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002607 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002608 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002609 Attributes: me.AttributeValueMap{
2610 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2611 },
2612 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002613 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002614 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2615 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2616 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002617 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002618 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002619 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2620 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002621 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002622 return
2623 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002624 //accept also nil as (error) return value for writing to LastTx
2625 // - this avoids misinterpretation of new received OMCI messages
2626 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002627 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002628
2629 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002630 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002631 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002633 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002634 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002635 return
2636 }
2637 } // just for local var's
2638 { // just for local var's
2639 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002641 "device-id": oFsm.deviceID})
2642 sliceEvtocdRule := make([]uint8, 16)
2643 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2644 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2645 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2646 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2647 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2648
2649 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2650 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2651 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2652 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2653 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2654
2655 // delete indication for the indicated Filter
2656 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2657 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2658
2659 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002660 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002661 Attributes: me.AttributeValueMap{
2662 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2663 },
2664 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002665 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2667 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2668 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002669 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002670 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002671 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2672 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002673 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002674 return
2675 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002676 //accept also nil as (error) return value for writing to LastTx
2677 // - this avoids misinterpretation of new received OMCI messages
2678 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002679 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002680
2681 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002682 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002683 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002684 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002685 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002686 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002687 return
2688 }
mpagenko01e726e2020-10-23 09:45:29 +00002689 }
2690 } //just for local var's
2691 }
2692 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002693 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002694 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002695 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002696}
2697
dbainbri4d3a0dc2020-12-02 00:33:42 +00002698func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002699 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002700 if oFsm.isCanceled {
2701 // FSM already canceled before entering wait
2702 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2703 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002705 }
mpagenko7d6bb022021-03-11 15:07:55 +00002706 oFsm.isAwaitingResponse = true
2707 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002708 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302709 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002710 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002711 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002712 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002713 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002714 oFsm.mutexIsAwaitingResponse.Lock()
2715 oFsm.isAwaitingResponse = false
2716 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002717 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002718 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302719 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002720 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002721 oFsm.mutexIsAwaitingResponse.Lock()
2722 oFsm.isAwaitingResponse = false
2723 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002724 return nil
2725 }
mpagenko7d6bb022021-03-11 15:07:55 +00002726 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002727 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002728 oFsm.mutexIsAwaitingResponse.Lock()
2729 oFsm.isAwaitingResponse = false
2730 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002731 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002732 }
2733}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002734
mpagenko551a4d42020-12-08 18:09:20 +00002735func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002736 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002737 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002738 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002739 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002740 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002741 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002742 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002743 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2744 }
2745
dbainbri4d3a0dc2020-12-02 00:33:42 +00002746 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002747 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002749 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002750 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002751 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2752 }
2753
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002756 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002757 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002758 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002759 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2760 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002761 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002762 if errMacBpCdEID != nil {
2763 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2764 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002765 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002766 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002767
Mahir Gunyel6781f962021-05-16 23:30:08 -07002768 }
2769 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002770 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2771 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002772 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002773 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002774 Attributes: me.AttributeValueMap{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 "BridgeIdPointer": cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002776 "PortNum": 0xf0, //fixed unique ANI side indication
2777 "TpType": 6, //MCGemIWTP
2778 "TpPointer": multicastGemPortID,
2779 },
2780 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002781 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2783 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002784 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002785 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002786 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2787 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002788 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002789 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2790 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002791 //accept also nil as (error) return value for writing to LastTx
2792 // - this avoids misinterpretation of new received OMCI messages
2793 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002794 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002795 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002796 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002797 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2799 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002800 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2801 }
2802
2803 // ==> Start creating VTFD for mcast vlan
2804
2805 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2806 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002807 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002808
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002810 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002811 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002812 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2813
2814 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2815 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2816 // new vlan associated with a different TP.
2817 vtfdFilterList[0] = uint16(vlanID)
2818
2819 meParams = me.ParamData{
2820 EntityID: mcastVtfdID,
2821 Attributes: me.AttributeValueMap{
2822 "VlanFilterList": vtfdFilterList,
2823 "ForwardOperation": uint8(0x10), //VID investigation
2824 "NumberOfEntries": oFsm.numVlanFilterEntries,
2825 },
2826 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002827 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002828 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2829 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002830 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002831 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002832 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2833 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002835 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2836 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002837 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002838 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002840 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002841 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002842 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002843 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2845 }
2846
2847 return nil
2848}
2849
dbainbri4d3a0dc2020-12-02 00:33:42 +00002850func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002851 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002852 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002853 logger.Errorw(ctx, "error generrating me instance id",
2854 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002855 return err
2856 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002857 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2858 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002859 meParams := me.ParamData{
2860 EntityID: instID,
2861 Attributes: me.AttributeValueMap{
2862 "MeType": 0,
2863 //Direct reference to the Operation profile
2864 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002865 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002866 },
2867 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002868 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
2870 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2871 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002872 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002873 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002874 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2875 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002877 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2878 oFsm.deviceID, err)
2879 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002880 //accept also nil as (error) return value for writing to LastTx
2881 // - this avoids misinterpretation of new received OMCI messages
2882 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002883 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002884 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002885 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002886 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002887 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002888 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2889 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2890 }
2891 return nil
2892}
2893
dbainbri4d3a0dc2020-12-02 00:33:42 +00002894func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002896 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002897 logger.Errorw(ctx, "error generating me instance id",
2898 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002899 return err
2900 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002901 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2902 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002903 meParams := me.ParamData{
2904 EntityID: instID,
2905 Attributes: me.AttributeValueMap{
2906 "IgmpVersion": 2,
2907 "IgmpFunction": 0,
2908 //0 means false
2909 "ImmediateLeave": 0,
2910 "Robustness": 2,
2911 "QuerierIp": 0,
2912 "QueryInterval": 125,
2913 "QuerierMaxResponseTime": 100,
2914 "LastMemberResponseTime": 10,
2915 //0 means false
2916 "UnauthorizedJoinBehaviour": 0,
2917 },
2918 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002919 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002920 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
2921 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2922 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002923 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002924 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002925 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2926 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002927 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002928 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2929 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 //accept also nil as (error) return value for writing to LastTx
2931 // - this avoids misinterpretation of new received OMCI messages
2932 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002933 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002935 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002936 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002937 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002939 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002940 }
2941 return nil
2942}
2943
dbainbri4d3a0dc2020-12-02 00:33:42 +00002944func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002946 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002947 logger.Errorw(ctx, "error generating me instance id",
2948 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002949 return err
2950 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002951 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2952 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 //TODO check that this is correct
2954 // Table control
2955 //setCtrl = 1
2956 //rowPartId = 0
2957 //test = 0
2958 //rowKey = 0
2959 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002961 dynamicAccessCL := make([]uint8, 24)
2962 copy(dynamicAccessCL, tableCtrl)
2963 //Multicast GemPortId
2964 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2965 // python version waits for installation of flows, see line 723 onward of
2966 // brcm_openomci_onu_handler.py
2967 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2968 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002969 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002970 //TODO start and end are hardcoded, get from TP
2971 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002973 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002974 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002975 //imputed group bandwidth
2976 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2977
2978 meParams := me.ParamData{
2979 EntityID: instID,
2980 Attributes: me.AttributeValueMap{
2981 "DynamicAccessControlListTable": dynamicAccessCL,
2982 },
2983 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002984 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
2986 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2987 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002988 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002989 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002990 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2991 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002992 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002993 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2994 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002995 //accept also nil as (error) return value for writing to LastTx
2996 // - this avoids misinterpretation of new received OMCI messages
2997 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002998 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002999 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003000 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003001 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003002 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003003 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003004 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003005 }
3006 return nil
3007}
Girish Gowdra26a40922021-01-29 17:14:34 -08003008
ozgecanetsia82b91a62021-05-21 18:54:49 +03003009func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3010 tpID uint8, uniID uint8, gemPortID uint16) error {
3011 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3012 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3013 // I created unique TD ID by flow direction.
3014 // TODO! Traffic descriptor ME ID will check
3015 trafficDescriptorID := gemPortID
3016 if aMeter == nil {
3017 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3018 }
3019 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3020 if err != nil {
3021 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3022 return err
3023 }
3024 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3025 cbs := trafficShapingInfo.Cbs
3026 pir := trafficShapingInfo.Pir
3027 pbs := trafficShapingInfo.Pbs
3028
3029 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3030 meParams := me.ParamData{
3031 EntityID: trafficDescriptorID,
3032 Attributes: me.AttributeValueMap{
3033 "Cir": cir,
3034 "Pir": pir,
3035 "Cbs": cbs,
3036 "Pbs": pbs,
3037 "ColourMode": 1,
3038 "IngressColourMarking": 3,
3039 "EgressColourMarking": 3,
3040 "MeterType": 1,
3041 },
3042 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003043 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003044 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3045 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003046 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003047 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003048 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3049 return err
3050 }
3051 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003052 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003053 err = oFsm.waitforOmciResponse(ctx)
3054 if err != nil {
3055 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3056 return err
3057 }
3058
Girish Gowdra09e5f212021-09-30 16:28:36 -07003059 // 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
3060 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003061 if err != nil {
3062 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3063 return err
3064 }
3065 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3066
3067 return nil
3068}
3069
Girish Gowdra09e5f212021-09-30 16:28:36 -07003070func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3071 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3072 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003073 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003074 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003075 Attributes: me.AttributeValueMap{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003076 "TrafficDescriptorProfilePointerForUpstream": trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003077 },
3078 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003079 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3081 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003082 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003083 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003084 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3085 return err
3086 }
3087 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003088 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003089 err = oFsm.waitforOmciResponse(ctx)
3090 if err != nil {
3091 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3092 return err
3093 }
3094 return nil
3095}
3096
Girish Gowdra26a40922021-01-29 17:14:34 -08003097// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00003098func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
3099 oFsm.mutexFlowParams.Lock()
3100 defer oFsm.mutexFlowParams.Unlock()
3101 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3102 //flow removal is still ongoing/pending
3103 oFsm.signalOnFlowDelete = true
3104 oFsm.flowDeleteChannel = aFlowDeleteChannel
3105 return true
3106 }
3107 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003108}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003109
3110func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3111 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3112 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3113 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3114 log.Fields{"device-id": oFsm.deviceID})
3115 } else {
3116 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3117 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3118 "index": oFsm.numVlanFilterEntries,
3119 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3120 "device-id": oFsm.deviceID})
3121 oFsm.numVlanFilterEntries++
3122 }
3123}