blob: 109ff30e620864e53062b26be29ec498b4cd2016 [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"
ozgecanetsia82b91a62021-05-21 18:54:49 +030031
mpagenko01e726e2020-10-23 09:45:29 +000032 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000033 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000034 "github.com/opencord/omci-lib-go/v2"
35 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040036 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000037 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
38 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
khenaidoo7d3c5582021-08-11 18:09:44 -040039 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000040)
41
42const (
43 // internal predefined values
44 cDefaultDownstreamMode = 0
45 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000046 cVtfdTableSize = 12 //as per G.988
47 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000048)
49
50const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000051 // internal offsets for requestEvent according to definition in onu_device_entry::cmn.OnuDeviceEvent
mpagenkof1fc3862021-02-16 10:09:52 +000052 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000053 cDeviceEventOffsetAddNoKvStore = cmn.OmciVlanFilterAddDoneNoKvStore - cmn.OmciVlanFilterAddDone
54 cDeviceEventOffsetRemoveWithKvStore = cmn.OmciVlanFilterRemDone - cmn.OmciVlanFilterAddDone
55 cDeviceEventOffsetRemoveNoKvStore = cmn.OmciVlanFilterRemDoneNoKvStore - cmn.OmciVlanFilterAddDone
mpagenkof1fc3862021-02-16 10:09:52 +000056)
57
58const (
mpagenkodff5dda2020-08-28 11:52:01 +000059 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
60 cFilterPrioOffset = 28
61 cFilterVidOffset = 15
62 cFilterTpidOffset = 12
63 cFilterEtherTypeOffset = 0
64 cTreatTTROffset = 30
65 cTreatPrioOffset = 16
66 cTreatVidOffset = 3
67 cTreatTpidOffset = 0
68)
69const (
70 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
71 cFilterOuterOffset = 0
72 cFilterInnerOffset = 4
73 cTreatOuterOffset = 8
74 cTreatInnerOffset = 12
75)
76const (
77 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
78 cPrioIgnoreTag uint32 = 15
79 cPrioDefaultFilter uint32 = 14
80 cPrioDoNotFilter uint32 = 8
81 cDoNotFilterVid uint32 = 4096
82 cDoNotFilterTPID uint32 = 0
83 cDoNotFilterEtherType uint32 = 0
84 cDoNotAddPrio uint32 = 15
85 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053086 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000087 cDontCareVid uint32 = 0
88 cDontCareTpid uint32 = 0
89 cSetOutputTpidCopyDei uint32 = 4
90)
91
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000092// events of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +000093const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000094 VlanEvStart = "VlanEvStart"
95 VlanEvPrepareDone = "VlanEvPrepareDone"
96 VlanEvWaitTechProf = "VlanEvWaitTechProf"
97 VlanEvCancelOutstandingConfig = "VlanEvCancelOutstandingConfig"
98 VlanEvContinueConfig = "VlanEvContinueConfig"
99 VlanEvStartConfig = "VlanEvStartConfig"
100 VlanEvRxConfigVtfd = "VlanEvRxConfigVtfd"
101 VlanEvRxConfigEvtocd = "VlanEvRxConfigEvtocd"
102 VlanEvWaitTPIncr = "VlanEvWaitTPIncr"
103 VlanEvIncrFlowConfig = "VlanEvIncrFlowConfig"
104 VlanEvRenew = "VlanEvRenew"
105 VlanEvRemFlowConfig = "VlanEvRemFlowConfig"
106 VlanEvRemFlowDone = "VlanEvRemFlowDone"
107 VlanEvFlowDataRemoved = "VlanEvFlowDataRemoved"
108 //VlanEvTimeoutSimple = "VlanEvTimeoutSimple"
109 //VlanEvTimeoutMids = "VlanEvTimeoutMids"
110 VlanEvReset = "VlanEvReset"
111 VlanEvRestart = "VlanEvRestart"
112 VlanEvSkipOmciConfig = "VlanEvSkipOmciConfig"
113 VlanEvSkipIncFlowConfig = "VlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000114)
mpagenko01e726e2020-10-23 09:45:29 +0000115
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000116// states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000117const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000118 VlanStDisabled = "VlanStDisabled"
119 VlanStPreparing = "VlanStPreparing"
120 VlanStStarting = "VlanStStarting"
121 VlanStWaitingTechProf = "VlanStWaitingTechProf"
122 VlanStConfigVtfd = "VlanStConfigVtfd"
123 VlanStConfigEvtocd = "VlanStConfigEvtocd"
124 VlanStConfigDone = "VlanStConfigDone"
125 VlanStIncrFlowWaitTP = "VlanStIncrFlowWaitTP"
126 VlanStConfigIncrFlow = "VlanStConfigIncrFlow"
127 VlanStRemoveFlow = "VlanStRemoveFlow"
128 VlanStCleanupDone = "VlanStCleanupDone"
129 VlanStResetting = "VlanStResetting"
mpagenkodff5dda2020-08-28 11:52:01 +0000130)
131
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000132// CVlanFsmIdleState - TODO: add comment
133const CVlanFsmIdleState = VlanStConfigDone // state where no OMCI activity is done (for a longer time)
134// CVlanFsmConfiguredState - TODO: add comment
135const CVlanFsmConfiguredState = VlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenko01e726e2020-10-23 09:45:29 +0000136
137type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000138 isSuspendedOnAdd bool
139 removeChannel chan bool
140 cookie uint64 //just the last cookie valid for removal
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000141 vlanRuleParams cmn.UniVlanRuleParams
Girish Gowdrae95687a2021-09-08 16:30:58 -0700142 respChan *chan error
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
mpagenkocf48e452021-04-23 09:23:00 +0000159 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000160 isAwaitingResponse bool
161 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000162 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000163 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
Girish Gowdrae95687a2021-09-08 16:30:58 -0700164 actualUniFlowParam cmn.UniVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000165 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000166 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000167 NumUniFlows uint8 // expected number of flows should be less than 12
168 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000169 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000170 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000171 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000173 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000174 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000175 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000176 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000177 signalOnFlowDelete bool
178 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000179 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
180 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200181 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
182 // thus notification needs to be sent on chan.
183 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000184}
185
mpagenko01e726e2020-10-23 09:45:29 +0000186//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
187// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000188func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
189 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
190 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400191 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *of.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000192 instFsm := &UniVlanConfigFsm{
193 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000194 pOnuDeviceEntry: apOnuDeviceEntry,
195 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000196 pOmciCC: apDevOmciCC,
197 pOnuUniPort: apUniPort,
198 pUniTechProf: apUniTechProf,
199 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000200 requestEvent: aRequestEvent,
201 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000202 NumUniFlows: 0,
203 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000204 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200205 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000206 }
207
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000208 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
209 if instFsm.PAdaptFsm == nil {
210 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000211 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700212 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000213 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000214 return nil
215 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000216 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
217 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000218 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000219 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
220 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
221 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
222 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
223 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
224 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
225 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
226 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
227 Dst: VlanStConfigDone},
228 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
229 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
230 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
231 Dst: VlanStConfigIncrFlow},
232 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
233 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
234 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000235 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000236 {Name: VlanEvTimeoutSimple, Src: []string{
237 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
238 {Name: VlanEvTimeoutMids, Src: []string{
239 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000240 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000241 // exceptional treatment for all states except VlanStResetting
242 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
243 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
244 VlanStRemoveFlow, VlanStCleanupDone},
245 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000246 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000247 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000248 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000249 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
250 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
251 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000252 },
mpagenkodff5dda2020-08-28 11:52:01 +0000253 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000254 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
255 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
256 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
257 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
258 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
259 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
260 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
261 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
262 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
263 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
264 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000265 },
266 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000267 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000268 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000269 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700270 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000271 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000272 return nil
273 }
274
Girish Gowdrae95687a2021-09-08 16:30:58 -0700275 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter, respChan)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000276
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000278 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return instFsm
280}
281
mpagenko01e726e2020-10-23 09:45:29 +0000282//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000283func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400284 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 loRuleParams := cmn.UniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000286 TpID: aTpID,
287 MatchVid: uint32(aMatchVlan),
288 SetVid: uint32(aSetVlan),
289 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000290 }
291 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
293 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000294
mpagenko01e726e2020-10-23 09:45:29 +0000295 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000296 //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 +0000297 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
299 } else {
300 if !oFsm.acceptIncrementalEvtoOption {
301 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000302 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 }
304 }
305
mpagenko01e726e2020-10-23 09:45:29 +0000306 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000307 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000308 loRuleParams.TagsToRemove = 0 //no tag pop action
309 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
310 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000311 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
312 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
313 // might collide with NoMatchVid/CopyPrio(/setVid) setting
314 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000315 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000316 }
317 }
mpagenko01e726e2020-10-23 09:45:29 +0000318
Girish Gowdrae95687a2021-09-08 16:30:58 -0700319 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000320 loFlowParams.CookieSlice = make([]uint64, 0)
321 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300322 if aMeter != nil {
323 loFlowParams.Meter = aMeter
324 }
mpagenko01e726e2020-10-23 09:45:29 +0000325
326 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000327 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000328 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000329 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000330 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
331 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
332 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
333 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000334 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000335
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000336 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000337 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
338 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000339 //cmp also usage in EVTOCDE create in omci_cc
340 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000341 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000342 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
343
344 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000345 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000346 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000347 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000348 return err
349 }
350
351 return nil
352}
353
mpagenko7d6bb022021-03-11 15:07:55 +0000354//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000355func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000356 if oFsm == nil {
357 logger.Error(ctx, "no valid UniVlanConfigFsm!")
358 return
359 }
mpagenko7d6bb022021-03-11 15:07:55 +0000360 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000361 oFsm.mutexIsAwaitingResponse.Lock()
362 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000363 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000364 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
365 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
366 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000367 //use channel to indicate that the response waiting shall be aborted
368 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000369 } else {
370 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000371 }
mpagenkocf48e452021-04-23 09:23:00 +0000372
mpagenko7d6bb022021-03-11 15:07:55 +0000373 // 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 +0000374 PAdaptFsm := oFsm.PAdaptFsm
375 if PAdaptFsm != nil {
376 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000377 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000378 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000379 }
mpagenko7d6bb022021-03-11 15:07:55 +0000380 }
381}
382
mpagenko551a4d42020-12-08 18:09:20 +0000383//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000384func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
385 if oFsm == nil {
386 logger.Error(ctx, "no valid UniVlanConfigFsm!")
387 return 0
388 }
mpagenko551a4d42020-12-08 18:09:20 +0000389 //mutex protection is required for possible concurrent access to FSM members
390 oFsm.mutexFlowParams.RLock()
391 defer oFsm.mutexFlowParams.RUnlock()
392 return oFsm.TpIDWaitingFor
393}
394
mpagenko01e726e2020-10-23 09:45:29 +0000395//SetUniFlowParams verifies on existence of flow parameters to be configured,
396// optionally udates the cookie list or appends a new flow if there is space
397// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000398// ignore complexity by now
399// nolint: gocyclo
400func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
khenaidoo42dcdfd2021-10-19 17:34:12 -0400401 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000402 if oFsm == nil {
403 logger.Error(ctx, "no valid UniVlanConfigFsm!")
404 return fmt.Errorf("no-valid-UniVlanConfigFsm")
405 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000406 loRuleParams := cmn.UniVlanRuleParams{
mpagenko01e726e2020-10-23 09:45:29 +0000407 TpID: aTpID,
408 MatchVid: uint32(aMatchVlan),
409 SetVid: uint32(aSetVlan),
410 SetPcp: uint32(aSetPcp),
411 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700412 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000413 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
414 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
415 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000416 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
417 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
418 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
419 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
420 } else {
421 if !oFsm.acceptIncrementalEvtoOption {
422 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
423 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
424 }
425 }
426
427 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
428 // no prio/vid filtering requested
429 loRuleParams.TagsToRemove = 0 //no tag pop action
430 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
431 if loRuleParams.SetPcp == cCopyPrioFromInner {
432 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
433 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
434 // might collide with NoMatchVid/CopyPrio(/setVid) setting
435 // this was some precondition setting taken over from py adapter ..
436 loRuleParams.SetPcp = 0
437 }
438 }
439
mpagenkof1d21d12021-06-11 13:14:45 +0000440 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
441 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
442 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
443 oFsm.mutexFlowParams.RLock()
444 if len(oFsm.uniRemoveFlowsSlice) > 0 {
445 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
446 if removeUniFlowParams.vlanRuleParams == loRuleParams {
447 // the flow to add is the same as the one already in progress of deleting
448 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000449 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
450 if flow >= len(oFsm.uniRemoveFlowsSlice) {
451 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
452 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
453 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700454 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000455 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700456 return err
457
mpagenkof582d6a2021-06-18 15:58:10 +0000458 }
mpagenkof1d21d12021-06-11 13:14:45 +0000459 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
460 oFsm.mutexFlowParams.RUnlock()
461 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
462 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
463 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700464 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000465 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700466 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000467 }
468 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000469 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000470 }
471 }
472 }
473 oFsm.mutexFlowParams.RUnlock()
474
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000475 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000476 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000477 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200478 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000479 //mutex protection is required for possible concurrent access to FSM members
480 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000481 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
482 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
483 // countable run time optimization (perhaps with including the hash in kvStore storage?)
484 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000485 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000486 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300487 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
488 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
489 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000490 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000491 var cookieMatch bool
492 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
493 cookieMatch = false
494 for _, cookie := range storedUniFlowParams.CookieSlice {
495 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000496 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000497 "device-id": oFsm.deviceID, "cookie": cookie})
498 cookieMatch = true
499 break //found new cookie - no further search for this requested cookie
500 }
501 }
502 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000503 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
504 if delayedCookie != 0 {
505 //a delay for adding the cookie to this rule is requested
506 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
507 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000508 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
509 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
510 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700511 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000512 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700513 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000514 }
mpagenkobc4170a2021-08-17 16:42:10 +0000515 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000516 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000517 } else {
518 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
519 "device-id": oFsm.deviceID, "cookie": newCookie})
520 //as range works with copies of the slice we have to write to the original slice!!
521 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
522 newCookie)
523 flowCookieModify = true
524 }
mpagenko01e726e2020-10-23 09:45:29 +0000525 }
526 } //for all new cookies
527 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000528 }
529 }
mpagenkof1fc3862021-02-16 10:09:52 +0000530 oFsm.mutexFlowParams.Unlock()
531
532 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000533 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
534 if !deleteSuccess {
535 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
536 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700537 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000538 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700539 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000540 }
mpagenkof1fc3862021-02-16 10:09:52 +0000541 requestAppendRule = true //default assumption here is that rule is to be appended
542 flowCookieModify = true //and that the the flow data base is to be updated
543 if delayedCookie != 0 { //it was suspended
544 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
545 }
546 }
547 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
548 if requestAppendRule {
549 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000550 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700551 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000552 loFlowParams.CookieSlice = make([]uint64, 0)
553 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300554 if aMeter != nil {
555 loFlowParams.Meter = aMeter
556 }
mpagenko01e726e2020-10-23 09:45:29 +0000557 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000558 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000559 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000560 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
561 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000562 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
563 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000564
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000566 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
567 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000568 oFsm.NumUniFlows++
569 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000570
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000571 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000572 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000574 //attention: take care to release the mutexFlowParams when calling the FSM directly -
575 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000576 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
578 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000579 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700581 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000582 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700583 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000584 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000585 }
586 return nil
587 }
mpagenko01e726e2020-10-23 09:45:29 +0000588 // note: theoretical it would be possible to clear the same rule from the remove slice
589 // (for entries that have not yet been started with removal)
590 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
591 // 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 +0000592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000593 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000594 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000596 // this is a restart with a complete new flow, we can re-use the initial flow config control
597 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000598 //attention: take care to release the mutexFlowParams when calling the FSM directly -
599 // synchronous FSM 'event/state' functions may rely on this mutex
600 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000601 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000602 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
603 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
604 }
mpagenko551a4d42020-12-08 18:09:20 +0000605 } else {
606 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000607 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000608 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000609 //check introduced after having observed some panic here
610 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000611 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000612 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
613 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700614 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000615 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700616 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000617 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700618
619 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000620 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700621 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000622 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700623 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000624 //attention: take care to release the mutexFlowParams when calling the FSM directly -
625 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000626 // but it must be released already before calling getTechProfileDone() as it may already be locked
627 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000628 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000629 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000630 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000631 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000632 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
633
mpagenkobb47bc22021-04-20 13:29:09 +0000634 var fsmErr error
635 if loTechProfDone {
636 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000637 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000638 } else {
639 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000640 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000641 }
642 if fsmErr != nil {
643 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
644 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000645 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700646 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000647 }
mpagenko551a4d42020-12-08 18:09:20 +0000648 }
mpagenkobb47bc22021-04-20 13:29:09 +0000649 } else {
650 // if not in the appropriate state a new entry will be automatically considered later
651 // when the configDone state is reached
652 oFsm.mutexFlowParams.Unlock()
653 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000654 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000656 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000657 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700658 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000659 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700660 return err
mpagenko01e726e2020-10-23 09:45:29 +0000661 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000662 } else {
663 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000664 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000666 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700667
mpagenko15ff4a52021-03-02 10:09:20 +0000668 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000669 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000670 //all requested rules really have been configured
671 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000672 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 if oFsm.pDeviceHandler != nil {
674 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000676 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000677 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
678 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000679 }
680 } else {
681 // avoid device reason update as the rule config connected to this flow may still be in progress
682 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000683 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000684 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000685 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000686 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000687 }
688 }
mpagenko01e726e2020-10-23 09:45:29 +0000689
mpagenkof1fc3862021-02-16 10:09:52 +0000690 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000691 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000692 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000693 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000694 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000695 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000696 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000697 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000698 }
mpagenko15ff4a52021-03-02 10:09:20 +0000699 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000700 }
701 return nil
702}
703
mpagenkof1d21d12021-06-11 13:14:45 +0000704func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
705 oFsm.mutexFlowParams.Lock()
706 deleteChannel := apRemoveFlowParams.removeChannel
707 apRemoveFlowParams.isSuspendedOnAdd = true
708 oFsm.mutexFlowParams.Unlock()
709
710 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
711 select {
712 case success := <-deleteChannel:
713 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
714 if success {
715 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
716 "device-id": oFsm.deviceID})
717 return nil
718 }
719 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
720 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
721 oFsm.mutexFlowParams.Lock()
722 if apRemoveFlowParams != nil {
723 apRemoveFlowParams.isSuspendedOnAdd = false
724 }
725 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000726 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000727 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000728 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000729 }
mpagenkof1d21d12021-06-11 13:14:45 +0000730}
731
mpagenkof1fc3862021-02-16 10:09:52 +0000732// VOL-3828 flow config sequence workaround ########### start ##########
733func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
734 //assumes mutexFlowParams.Lock() protection from caller!
735 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
736 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000737 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000738 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
739 newCookie := aCookieSlice[0]
740 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
741 for _, cookie := range storedUniFlowParams.CookieSlice {
742 if cookie == newCookie {
743 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
744 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
745 oFsm.delayNewRuleCookie = newCookie
746 return newCookie //found new cookie in some existing rule
747 }
748 } // for all stored cookies of the actual inspected rule
749 } //for all rules
750 }
751 return 0 //no delay requested
752}
mpagenkobc4170a2021-08-17 16:42:10 +0000753func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000754 oFsm.mutexFlowParams.RLock()
755 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
756 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
757 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000758 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000759 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000760 case cookieDeleted = <-oFsm.chCookieDeleted:
761 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
762 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000763 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000764 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
765 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
766 }
767 oFsm.mutexFlowParams.Lock()
768 oFsm.delayNewRuleCookie = 0
769 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000770 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000771}
mpagenkobc4170a2021-08-17 16:42:10 +0000772func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000773 oFsm.mutexFlowParams.Lock()
774 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
775 oFsm.mutexFlowParams.Unlock()
776
mpagenkobc4170a2021-08-17 16:42:10 +0000777 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000778 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000779 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000780 }
mpagenkobc4170a2021-08-17 16:42:10 +0000781 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000782}
783
784//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000785func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000786 flowEntryMatch := false
787 oFsm.mutexFlowParams.Lock()
788 defer oFsm.mutexFlowParams.Unlock()
789 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
790 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
791 flowEntryMatch = true
792 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
793 "device-id": oFsm.deviceID})
794 cookieMatch := false
795 for _, cookie := range storedUniFlowParams.CookieSlice {
796 if cookie == aCookie {
797 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
798 "device-id": oFsm.deviceID, "cookie": cookie})
799 cookieMatch = true
800 break //found new cookie - no further search for this requested cookie
801 }
802 }
803 if !cookieMatch {
804 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
805 "device-id": oFsm.deviceID, "cookie": aCookie})
806 //as range works with copies of the slice we have to write to the original slice!!
807 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
808 aCookie)
809 return true, false //flowModified, NoRuleAppend
810 }
811 break // found rule - no further rule search
812 }
813 }
814 if !flowEntryMatch { //it is a new rule
815 return true, true //flowModified, RuleAppend
816 }
817 return false, false //flowNotModified, NoRuleAppend
818}
819
820// VOL-3828 flow config sequence workaround ########### end ##########
821
mpagenko01e726e2020-10-23 09:45:29 +0000822//RemoveUniFlowParams verifies on existence of flow cookie,
823// if found removes cookie from flow cookie list and if this is empty
824// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700825func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000826 if oFsm == nil {
827 logger.Error(ctx, "no valid UniVlanConfigFsm!")
828 return fmt.Errorf("no-valid-UniVlanConfigFsm")
829 }
mpagenkof1fc3862021-02-16 10:09:52 +0000830 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000831 flowCookieMatch := false
832 //mutex protection is required for possible concurrent access to FSM members
833 oFsm.mutexFlowParams.Lock()
834 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000835remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000836 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
837 for i, cookie := range storedUniFlowParams.CookieSlice {
838 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000840 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000841 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000842 //remove the cookie from the cookie slice and verify it is getting empty
843 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000844 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700845 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000846 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000847 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000848 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000849 //cut off the requested cookie by slicing out this element
850 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
851 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
852 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
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 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000856 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
857 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000858 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000859 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000860 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000861 if deletedCookie == oFsm.delayNewRuleCookie {
862 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
863 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
864 //simply use the first one
865 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
866 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
867 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
868 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700869 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000870 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000871 //permanently store the modified flow config for reconcile case and immediately write to KvStore
872 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000873 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000874 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
875 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
876 return err
877 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000878 }
mpagenko01e726e2020-10-23 09:45:29 +0000879 }
mpagenkof1fc3862021-02-16 10:09:52 +0000880 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000881 }
882 }
mpagenko01e726e2020-10-23 09:45:29 +0000883 } //search all flows
884 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000886 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
887 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000888 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
889 // state transition notification is checked in deviceHandler
890 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000891 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000892 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000893 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700894 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000895 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000896 return nil
897 } //unknown cookie
898
899 return nil
900}
901
mpagenkof582d6a2021-06-18 15:58:10 +0000902// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000903// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000904func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700905 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000906 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000907 var cancelPendingConfig bool = false
908 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
909 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
910 "device-id": oFsm.deviceID})
911 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
912 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
913 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
914 // 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 +0000915 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000916 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
917 log.Fields{"device-id": oFsm.deviceID})
918 cancelPendingConfig = true
919 } else {
920 //create a new element for the removeVlanFlow slice
921 loRemoveParams = uniRemoveVlanFlowParams{
922 vlanRuleParams: aUniFlowParams.VlanRuleParams,
923 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700924 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000925 }
926 loRemoveParams.removeChannel = make(chan bool)
927 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
928 }
929
930 usedTpID := aUniFlowParams.VlanRuleParams.TpID
931 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
932 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
933 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
934 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000935 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
936 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000937 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
938 "device-id": oFsm.deviceID})
939 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000940 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000941 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000942 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000943 }
944 } else {
945 if !cancelPendingConfig {
946 oFsm.updateTechProfileToDelete(ctx, usedTpID)
947 }
948 }
949 //trigger the FSM to remove the relevant rule
950 if cancelPendingConfig {
951 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000952 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000953 //call from 'non-configured' state of the rules
954 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
955 //something quite inconsistent detected, perhaps just try to recover with FSM reset
956 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000958 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
959 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
960 }
961 return false //data base update could not be done, return like cookie not found
962 }
963
964 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
965 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
966 // synchronous FSM 'event/state' functions may rely on this mutex
967 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000968 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000969 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
970 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
971 }
972 oFsm.mutexFlowParams.Lock()
973 return true
974 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000975 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000976 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000978 "tp-id": loRemoveParams.vlanRuleParams.TpID,
979 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
980 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
981 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
982 // synchronous FSM 'event/state' functions may rely on this mutex
983 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000984 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000985 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
986 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
987 }
988 oFsm.mutexFlowParams.Lock()
989 } // if not in the appropriate state a new entry will be automatically considered later
990 // when the configDone state is reached
991 return true
992}
993
mpagenkof1d21d12021-06-11 13:14:45 +0000994//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
995// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
996// from the start of the deletion request to avoid to much interference
997// so when called, there can only be one cookie active for this flow
998// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000999func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001000 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1001 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001002 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001003removeFromSlice_loop:
1004 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001005 // if UniFlowParams exists, cookieSlice should always have at least one element
1006 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1007 if cookieSliceLen == 1 {
1008 if storedUniFlowParams.CookieSlice[0] == aCookie {
1009 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001010 }
mpagenkof582d6a2021-06-18 15:58:10 +00001011 } else if cookieSliceLen == 0 {
1012 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1013 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1014 return errors.New(errStr)
1015 } else {
1016 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1017 logger.Errorw(ctx, errStr, log.Fields{
1018 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1019 for _, cookie := range storedUniFlowParams.CookieSlice {
1020 if cookie == aCookie {
1021 cookieFound = true
1022 break
1023 }
1024 }
1025 }
1026 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001027 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1028 "device-id": oFsm.deviceID, "cookie": aCookie})
1029 //remove the actual element from the addVlanFlow slice
1030 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1031 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001032 oFsm.NumUniFlows = 0 //no more flows
1033 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001034 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1035 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1036 //request that this profile gets deleted before a new flow add is allowed
1037 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1038 "device-id": oFsm.deviceID})
1039 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001040 oFsm.NumUniFlows--
1041 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1042 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001043 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001044 if !aWasConfigured {
1045 // We did not actually process this flow but was removed before that.
1046 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001047 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001048 }
1049
mpagenkof1d21d12021-06-11 13:14:45 +00001050 //cut off the requested flow by slicing out this element
1051 oFsm.uniVlanFlowParamsSlice = append(
1052 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1053 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1054 "device-id": oFsm.deviceID})
1055 }
1056 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1057 }
1058 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001059 if !cookieFound {
1060 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1061 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1062 return errors.New(errStr)
1063 }
mpagenkodee02a62021-07-21 10:56:10 +00001064 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1065 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001066 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001067 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1068 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1069 return err
1070 }
mpagenkof582d6a2021-06-18 15:58:10 +00001071 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001072}
1073
1074// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001075func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1076 //here we have to check, if there are still other flows referencing to the actual ProfileId
1077 // before we can request that this profile gets deleted before a new flow add is allowed
1078 tpIDInOtherFlows := false
1079 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1080 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1081 tpIDInOtherFlows = true
1082 break // search loop can be left
1083 }
1084 }
1085 if tpIDInOtherFlows {
1086 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1087 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1088 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001089 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 +00001090 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001091 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1092 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001093 if oFsm.pUniTechProf != nil {
1094 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001095 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001096 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001097 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001098 }
1099}
1100
mpagenkof1d21d12021-06-11 13:14:45 +00001101func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1102 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001103
1104 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001105 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001106 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001107 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001108 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001109 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001110 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001111 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001112 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001114 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001115 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001116 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001117 go func(a_pAFsm *cmn.AdapterFsm) {
1118 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001119 }(pConfigVlanStateAFsm)
1120 return
1121 }
mpagenkof1d21d12021-06-11 13:14:45 +00001122 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001123 go func(a_pAFsm *cmn.AdapterFsm) {
1124 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001125 }(pConfigVlanStateAFsm)
1126 return
1127 }
1128 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1129 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1130 //should never happen, else: recovery would be needed from outside the FSM
1131}
1132
1133func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1134 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001135 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001136 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001137 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001138 //possibly the entry is not valid anymore based on intermediate delete requests
1139 //just a basic protection ...
1140 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1141 oFsm.mutexFlowParams.Unlock()
1142 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1143 "device-id": oFsm.deviceID})
1144 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001145 go func(a_pAFsm *cmn.AdapterFsm) {
1146 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001147 }(pConfigVlanStateAFsm)
1148 return
1149 }
mpagenko9a304ea2020-12-16 15:54:01 +00001150 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1151 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001152 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1153 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001154 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001155 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001156 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1157 // synchronous FSM 'event/state' functions may rely on this mutex
1158 // but it must be released already before calling getTechProfileDone() as it may already be locked
1159 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001160 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001161 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001162 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001163 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001164 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001165
mpagenko9a304ea2020-12-16 15:54:01 +00001166 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001167 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1168 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001169 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001170 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001171 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001172 } else {
1173 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001174 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001175 }
1176 }
mpagenko551a4d42020-12-08 18:09:20 +00001177 }(pConfigVlanStateAFsm, loTechProfDone)
1178 } else {
1179 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1180 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1181 //should never happen, else: recovery would be needed from outside the FSM
1182 return
mpagenkodff5dda2020-08-28 11:52:01 +00001183 }
1184}
1185
dbainbri4d3a0dc2020-12-02 00:33:42 +00001186func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001187 //mutex protection is required for possible concurrent access to FSM members
1188 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001189 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001190 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001191 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001192 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001194 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001195 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001196 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001197 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001198 go func(a_pAFsm *cmn.AdapterFsm) {
1199 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001200 }(pConfigVlanStateAFsm)
1201 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001202 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1203 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001204 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001205 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001206 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001207 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001208 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001209 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001210 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001211 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001212 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001213 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1214 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001215 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001216 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001217 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001218 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1219 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1220 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001221 },
1222 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001223 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001224 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001225 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001226 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1227 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001228 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001229 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001230 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1231 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001232 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001233 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 go func(a_pAFsm *cmn.AdapterFsm) {
1235 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001236 }(pConfigVlanStateAFsm)
1237 }
1238 return
1239 }
mpagenkodff5dda2020-08-28 11:52:01 +00001240 //accept also nil as (error) return value for writing to LastTx
1241 // - this avoids misinterpretation of new received OMCI messages
1242 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1243 // send shall return (dual format) error code that can be used here for immediate error treatment
1244 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001245 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001246 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001247 }
1248}
1249
dbainbri4d3a0dc2020-12-02 00:33:42 +00001250func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1251 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001252 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001253 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001254 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001255 //using the first element in the slice because it's the first flow per definition here
1256 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001257 //This is correct passing scenario
1258 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001259 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001260 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1261 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001262 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001263 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1264 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001265 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001266 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001269 vlanID)
1270 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001271 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001272 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001273 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001274 }
1275 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001276 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001277 if oFsm.actualUniFlowParam.Meter != nil {
1278 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001279 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001280 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1281 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001283 if errCreateTrafficDescriptor != nil {
1284 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1285 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001287 }
1288 }
1289 }
1290
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001291 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001292 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001293 }
1294 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001295}
1296
dbainbri4d3a0dc2020-12-02 00:33:42 +00001297func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001298
mpagenkof1d21d12021-06-11 13:14:45 +00001299 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001300
mpagenkof1fc3862021-02-16 10:09:52 +00001301 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001302 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001303 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001304 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001305 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001306 }
1307
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001308 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001309 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001310 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001311 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1312 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1313 //should never happen, else: recovery would be needed from outside the FSM
1314 return
1315 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001316 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001317 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1318 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001319 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001320 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001321 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1322 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001323 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001324 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001325 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001326 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001327 }(pConfigVlanStateBaseFsm)
1328 return
1329 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001330 if oFsm.lastFlowToReconcile {
1331 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1332 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1333 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1334 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1335 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1336 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001337 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1338 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001339 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001340 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001341 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001342 return
1343 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1345 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001346 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001347 // this is a restart with a complete new flow, we can re-use the initial flow config control
1348 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001349 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001350 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001352 }(pConfigVlanStateBaseFsm)
1353 return
1354 }
1355
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001356 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001357 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001359 //check introduced after having observed some panic in this processing
1360 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001361 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001362 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1363 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 go func(a_pAFsm *cmn.AdapterFsm) {
1365 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001366 }(pConfigVlanStateAFsm)
1367 return
1368 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001369 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001370 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001371 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001372 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001373 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001374 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1375 // synchronous FSM 'event/state' functions may rely on this mutex
1376 // but it must be released already before calling getTechProfileDone() as it may already be locked
1377 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1378 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001379 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001380 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001382 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1383
mpagenko9a304ea2020-12-16 15:54:01 +00001384 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001385 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1386 if aTechProfDone {
1387 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001389 } else {
1390 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001391 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001392 }
1393 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001394 return
1395 }
mpagenkof1d21d12021-06-11 13:14:45 +00001396 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001398 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001399 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1400 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001401 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001402 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001403 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001405 }
1406}
1407
dbainbri4d3a0dc2020-12-02 00:33:42 +00001408func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001409
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001410 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001411 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001413 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001414 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1415 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001416 return
1417 }
mpagenko15ff4a52021-03-02 10:09:20 +00001418 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001420 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001421 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001422 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001423
Girish Gowdrae95687a2021-09-08 16:30:58 -07001424 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001425 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001427 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001428 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001429 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1430 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1431 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1432 // 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 +00001433 if oFsm.numVlanFilterEntries == 0 {
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.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001436 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001437 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001438 logger.Debugw(ctx, "UniVlanConfigFsm create 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,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001441 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001442 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001443 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001444
mpagenko01e726e2020-10-23 09:45:29 +00001445 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001446 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1447 oFsm.numVlanFilterEntries = 1
1448 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001449 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001450 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001451 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1452 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1453 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001454 },
1455 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001456 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001457 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1458 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001459 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001460 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001461 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001462 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1463 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001465 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001466 go func(a_pAFsm *cmn.AdapterFsm) {
1467 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001468 }(pConfigVlanStateAFsm)
1469 }
1470 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 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001480 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1481 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001482 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001483
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001485 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001486 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001487 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001488 // setVid is assumed to be masked already by the caller to 12 bit
1489 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001490 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001491 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001492
1493 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1494 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1495 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001496 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001497
1498 oFsm.numVlanFilterEntries++
1499 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001500 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001501 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001502 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1503 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1504 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001505 },
1506 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001507 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001508 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1509 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001510 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001511 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001512 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001513 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1514 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001516 return
1517 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001518 //accept also nil as (error) return value for writing to LastTx
1519 // - this avoids misinterpretation of new received OMCI messages
1520 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1521 // send shall return (dual format) error code that can be used here for immediate error treatment
1522 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001523 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001524 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001525 }
1526 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001527 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001528 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001529 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001531 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001532 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001533 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001534 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001535 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001536 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001537 return
1538 }
1539 }
mpagenkof1d21d12021-06-11 13:14:45 +00001540
mpagenkof1fc3862021-02-16 10:09:52 +00001541 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001542 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001543 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001544 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001545 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1546 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001547 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001548 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001549 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001550 //This is correct passing scenario
1551 if errEvto == nil {
1552 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001553 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001554 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001555 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001557 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001558 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001559 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001561 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001563 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001564 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001565 }
1566 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001567 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001568 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001569 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001570 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1571 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001572 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001573 if errCreateTrafficDescriptor != nil {
1574 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1575 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001576 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001577 }
1578 }
1579 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001580 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001581 }
1582 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001583}
1584
dbainbri4d3a0dc2020-12-02 00:33:42 +00001585func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001586 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001588 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1589 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001590
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001591 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1592 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001593 loVlanEntryClear := uint8(0)
1594 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1595 //shallow copy is sufficient as no reference variables are used within struct
1596 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001597 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001599 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1600 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1601 "device-id": oFsm.deviceID})
1602
1603 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1604 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001606 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1607 } else {
1608 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1609 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001610 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001611 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1612 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001614 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001615 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001616 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001617 loVlanEntryClear = 1 //full VlanFilter clear request
1618 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001619 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001620 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1621 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001622 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001623 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001624 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1625 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001626 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001627 return
1628 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001629 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001630 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001631 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001632 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001634 }
mpagenko01e726e2020-10-23 09:45:29 +00001635 } else {
1636 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1637 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001638 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001639 log.Fields{"current vlan list": oFsm.vlanFilterList,
1640 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1641 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1642 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1643 loVlanEntryRmPos = i
1644 break //abort search
1645 }
1646 }
1647 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001648 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001649 //valid entry was found - to be eclipsed
1650 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1651 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1652 if i < loVlanEntryRmPos {
1653 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1654 } else if i < (cVtfdTableSize - 1) {
1655 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1656 } else {
1657 vtfdFilterList[i] = 0 //set last byte if needed
1658 }
1659 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001660 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001661 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001662 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001663 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001664
mpagenkofc4f56e2020-11-04 17:17:49 +00001665 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001666 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001667 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001668 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1669 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001670 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001671 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001672 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1673 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001674 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001675 return
1676 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001677 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001678 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001679 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001680 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001682 }
mpagenko01e726e2020-10-23 09:45:29 +00001683 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001684 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001685 log.Fields{"device-id": oFsm.deviceID})
1686 }
1687 }
1688 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001689 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1690 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001692 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001694 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001695 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001696 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001697 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001698 }(pConfigVlanStateBaseFsm)
1699 return
1700 }
mpagenko01e726e2020-10-23 09:45:29 +00001701 }
1702
mpagenko15ff4a52021-03-02 10:09:20 +00001703 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001704 if loVlanEntryClear == 1 {
1705 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1706 oFsm.numVlanFilterEntries = 0
1707 } else if loVlanEntryClear == 2 {
1708 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1709 // this loop now includes the 0 element on previous last valid entry
1710 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1711 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1712 }
1713 oFsm.numVlanFilterEntries--
1714 }
mpagenko15ff4a52021-03-02 10:09:20 +00001715 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001716 }
1717 }
1718
mpagenkofc4f56e2020-11-04 17:17:49 +00001719 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001721 } else {
1722 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001724 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001725 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001726 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001727 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001728 }(pConfigVlanStateBaseFsm)
1729 }
mpagenkodff5dda2020-08-28 11:52:01 +00001730}
1731
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001733 var tpID uint8
1734 // Extract the tpID
1735 if len(e.Args) > 0 {
1736 tpID = e.Args[0].(uint8)
1737 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1738 } else {
1739 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1740 }
mpagenko01e726e2020-10-23 09:45:29 +00001741 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001742 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001743
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001744 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001745 if pConfigVlanStateAFsm == nil {
1746 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1747 log.Fields{"device-id": oFsm.deviceID})
1748 //would have to be fixed from outside somehow
1749 return
1750 }
1751
mpagenkof1d21d12021-06-11 13:14:45 +00001752 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1753 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001754 //call from 'configured' state of the rule
1755 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1756 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1757 oFsm.mutexFlowParams.Unlock()
1758 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001759 go func(a_pAFsm *cmn.AdapterFsm) {
1760 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001761 }(pConfigVlanStateAFsm)
1762 return
1763 }
mpagenkof1d21d12021-06-11 13:14:45 +00001764 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1765 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1766 oFsm.mutexFlowParams.Unlock()
1767 removeChannel <- true
1768 oFsm.mutexFlowParams.Lock()
1769 }
1770
mpagenkof1fc3862021-02-16 10:09:52 +00001771 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1772 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1773 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1774
Girish Gowdrae95687a2021-09-08 16:30:58 -07001775 // Store the reference to the flow response channel before this entry in the slice is deleted
1776 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1777
mpagenko01e726e2020-10-23 09:45:29 +00001778 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1779 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001780 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001781 "device-id": oFsm.deviceID})
1782 } else {
1783 //cut off the actual flow by slicing out the first element
1784 oFsm.uniRemoveFlowsSlice = append(
1785 oFsm.uniRemoveFlowsSlice[:0],
1786 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001788 "device-id": oFsm.deviceID})
1789 }
1790 oFsm.mutexFlowParams.Unlock()
1791
mpagenkof1fc3862021-02-16 10:09:52 +00001792 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001793 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001794 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001795 go func(a_pAFsm *cmn.AdapterFsm) {
1796 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001797 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001798
mpagenkobb47bc22021-04-20 13:29:09 +00001799 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001800 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001801 if deletedCookie == oFsm.delayNewRuleCookie {
1802 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1803 select {
1804 case <-oFsm.chCookieDeleted:
1805 logger.Debug(ctx, "flushed CookieDeleted")
1806 default:
1807 }
1808 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1809 }
mpagenkobb47bc22021-04-20 13:29:09 +00001810 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1811 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1812 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 -08001813 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001814 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1815 oFsm.flowDeleteChannel <- true
1816 oFsm.signalOnFlowDelete = false
1817 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001818 }
mpagenkobb47bc22021-04-20 13:29:09 +00001819 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001820
1821 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001822 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001823}
1824
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1826 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001827
mpagenko0f543222021-11-03 16:24:14 +00001828 oFsm.mutexPLastTxMeInstance.Lock()
1829 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1830 oFsm.mutexPLastTxMeInstance.Unlock()
1831
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001832 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001833 if pConfigVlanStateAFsm != nil {
1834 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001835 fsmAbortMsg := cmn.Message{
1836 Type: cmn.TestMsg,
1837 Data: cmn.TestMessage{
1838 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001839 },
1840 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001842
mpagenko0f543222021-11-03 16:24:14 +00001843 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1844 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1845
1846 oFsm.mutexFlowParams.RLock()
1847 if oFsm.delayNewRuleCookie != 0 {
1848 // looks like the waiting AddFlow is stuck
1849 oFsm.mutexFlowParams.RUnlock()
1850 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1851 select {
1852 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1853 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001854 }
mpagenko0f543222021-11-03 16:24:14 +00001855 oFsm.mutexFlowParams.RLock()
1856 }
1857 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1858 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1859 if removeUniFlowParams.isSuspendedOnAdd {
1860 removeChannel := removeUniFlowParams.removeChannel
1861 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1862 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1863 oFsm.mutexFlowParams.RUnlock()
1864 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1865 select {
1866 case removeChannel <- false:
1867 default:
1868 }
1869 oFsm.mutexFlowParams.RLock()
1870 }
1871 // Send response on response channel if the caller is waiting on it.
1872 var err error = nil
1873 if !oFsm.isCanceled {
1874 //only if the FSM is not canceled on external request use some error indication for the respChan
1875 // so only at real internal FSM abortion some error code is sent back
1876 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1877 err = fmt.Errorf("internal-error")
1878 }
1879 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1880 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1881 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1882 }
1883 }
1884
1885 if oFsm.pDeviceHandler != nil {
1886 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1887 if !oFsm.isCanceled {
1888 //if the FSM is not canceled on external request use "internal-error" for the respChan
1889 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1890 // Send response on response channel if the caller is waiting on it with according error indication.
1891 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1892 }
1893 //permanently remove possibly stored persistent data
1894 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1895 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1896 } else {
1897 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1898 // no need to remove specific data in this case here
1899 // TODO: cancelation may also abort a running flowAdd activity in which case it would be better
1900 // to also resopnd on the respChan with some error ("config canceled"), but that is a bit hard to decide here
1901 // so just left open by now
1902 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1903 }
1904 }
1905 oFsm.mutexFlowParams.RUnlock()
1906
1907 //try to let the FSM proceed to 'disabled'
1908 // Can't call FSM Event directly, decoupling it
1909 go func(a_pAFsm *cmn.AdapterFsm) {
1910 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1911 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1912 }
1913 }(pConfigVlanStateAFsm)
1914 return
1915 }
1916 oFsm.mutexFlowParams.RUnlock()
1917 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1918 log.Fields{"device-id": oFsm.deviceID})
1919 return
mpagenkodff5dda2020-08-28 11:52:01 +00001920 }
mpagenko0f543222021-11-03 16:24:14 +00001921 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1922 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001923}
1924
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1926 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001927
mpagenkodff5dda2020-08-28 11:52:01 +00001928 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001929 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001931 return
mpagenkodff5dda2020-08-28 11:52:01 +00001932 }
mpagenko0f543222021-11-03 16:24:14 +00001933 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1934 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001935}
1936
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1938 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001939loop:
1940 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001941 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001943 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001944 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301945 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301947 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001948 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301949 break loop
1950 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301952
1953 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001954 case cmn.TestMsg:
1955 msg, _ := message.Data.(cmn.TestMessage)
1956 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001958 break loop
1959 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001961 case cmn.OMCI:
1962 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301964 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301966 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001967 }
1968 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001970}
1971
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001972func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001974 "msgType": msg.OmciMsg.MessageType})
1975
1976 switch msg.OmciMsg.MessageType {
1977 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001978 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00001980 logger.Warnw(ctx, "CreateResponse handling aborted",
1981 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001982 return
1983 }
mpagenkodff5dda2020-08-28 11:52:01 +00001984 } //CreateResponseType
1985 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001986 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001987 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1988 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001990 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001991 return
1992 }
1993 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1994 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001995 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001996 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001997 return
1998 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002000 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002002 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00002003 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2004 return
2005 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002006 oFsm.mutexPLastTxMeInstance.RLock()
2007 if oFsm.pLastTxMeInstance != nil {
2008 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2009 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2010 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002011 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002012 { // let the MultiEntity config proceed by stopping the wait function
2013 oFsm.mutexPLastTxMeInstance.RUnlock()
2014 oFsm.omciMIdsResponseReceived <- true
2015 return
2016 }
2017 default:
2018 {
2019 logger.Warnw(ctx, "Unsupported ME name received!",
2020 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2021 }
mpagenkodff5dda2020-08-28 11:52:01 +00002022 }
2023 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002024 } else {
2025 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002026 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002027 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002028 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002029 case omci.DeleteResponseType:
2030 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002032 logger.Warnw(ctx, "DeleteResponse handling aborted",
2033 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002034 return
2035 }
2036 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002037 default:
2038 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002040 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002041 return
2042 }
2043 }
2044}
2045
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002047 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2048 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002050 log.Fields{"device-id": oFsm.deviceID})
2051 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2052 oFsm.deviceID)
2053 }
2054 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2055 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002057 log.Fields{"device-id": oFsm.deviceID})
2058 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2059 oFsm.deviceID)
2060 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002061 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002062 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002064 "Error": msgObj.Result})
2065 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2066 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2067 oFsm.deviceID)
2068 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002069 oFsm.mutexPLastTxMeInstance.RLock()
2070 if oFsm.pLastTxMeInstance != nil {
2071 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2072 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2073 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2074 switch oFsm.pLastTxMeInstance.GetName() {
2075 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2076 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002077 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002078 {
2079 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002080 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002081 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002083 } else { // let the MultiEntity config proceed by stopping the wait function
2084 oFsm.omciMIdsResponseReceived <- true
2085 }
2086 return nil
2087 }
2088 default:
2089 {
2090 logger.Warnw(ctx, "Unsupported ME name received!",
2091 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002092 }
2093 }
2094 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002095 } else {
2096 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002097 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002098 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002099 return nil
2100}
2101
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002103 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2104 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002105 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002106 log.Fields{"device-id": oFsm.deviceID})
2107 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2108 oFsm.deviceID)
2109 }
2110 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2111 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002112 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002113 log.Fields{"device-id": oFsm.deviceID})
2114 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2115 oFsm.deviceID)
2116 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002118 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002120 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2121 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2122 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2123 oFsm.deviceID)
2124 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002125 oFsm.mutexPLastTxMeInstance.RLock()
2126 if oFsm.pLastTxMeInstance != nil {
2127 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2128 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2129 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002130 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002131 { // let the MultiEntity config proceed by stopping the wait function
2132 oFsm.mutexPLastTxMeInstance.RUnlock()
2133 oFsm.omciMIdsResponseReceived <- true
2134 return nil
2135 }
2136 default:
2137 {
2138 logger.Warnw(ctx, "Unsupported ME name received!",
2139 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2140 }
mpagenko01e726e2020-10-23 09:45:29 +00002141 }
2142 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002143 } else {
2144 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002145 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002146 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002147 return nil
2148}
2149
dbainbri4d3a0dc2020-12-02 00:33:42 +00002150func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002151 oFsm.mutexFlowParams.RLock()
2152 evtocdID := oFsm.evtocdID
2153 oFsm.mutexFlowParams.RUnlock()
2154
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002155 if aFlowEntryNo == 0 {
2156 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002157 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2158 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002160 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002161 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002162 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002163 associationType := 2 // default to UniPPTP
2164 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002165 associationType = 10
2166 }
2167 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002168 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002169 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002170 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002171 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2172 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002173 },
2174 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002175 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002176 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2177 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002178 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002179 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002180 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2181 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002182 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002183 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2184 }
mpagenkodff5dda2020-08-28 11:52:01 +00002185 //accept also nil as (error) return value for writing to LastTx
2186 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002187 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002188 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002189
2190 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002191 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002192 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002193 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002194 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002195 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002196 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2197 }
2198
2199 // Set the EVTOCD ME default params
2200 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002201 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002202 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002203 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2204 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2205 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002206 },
2207 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002208 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002209 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2210 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2211 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002212 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002213 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002214 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2215 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002216 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002217 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2218 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002219 //accept also nil as (error) return value for writing to LastTx
2220 // - this avoids misinterpretation of new received OMCI messages
2221 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002222 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002223
2224 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002226 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002228 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002229 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002230 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002231 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002232 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002233
mpagenko551a4d42020-12-08 18:09:20 +00002234 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07002235 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002236 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002237 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002238 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002239 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002240 sliceEvtocdRule := make([]uint8, 16)
2241 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2242 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2243 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2244 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2245 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2246
2247 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2248 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2249 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2250 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2251 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2252
2253 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2254 0<<cTreatTTROffset| // Do not pop any tags
2255 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2256 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2257 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2258
2259 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2260 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2261 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2262 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2263
2264 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002265 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002266 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002267 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002268 },
2269 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002270 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002271 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2272 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2273 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002274 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002275 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002276 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2277 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002278 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002279 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2280 }
mpagenkodff5dda2020-08-28 11:52:01 +00002281 //accept also nil as (error) return value for writing to LastTx
2282 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002283 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002284 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002285
2286 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002287 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002288 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002289 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002290 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002291 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002292 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2293
mpagenkodff5dda2020-08-28 11:52:01 +00002294 }
2295 } else {
2296 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2297 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002298 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2299 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2300 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2301 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002302 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002303 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002304 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002305 sliceEvtocdRule := make([]uint8, 16)
2306 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2307 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2308 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2309 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2310 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2311
2312 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002313 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2314 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002315 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2316 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2317
2318 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002319 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002320 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2321 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2322 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2323
2324 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002325 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2326 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002327 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002328 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002329
2330 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002331 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002332 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002333 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002334 },
2335 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002336 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002337 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2338 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2339 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002340 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002341 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002342 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2343 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002344 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002345 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2346 }
mpagenkodff5dda2020-08-28 11:52:01 +00002347 //accept also nil as (error) return value for writing to LastTx
2348 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002349 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002350 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002351
2352 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002353 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002354 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002355 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002356 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002357 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002358 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002359 }
2360 } else {
2361 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2362 { // just for local var's
2363 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002364 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002365 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002366 sliceEvtocdRule := make([]uint8, 16)
2367 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2368 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2369 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2370 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2371 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2372
2373 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2374 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2375 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2376 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2377 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2378
2379 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2380 0<<cTreatTTROffset| // Do not pop any tags
2381 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2382 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2383 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2384
2385 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2386 0<<cTreatPrioOffset| // vlan prio set to 0
2387 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002388 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002389 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2390
mpagenko551a4d42020-12-08 18:09:20 +00002391 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002392 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002393 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002394 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002395 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002396 },
2397 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002398 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002399 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2400 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2401 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002402 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002403 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002404 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2405 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002407 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2408 }
mpagenkodff5dda2020-08-28 11:52:01 +00002409 //accept also nil as (error) return value for writing to LastTx
2410 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002411 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002412 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002413
2414 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002415 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002416 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002418 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002419 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002420 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2421
mpagenkodff5dda2020-08-28 11:52:01 +00002422 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002423 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002424 { // just for local var's
2425 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002426 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002427 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002428 sliceEvtocdRule := make([]uint8, 16)
2429 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2430 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2431 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2432 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2433 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2434
2435 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2436 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2437 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2438 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2439 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2440
2441 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2442 1<<cTreatTTROffset| // pop the prio-tag
2443 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2444 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2445 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2446
mpagenko551a4d42020-12-08 18:09:20 +00002447 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002448 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2449 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2450 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002451 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002452 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002453 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002454
2455 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002456 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002457 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002458 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002459 },
2460 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002462 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2463 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2464 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002465 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002466 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002467 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2468 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002469 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002470 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2471 }
mpagenkodff5dda2020-08-28 11:52:01 +00002472 //accept also nil as (error) return value for writing to LastTx
2473 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002474 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002475 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002476
2477 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002478 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002479 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002480 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002481 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002482 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002483 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2484
mpagenkodff5dda2020-08-28 11:52:01 +00002485 }
2486 } //just for local var's
2487 }
2488 }
2489
mpagenkofc4f56e2020-11-04 17:17:49 +00002490 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002491 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002492 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002493 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002494 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002495 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002496}
2497
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002498func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002499 oFsm.mutexFlowParams.RLock()
2500 evtocdID := oFsm.evtocdID
2501 oFsm.mutexFlowParams.RUnlock()
2502
mpagenko01e726e2020-10-23 09:45:29 +00002503 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2504 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2505 //transparent transmission was set
2506 //perhaps the config is not needed for removal,
2507 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002508 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002509 "device-id": oFsm.deviceID})
2510 sliceEvtocdRule := make([]uint8, 16)
2511 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2512 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2513 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2514 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2515 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2516
2517 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2518 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2519 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2520 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2521 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2522
2523 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2524 0<<cTreatTTROffset| // Do not pop any tags
2525 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2526 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2527 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2528
2529 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2530 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2531 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2532 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2533
2534 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002535 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002536 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002537 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002538 },
2539 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002540 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002541 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2542 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2543 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002544 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002545 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002546 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2547 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002548 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002549 return
2550 }
mpagenko01e726e2020-10-23 09:45:29 +00002551 //accept also nil as (error) return value for writing to LastTx
2552 // - this avoids misinterpretation of new received OMCI messages
2553 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002554 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002555
2556 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002557 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002558 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002559 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002560 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002561 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002562 return
2563 }
2564 } else {
2565 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002566 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002567 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002568 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002569 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002571 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2572 sliceEvtocdRule := make([]uint8, 16)
2573 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2574 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2575 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2576 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2577 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2578
2579 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2580 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2581 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2582 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2583 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2584
2585 // delete indication for the indicated Filter
2586 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2587 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2588
2589 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002590 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002591 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002592 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002593 },
2594 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002595 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002596 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2597 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2598 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002599 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002600 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002601 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2602 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002603 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002604 return
2605 }
mpagenko01e726e2020-10-23 09:45:29 +00002606 //accept also nil as (error) return value for writing to LastTx
2607 // - this avoids misinterpretation of new received OMCI messages
2608 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002609 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002610
2611 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002612 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002613 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002614 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002615 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002617 return
2618 }
2619 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002620 // VOL-3685
2621 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2622 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2623 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2624 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2625 // later when the flow is being re-installed.
2626 // Of course this is applicable to case only where single service (or single tcont) is in use and
2627 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2628 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2629 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002630 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002631 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002632 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002633 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2634 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002635 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002636 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002637 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002638 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002639 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2640 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2641 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002642 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002643 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002644 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2645 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002646 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002647 return
2648 }
mpagenko01e726e2020-10-23 09:45:29 +00002649 //accept also nil as (error) return value for writing to LastTx
2650 // - this avoids misinterpretation of new received OMCI messages
2651 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002652 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002653
2654 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002655 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002656 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002657 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002658 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002659 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002660 return
2661 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002662 } else {
2663 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2664 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002665 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002666 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002667 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002668 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2669 { // just for local var's
2670 // this defines stacking scenario: untagged->singletagged
2671 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2672 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2673 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2674 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002675 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002676 "device-id": oFsm.deviceID})
2677 sliceEvtocdRule := make([]uint8, 16)
2678 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2679 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2680 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2681 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2682 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002683
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002684 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2685 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2686 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2687 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2688 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002689
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002690 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2691 0<<cTreatTTROffset| // Do not pop any tags
2692 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2693 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2694 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002695
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002696 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2697 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2698 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2699 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002700
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002701 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002702 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002703 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002704 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002705 },
2706 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002707 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002708 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2709 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2710 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002711 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002712 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002713 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2714 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002715 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002716 return
2717 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002718 //accept also nil as (error) return value for writing to LastTx
2719 // - this avoids misinterpretation of new received OMCI messages
2720 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002721 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002722
2723 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002724 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002725 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002726 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002727 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002728 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002729 return
2730 }
2731 } // just for local var's
2732 { // just for local var's
2733 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002734 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002735 "device-id": oFsm.deviceID})
2736 sliceEvtocdRule := make([]uint8, 16)
2737 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2738 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2739 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2740 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2741 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2742
2743 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2744 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2745 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2746 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2747 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2748
2749 // delete indication for the indicated Filter
2750 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2751 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2752
2753 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002754 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002756 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002757 },
2758 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002759 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002760 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2761 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2762 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002763 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002764 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002765 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2766 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002768 return
2769 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002770 //accept also nil as (error) return value for writing to LastTx
2771 // - this avoids misinterpretation of new received OMCI messages
2772 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002773 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002774
2775 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002776 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002777 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002778 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002779 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002780 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002781 return
2782 }
mpagenko01e726e2020-10-23 09:45:29 +00002783 }
2784 } //just for local var's
2785 }
2786 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002787 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002788 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002790}
2791
dbainbri4d3a0dc2020-12-02 00:33:42 +00002792func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002793 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002794 if oFsm.isCanceled {
2795 // FSM already canceled before entering wait
2796 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2797 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002798 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002799 }
mpagenko7d6bb022021-03-11 15:07:55 +00002800 oFsm.isAwaitingResponse = true
2801 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002802 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302803 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002804 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002806 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002808 oFsm.mutexIsAwaitingResponse.Lock()
2809 oFsm.isAwaitingResponse = false
2810 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002811 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002812 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302813 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002814 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002815 oFsm.mutexIsAwaitingResponse.Lock()
2816 oFsm.isAwaitingResponse = false
2817 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002818 return nil
2819 }
mpagenko7d6bb022021-03-11 15:07:55 +00002820 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002821 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002822 oFsm.mutexIsAwaitingResponse.Lock()
2823 oFsm.isAwaitingResponse = false
2824 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002825 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002826 }
2827}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002828
mpagenko551a4d42020-12-08 18:09:20 +00002829func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002831 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002832 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002833 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002834 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002835 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002836 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002837 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2838 }
2839
dbainbri4d3a0dc2020-12-02 00:33:42 +00002840 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002841 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002842 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002844 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2846 }
2847
dbainbri4d3a0dc2020-12-02 00:33:42 +00002848 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002849 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002850 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002851 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002852 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002853 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2854 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002855 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002856 if errMacBpCdEID != nil {
2857 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2858 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002860 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002861
Mahir Gunyel6781f962021-05-16 23:30:08 -07002862 }
2863 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002864 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2865 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002866 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002867 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002868 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002869 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2870 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2871 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2872 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002873 },
2874 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002875 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002876 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2877 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002878 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002879 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002880 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2881 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002883 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2884 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002885 //accept also nil as (error) return value for writing to LastTx
2886 // - this avoids misinterpretation of new received OMCI messages
2887 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002888 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002889 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002890 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002892 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2893 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002894 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2895 }
2896
2897 // ==> Start creating VTFD for mcast vlan
2898
2899 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2900 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002901 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002902
dbainbri4d3a0dc2020-12-02 00:33:42 +00002903 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002904 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002906 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2907
2908 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2909 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2910 // new vlan associated with a different TP.
2911 vtfdFilterList[0] = uint16(vlanID)
2912
2913 meParams = me.ParamData{
2914 EntityID: mcastVtfdID,
2915 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002916 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
2917 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
2918 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002919 },
2920 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002921 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2923 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002924 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002925 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002926 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2927 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002928 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002929 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2930 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002931 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002932 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002935 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002936 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002937 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2939 }
2940
2941 return nil
2942}
2943
dbainbri4d3a0dc2020-12-02 00:33:42 +00002944func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002945 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002947 logger.Errorw(ctx, "error generrating me instance id",
2948 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002949 return err
2950 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002951 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2952 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 meParams := me.ParamData{
2954 EntityID: instID,
2955 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002956 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002957 //Direct reference to the Operation profile
2958 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002959 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002960 },
2961 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002962 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002963 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
2964 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2965 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002966 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002967 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002968 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2969 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002970 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002971 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2972 oFsm.deviceID, err)
2973 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002974 //accept also nil as (error) return value for writing to LastTx
2975 // - this avoids misinterpretation of new received OMCI messages
2976 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002977 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002978 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002979 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002980 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002981 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002982 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2983 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2984 }
2985 return nil
2986}
2987
dbainbri4d3a0dc2020-12-02 00:33:42 +00002988func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002989 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002990 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002991 logger.Errorw(ctx, "error generating me instance id",
2992 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002993 return err
2994 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002995 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2996 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002997 meParams := me.ParamData{
2998 EntityID: instID,
2999 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003000 me.MulticastOperationsProfile_IgmpVersion: 2,
3001 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003002 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003003 me.MulticastOperationsProfile_ImmediateLeave: 0,
3004 me.MulticastOperationsProfile_Robustness: 2,
3005 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3006 me.MulticastOperationsProfile_QueryInterval: 125,
3007 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3008 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003009 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003010 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003011 },
3012 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003013 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003014 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3015 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3016 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003017 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003018 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003019 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3020 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003021 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003022 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3023 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003024 //accept also nil as (error) return value for writing to LastTx
3025 // - this avoids misinterpretation of new received OMCI messages
3026 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003027 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003028 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003029 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003030 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003031 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003032 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003033 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003034 }
3035 return nil
3036}
3037
dbainbri4d3a0dc2020-12-02 00:33:42 +00003038func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003039 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003040 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003041 logger.Errorw(ctx, "error generating me instance id",
3042 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003043 return err
3044 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003045 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3046 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003047 //TODO check that this is correct
3048 // Table control
3049 //setCtrl = 1
3050 //rowPartId = 0
3051 //test = 0
3052 //rowKey = 0
3053 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003054 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003055 dynamicAccessCL := make([]uint8, 24)
3056 copy(dynamicAccessCL, tableCtrl)
3057 //Multicast GemPortId
3058 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3059 // python version waits for installation of flows, see line 723 onward of
3060 // brcm_openomci_onu_handler.py
3061 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3062 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003063 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003064 //TODO start and end are hardcoded, get from TP
3065 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003066 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003067 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003068 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003069 //imputed group bandwidth
3070 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3071
3072 meParams := me.ParamData{
3073 EntityID: instID,
3074 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003075 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003076 },
3077 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003078 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003079 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3080 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3081 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003082 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003083 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003084 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3085 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003086 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003087 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3088 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003089 //accept also nil as (error) return value for writing to LastTx
3090 // - this avoids misinterpretation of new received OMCI messages
3091 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003092 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003093 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003094 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003095 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003096 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003097 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003098 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003099 }
3100 return nil
3101}
Girish Gowdra26a40922021-01-29 17:14:34 -08003102
khenaidoo42dcdfd2021-10-19 17:34:12 -04003103func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003104 tpID uint8, uniID uint8, gemPortID uint16) error {
3105 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3106 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3107 // I created unique TD ID by flow direction.
3108 // TODO! Traffic descriptor ME ID will check
3109 trafficDescriptorID := gemPortID
3110 if aMeter == nil {
3111 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3112 }
3113 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3114 if err != nil {
3115 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3116 return err
3117 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003118 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003119 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003120 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003121 pbs := trafficShapingInfo.Pbs
3122
3123 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3124 meParams := me.ParamData{
3125 EntityID: trafficDescriptorID,
3126 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003127 me.TrafficDescriptor_Cir: cir,
3128 me.TrafficDescriptor_Pir: pir,
3129 me.TrafficDescriptor_Cbs: cbs,
3130 me.TrafficDescriptor_Pbs: pbs,
3131 me.TrafficDescriptor_ColourMode: 1,
3132 me.TrafficDescriptor_IngressColourMarking: 3,
3133 me.TrafficDescriptor_EgressColourMarking: 3,
3134 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003135 },
3136 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003137 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3139 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003140 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003141 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003142 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3143 return err
3144 }
3145 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003146 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003147 err = oFsm.waitforOmciResponse(ctx)
3148 if err != nil {
3149 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3150 return err
3151 }
3152
Girish Gowdra09e5f212021-09-30 16:28:36 -07003153 // 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
3154 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003155 if err != nil {
3156 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3157 return err
3158 }
3159 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3160
3161 return nil
3162}
3163
Girish Gowdra09e5f212021-09-30 16:28:36 -07003164func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3165 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3166 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003167 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003168 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003169 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003170 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003171 },
3172 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003173 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003174 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3175 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003176 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003177 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003178 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3179 return err
3180 }
3181 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003182 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003183 err = oFsm.waitforOmciResponse(ctx)
3184 if err != nil {
3185 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3186 return err
3187 }
3188 return nil
3189}
3190
Girish Gowdra26a40922021-01-29 17:14:34 -08003191// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003192func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3193 if oFsm == nil {
3194 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3195 return false
3196 }
mpagenkobb47bc22021-04-20 13:29:09 +00003197 oFsm.mutexFlowParams.Lock()
3198 defer oFsm.mutexFlowParams.Unlock()
3199 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3200 //flow removal is still ongoing/pending
3201 oFsm.signalOnFlowDelete = true
3202 oFsm.flowDeleteChannel = aFlowDeleteChannel
3203 return true
3204 }
3205 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003206}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003207
3208func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3209 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3210 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3211 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3212 log.Fields{"device-id": oFsm.deviceID})
3213 } else {
3214 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3215 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3216 "index": oFsm.numVlanFilterEntries,
3217 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3218 "device-id": oFsm.deviceID})
3219 oFsm.numVlanFilterEntries++
3220 }
3221}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003222
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003223// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3224func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003225 if respChan != nil {
3226 // Do it in a non blocking fashion, so that in case the flow handler routine has shutdown for any reason, we do not block here
3227 select {
3228 case *respChan <- err:
3229 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3230 default:
3231 }
3232 }
3233}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003234
3235// PrepareForGarbageCollection - remove references to prepare for garbage collection
3236func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3237 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3238 oFsm.pDeviceHandler = nil
3239 oFsm.pOnuDeviceEntry = nil
3240 oFsm.pOmciCC = nil
3241}