blob: 48353b9d4379aa3e6a946c88dd8e1327233592e1 [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
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +053086 cCopyPrioFromOuter uint32 = 9
Himani Chawla4d908332020-08-31 12:30:20 +053087 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000088 cDontCareVid uint32 = 0
89 cDontCareTpid uint32 = 0
90 cSetOutputTpidCopyDei uint32 = 4
91)
92
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000093// events of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +000094const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000095 VlanEvStart = "VlanEvStart"
96 VlanEvPrepareDone = "VlanEvPrepareDone"
97 VlanEvWaitTechProf = "VlanEvWaitTechProf"
98 VlanEvCancelOutstandingConfig = "VlanEvCancelOutstandingConfig"
99 VlanEvContinueConfig = "VlanEvContinueConfig"
100 VlanEvStartConfig = "VlanEvStartConfig"
101 VlanEvRxConfigVtfd = "VlanEvRxConfigVtfd"
102 VlanEvRxConfigEvtocd = "VlanEvRxConfigEvtocd"
103 VlanEvWaitTPIncr = "VlanEvWaitTPIncr"
104 VlanEvIncrFlowConfig = "VlanEvIncrFlowConfig"
105 VlanEvRenew = "VlanEvRenew"
106 VlanEvRemFlowConfig = "VlanEvRemFlowConfig"
107 VlanEvRemFlowDone = "VlanEvRemFlowDone"
108 VlanEvFlowDataRemoved = "VlanEvFlowDataRemoved"
109 //VlanEvTimeoutSimple = "VlanEvTimeoutSimple"
110 //VlanEvTimeoutMids = "VlanEvTimeoutMids"
111 VlanEvReset = "VlanEvReset"
112 VlanEvRestart = "VlanEvRestart"
113 VlanEvSkipOmciConfig = "VlanEvSkipOmciConfig"
114 VlanEvSkipIncFlowConfig = "VlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000115)
mpagenko01e726e2020-10-23 09:45:29 +0000116
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117// states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000118const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 VlanStDisabled = "VlanStDisabled"
120 VlanStPreparing = "VlanStPreparing"
121 VlanStStarting = "VlanStStarting"
122 VlanStWaitingTechProf = "VlanStWaitingTechProf"
123 VlanStConfigVtfd = "VlanStConfigVtfd"
124 VlanStConfigEvtocd = "VlanStConfigEvtocd"
125 VlanStConfigDone = "VlanStConfigDone"
126 VlanStIncrFlowWaitTP = "VlanStIncrFlowWaitTP"
127 VlanStConfigIncrFlow = "VlanStConfigIncrFlow"
128 VlanStRemoveFlow = "VlanStRemoveFlow"
129 VlanStCleanupDone = "VlanStCleanupDone"
130 VlanStResetting = "VlanStResetting"
mpagenkodff5dda2020-08-28 11:52:01 +0000131)
132
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000133// CVlanFsmIdleState - TODO: add comment
134const CVlanFsmIdleState = VlanStConfigDone // state where no OMCI activity is done (for a longer time)
135// CVlanFsmConfiguredState - TODO: add comment
136const CVlanFsmConfiguredState = VlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenko01e726e2020-10-23 09:45:29 +0000137
138type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000139 isSuspendedOnAdd bool
140 removeChannel chan bool
141 cookie uint64 //just the last cookie valid for removal
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000142 vlanRuleParams cmn.UniVlanRuleParams
Girish Gowdrae95687a2021-09-08 16:30:58 -0700143 respChan *chan error
mpagenko01e726e2020-10-23 09:45:29 +0000144}
145
mpagenkobb47bc22021-04-20 13:29:09 +0000146//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000148type UniVlanConfigFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000149 pDeviceHandler cmn.IdeviceHandler
150 pOnuDeviceEntry cmn.IonuDeviceEntry
mpagenko01e726e2020-10-23 09:45:29 +0000151 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 pOmciCC *cmn.OmciCC
153 pOnuUniPort *cmn.OnuUniPort
154 pUniTechProf *OnuUniTechProf
155 pOnuDB *devdb.OnuDeviceDB
156 requestEvent cmn.OnuDeviceEvent
mpagenkodff5dda2020-08-28 11:52:01 +0000157 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000158 PAdaptFsm *cmn.AdapterFsm
mpagenkodff5dda2020-08-28 11:52:01 +0000159 acceptIncrementalEvtoOption bool
mpagenkocf48e452021-04-23 09:23:00 +0000160 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000161 isAwaitingResponse bool
162 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000163 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000164 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
Girish Gowdrae95687a2021-09-08 16:30:58 -0700165 actualUniFlowParam cmn.UniVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000166 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000167 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168 NumUniFlows uint8 // expected number of flows should be less than 12
169 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000170 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000171 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000172 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000174 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000175 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000176 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000177 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000178 signalOnFlowDelete bool
179 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000180 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
181 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200182 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
183 // thus notification needs to be sent on chan.
184 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000185}
186
mpagenko01e726e2020-10-23 09:45:29 +0000187//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
188// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000189func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
190 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
191 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530192 aCookieSlice []uint64, aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, lastFlowToRec bool, aMeter *of.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000193 instFsm := &UniVlanConfigFsm{
194 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000195 pOnuDeviceEntry: apOnuDeviceEntry,
196 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000197 pOmciCC: apDevOmciCC,
198 pOnuUniPort: apUniPort,
199 pUniTechProf: apUniTechProf,
200 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000201 requestEvent: aRequestEvent,
202 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000203 NumUniFlows: 0,
204 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000205 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200206 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000207 }
208
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000209 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
210 if instFsm.PAdaptFsm == nil {
211 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000212 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700213 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000214 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000215 return nil
216 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000217 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
218 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000219 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000220 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
221 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
222 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
223 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
224 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
225 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
226 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
227 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
228 Dst: VlanStConfigDone},
229 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
230 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
231 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
232 Dst: VlanStConfigIncrFlow},
233 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
234 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
235 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000236 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000237 {Name: VlanEvTimeoutSimple, Src: []string{
238 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
239 {Name: VlanEvTimeoutMids, Src: []string{
240 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000241 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000242 // exceptional treatment for all states except VlanStResetting
243 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
244 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
245 VlanStRemoveFlow, VlanStCleanupDone},
246 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000247 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000249 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
251 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
252 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000253 },
mpagenkodff5dda2020-08-28 11:52:01 +0000254 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000255 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
256 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
257 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
258 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
259 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
260 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
261 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
262 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
263 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
264 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
265 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000266 },
267 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000268 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000270 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700271 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000272 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000273 return nil
274 }
275
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530276 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, aMeter, respChan)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000278 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return instFsm
280}
281
mpagenko01e726e2020-10-23 09:45:29 +0000282//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000283func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530284 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000285 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530286 TpID: aTpID,
287 MatchVid: uint32(aMatchVlan),
288 MatchPcp: uint32(aMatchPcp),
289 SetVid: uint32(aSetVlan),
290 SetPcp: uint32(aSetPcp),
291 InnerCvlan: innerCvlan,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000292 }
293 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +0530294 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000298 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
300 } else {
301 if !oFsm.acceptIncrementalEvtoOption {
302 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000303 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000304 }
305 }
306
mpagenko01e726e2020-10-23 09:45:29 +0000307 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000308 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.TagsToRemove = 0 //no tag pop action
310 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
311 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000312 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
313 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
314 // might collide with NoMatchVid/CopyPrio(/setVid) setting
315 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000316 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000317 }
318 }
mpagenko01e726e2020-10-23 09:45:29 +0000319
Girish Gowdrae95687a2021-09-08 16:30:58 -0700320 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000321 loFlowParams.CookieSlice = make([]uint64, 0)
322 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300323 if aMeter != nil {
324 loFlowParams.Meter = aMeter
325 }
mpagenko01e726e2020-10-23 09:45:29 +0000326
327 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000329 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000331 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
332 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
333 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
334 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000338 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
339 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000340 //cmp also usage in EVTOCDE create in omci_cc
341 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000342 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000343 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
344
345 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000347 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000349 return err
350 }
351
352 return nil
353}
354
mpagenko7d6bb022021-03-11 15:07:55 +0000355//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000356func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000357 if oFsm == nil {
358 logger.Error(ctx, "no valid UniVlanConfigFsm!")
359 return
360 }
mpagenko7d6bb022021-03-11 15:07:55 +0000361 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000362 oFsm.mutexIsAwaitingResponse.Lock()
363 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000364 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000365 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
366 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
367 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000368 //use channel to indicate that the response waiting shall be aborted
369 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000370 } else {
371 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000372 }
mpagenkocf48e452021-04-23 09:23:00 +0000373
mpagenko7d6bb022021-03-11 15:07:55 +0000374 // 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 +0000375 PAdaptFsm := oFsm.PAdaptFsm
376 if PAdaptFsm != nil {
377 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000378 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000380 }
mpagenko7d6bb022021-03-11 15:07:55 +0000381 }
382}
383
mpagenko551a4d42020-12-08 18:09:20 +0000384//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000385func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
386 if oFsm == nil {
387 logger.Error(ctx, "no valid UniVlanConfigFsm!")
388 return 0
389 }
mpagenko551a4d42020-12-08 18:09:20 +0000390 //mutex protection is required for possible concurrent access to FSM members
391 oFsm.mutexFlowParams.RLock()
392 defer oFsm.mutexFlowParams.RUnlock()
393 return oFsm.TpIDWaitingFor
394}
395
mpagenko01e726e2020-10-23 09:45:29 +0000396//SetUniFlowParams verifies on existence of flow parameters to be configured,
397// optionally udates the cookie list or appends a new flow if there is space
398// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000399// ignore complexity by now
400// nolint: gocyclo
401func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530402 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, aInnerCvlan uint16, lastFlowToReconcile bool, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000403 if oFsm == nil {
404 logger.Error(ctx, "no valid UniVlanConfigFsm!")
405 return fmt.Errorf("no-valid-UniVlanConfigFsm")
406 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530408 TpID: aTpID,
409 MatchVid: uint32(aMatchVlan),
410 MatchPcp: uint32(aMatchPcp),
411 SetVid: uint32(aSetVlan),
412 SetPcp: uint32(aSetPcp),
413 InnerCvlan: aInnerCvlan,
mpagenko01e726e2020-10-23 09:45:29 +0000414 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700415 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000416 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530417 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
mpagenko01e726e2020-10-23 09:45:29 +0000418 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
419 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
420 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
421 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
422 } else {
423 if !oFsm.acceptIncrementalEvtoOption {
424 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
425 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
426 }
427 }
428
429 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
430 // no prio/vid filtering requested
431 loRuleParams.TagsToRemove = 0 //no tag pop action
432 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
433 if loRuleParams.SetPcp == cCopyPrioFromInner {
434 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
435 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
436 // might collide with NoMatchVid/CopyPrio(/setVid) setting
437 // this was some precondition setting taken over from py adapter ..
438 loRuleParams.SetPcp = 0
439 }
440 }
441
mpagenkof1d21d12021-06-11 13:14:45 +0000442 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
443 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
444 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
445 oFsm.mutexFlowParams.RLock()
446 if len(oFsm.uniRemoveFlowsSlice) > 0 {
447 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
448 if removeUniFlowParams.vlanRuleParams == loRuleParams {
449 // the flow to add is the same as the one already in progress of deleting
450 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000451 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
452 if flow >= len(oFsm.uniRemoveFlowsSlice) {
453 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
454 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
455 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700456 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000457 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700458 return err
459
mpagenkof582d6a2021-06-18 15:58:10 +0000460 }
mpagenkof1d21d12021-06-11 13:14:45 +0000461 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
462 oFsm.mutexFlowParams.RUnlock()
463 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
464 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
465 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700466 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000467 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700468 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000469 }
470 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000471 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000472 }
473 }
474 }
475 oFsm.mutexFlowParams.RUnlock()
476
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000477 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000478 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000479 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200480 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000481 //mutex protection is required for possible concurrent access to FSM members
482 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000483 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
484 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
485 // countable run time optimization (perhaps with including the hash in kvStore storage?)
486 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000487 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000488 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300489 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
490 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
491 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000492 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000493 var cookieMatch bool
494 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
495 cookieMatch = false
496 for _, cookie := range storedUniFlowParams.CookieSlice {
497 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000498 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000499 "device-id": oFsm.deviceID, "cookie": cookie})
500 cookieMatch = true
501 break //found new cookie - no further search for this requested cookie
502 }
503 }
504 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000505 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
506 if delayedCookie != 0 {
507 //a delay for adding the cookie to this rule is requested
508 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
509 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000510 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
511 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
512 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700513 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000514 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700515 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000516 }
mpagenkobc4170a2021-08-17 16:42:10 +0000517 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000518 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000519 } else {
520 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
521 "device-id": oFsm.deviceID, "cookie": newCookie})
522 //as range works with copies of the slice we have to write to the original slice!!
523 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
524 newCookie)
525 flowCookieModify = true
526 }
mpagenko01e726e2020-10-23 09:45:29 +0000527 }
528 } //for all new cookies
529 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000530 }
531 }
mpagenkof1fc3862021-02-16 10:09:52 +0000532 oFsm.mutexFlowParams.Unlock()
533
534 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000535 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
536 if !deleteSuccess {
537 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
538 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700539 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000540 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700541 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000542 }
mpagenkof1fc3862021-02-16 10:09:52 +0000543 requestAppendRule = true //default assumption here is that rule is to be appended
544 flowCookieModify = true //and that the the flow data base is to be updated
545 if delayedCookie != 0 { //it was suspended
546 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
547 }
548 }
549 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
550 if requestAppendRule {
551 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000552 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700553 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000554 loFlowParams.CookieSlice = make([]uint64, 0)
555 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300556 if aMeter != nil {
557 loFlowParams.Meter = aMeter
558 }
mpagenko01e726e2020-10-23 09:45:29 +0000559 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000560 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000561 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000562 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
563 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
565 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000566
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000568 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
569 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 oFsm.NumUniFlows++
571 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000572
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000574 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000575 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000576 //attention: take care to release the mutexFlowParams when calling the FSM directly -
577 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000578 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000579 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
580 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000581 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700583 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000584 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700585 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000586 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000587 }
588 return nil
589 }
mpagenko01e726e2020-10-23 09:45:29 +0000590 // note: theoretical it would be possible to clear the same rule from the remove slice
591 // (for entries that have not yet been started with removal)
592 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
593 // 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 +0000594
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000596 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000597 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000598 // this is a restart with a complete new flow, we can re-use the initial flow config control
599 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000600 //attention: take care to release the mutexFlowParams when calling the FSM directly -
601 // synchronous FSM 'event/state' functions may rely on this mutex
602 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000603 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000604 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
605 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
606 }
mpagenko551a4d42020-12-08 18:09:20 +0000607 } else {
608 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000609 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000611 //check introduced after having observed some panic here
612 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000614 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
615 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700616 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000617 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700618 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000619 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700620
621 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000622 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700623 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000624 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700625 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000626 //attention: take care to release the mutexFlowParams when calling the FSM directly -
627 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000628 // but it must be released already before calling getTechProfileDone() as it may already be locked
629 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000630 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000631 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000632 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000633 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000634 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
635
mpagenkobb47bc22021-04-20 13:29:09 +0000636 var fsmErr error
637 if loTechProfDone {
638 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000639 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000640 } else {
641 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000643 }
644 if fsmErr != nil {
645 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
646 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000647 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700648 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000649 }
mpagenko551a4d42020-12-08 18:09:20 +0000650 }
mpagenkobb47bc22021-04-20 13:29:09 +0000651 } else {
652 // if not in the appropriate state a new entry will be automatically considered later
653 // when the configDone state is reached
654 oFsm.mutexFlowParams.Unlock()
655 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000658 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000659 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700660 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000661 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700662 return err
mpagenko01e726e2020-10-23 09:45:29 +0000663 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000664 } else {
665 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000666 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700667 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000668 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700669
mpagenko15ff4a52021-03-02 10:09:20 +0000670 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000672 //all requested rules really have been configured
673 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000674 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 if oFsm.pDeviceHandler != nil {
676 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000677 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000678 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000679 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
680 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000681 }
682 } else {
683 // avoid device reason update as the rule config connected to this flow may still be in progress
684 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000685 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000686 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000687 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000688 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000689 }
690 }
mpagenko01e726e2020-10-23 09:45:29 +0000691
mpagenkof1fc3862021-02-16 10:09:52 +0000692 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000693 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000694 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000695 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000696 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000697 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000699 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000700 }
mpagenko15ff4a52021-03-02 10:09:20 +0000701 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000702 }
703 return nil
704}
705
mpagenkof1d21d12021-06-11 13:14:45 +0000706func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
707 oFsm.mutexFlowParams.Lock()
708 deleteChannel := apRemoveFlowParams.removeChannel
709 apRemoveFlowParams.isSuspendedOnAdd = true
710 oFsm.mutexFlowParams.Unlock()
711
712 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
713 select {
714 case success := <-deleteChannel:
715 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
716 if success {
717 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
718 "device-id": oFsm.deviceID})
719 return nil
720 }
721 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
722 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
723 oFsm.mutexFlowParams.Lock()
724 if apRemoveFlowParams != nil {
725 apRemoveFlowParams.isSuspendedOnAdd = false
726 }
727 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000728 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000729 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000730 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000731 }
mpagenkof1d21d12021-06-11 13:14:45 +0000732}
733
mpagenkof1fc3862021-02-16 10:09:52 +0000734// VOL-3828 flow config sequence workaround ########### start ##########
735func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
736 //assumes mutexFlowParams.Lock() protection from caller!
737 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
738 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000739 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000740 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
741 newCookie := aCookieSlice[0]
742 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
743 for _, cookie := range storedUniFlowParams.CookieSlice {
744 if cookie == newCookie {
745 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
746 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
747 oFsm.delayNewRuleCookie = newCookie
748 return newCookie //found new cookie in some existing rule
749 }
750 } // for all stored cookies of the actual inspected rule
751 } //for all rules
752 }
753 return 0 //no delay requested
754}
mpagenkobc4170a2021-08-17 16:42:10 +0000755func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000756 oFsm.mutexFlowParams.RLock()
757 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
758 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
759 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000760 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000761 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000762 case cookieDeleted = <-oFsm.chCookieDeleted:
763 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
764 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000765 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000766 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
767 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
768 }
769 oFsm.mutexFlowParams.Lock()
770 oFsm.delayNewRuleCookie = 0
771 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000772 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000773}
mpagenkobc4170a2021-08-17 16:42:10 +0000774func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000775 oFsm.mutexFlowParams.Lock()
776 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
777 oFsm.mutexFlowParams.Unlock()
778
mpagenkobc4170a2021-08-17 16:42:10 +0000779 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000780 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000781 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000782 }
mpagenkobc4170a2021-08-17 16:42:10 +0000783 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000784}
785
786//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000787func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000788 flowEntryMatch := false
789 oFsm.mutexFlowParams.Lock()
790 defer oFsm.mutexFlowParams.Unlock()
791 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
792 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
793 flowEntryMatch = true
794 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
795 "device-id": oFsm.deviceID})
796 cookieMatch := false
797 for _, cookie := range storedUniFlowParams.CookieSlice {
798 if cookie == aCookie {
799 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
800 "device-id": oFsm.deviceID, "cookie": cookie})
801 cookieMatch = true
802 break //found new cookie - no further search for this requested cookie
803 }
804 }
805 if !cookieMatch {
806 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
807 "device-id": oFsm.deviceID, "cookie": aCookie})
808 //as range works with copies of the slice we have to write to the original slice!!
809 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
810 aCookie)
811 return true, false //flowModified, NoRuleAppend
812 }
813 break // found rule - no further rule search
814 }
815 }
816 if !flowEntryMatch { //it is a new rule
817 return true, true //flowModified, RuleAppend
818 }
819 return false, false //flowNotModified, NoRuleAppend
820}
821
822// VOL-3828 flow config sequence workaround ########### end ##########
823
mpagenko01e726e2020-10-23 09:45:29 +0000824//RemoveUniFlowParams verifies on existence of flow cookie,
825// if found removes cookie from flow cookie list and if this is empty
826// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700827func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000828 if oFsm == nil {
829 logger.Error(ctx, "no valid UniVlanConfigFsm!")
830 return fmt.Errorf("no-valid-UniVlanConfigFsm")
831 }
mpagenkof1fc3862021-02-16 10:09:52 +0000832 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000833 flowCookieMatch := false
834 //mutex protection is required for possible concurrent access to FSM members
835 oFsm.mutexFlowParams.Lock()
836 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000837remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000838 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
839 for i, cookie := range storedUniFlowParams.CookieSlice {
840 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000841 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000842 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000843 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000844 //remove the cookie from the cookie slice and verify it is getting empty
845 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000846 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700847 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000848 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000849 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000850 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000851 //cut off the requested cookie by slicing out this element
852 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
853 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
854 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000855 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
856 // state transition notification is checked in deviceHandler
857 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000858 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
859 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000860 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000862 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000863 if deletedCookie == oFsm.delayNewRuleCookie {
864 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
865 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
866 //simply use the first one
867 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
868 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
869 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
870 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700871 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000872 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000873 //permanently store the modified flow config for reconcile case and immediately write to KvStore
874 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000875 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000876 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
877 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
878 return err
879 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000880 }
mpagenko01e726e2020-10-23 09:45:29 +0000881 }
mpagenkof1fc3862021-02-16 10:09:52 +0000882 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000883 }
884 }
mpagenko01e726e2020-10-23 09:45:29 +0000885 } //search all flows
886 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000887 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000888 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
889 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000890 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
891 // state transition notification is checked in deviceHandler
892 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000893 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000894 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000895 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700896 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000897 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000898 return nil
899 } //unknown cookie
900
901 return nil
902}
903
mpagenkof582d6a2021-06-18 15:58:10 +0000904// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000905// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000906func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700907 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000908 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000909 var cancelPendingConfig bool = false
910 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
911 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
912 "device-id": oFsm.deviceID})
913 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
914 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
915 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
916 // 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 +0000917 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000918 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
919 log.Fields{"device-id": oFsm.deviceID})
920 cancelPendingConfig = true
921 } else {
922 //create a new element for the removeVlanFlow slice
923 loRemoveParams = uniRemoveVlanFlowParams{
924 vlanRuleParams: aUniFlowParams.VlanRuleParams,
925 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700926 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000927 }
928 loRemoveParams.removeChannel = make(chan bool)
929 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
930 }
931
932 usedTpID := aUniFlowParams.VlanRuleParams.TpID
933 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
934 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
935 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
936 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000937 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
938 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000939 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
940 "device-id": oFsm.deviceID})
941 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000942 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000943 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000944 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000945 }
946 } else {
947 if !cancelPendingConfig {
948 oFsm.updateTechProfileToDelete(ctx, usedTpID)
949 }
950 }
951 //trigger the FSM to remove the relevant rule
952 if cancelPendingConfig {
953 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000954 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000955 //call from 'non-configured' state of the rules
956 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
957 //something quite inconsistent detected, perhaps just try to recover with FSM reset
958 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000959 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000960 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
961 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
962 }
963 return false //data base update could not be done, return like cookie not found
964 }
965
966 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
967 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
968 // synchronous FSM 'event/state' functions may rely on this mutex
969 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000970 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000971 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
972 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
973 }
974 oFsm.mutexFlowParams.Lock()
975 return true
976 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000977 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000978 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000979 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000980 "tp-id": loRemoveParams.vlanRuleParams.TpID,
981 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
982 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
983 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
984 // synchronous FSM 'event/state' functions may rely on this mutex
985 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000986 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000987 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
988 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
989 }
990 oFsm.mutexFlowParams.Lock()
991 } // if not in the appropriate state a new entry will be automatically considered later
992 // when the configDone state is reached
993 return true
994}
995
mpagenkof1d21d12021-06-11 13:14:45 +0000996//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
997// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
998// from the start of the deletion request to avoid to much interference
999// so when called, there can only be one cookie active for this flow
1000// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001001func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001002 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1003 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001004 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001005removeFromSlice_loop:
1006 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001007 // if UniFlowParams exists, cookieSlice should always have at least one element
1008 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1009 if cookieSliceLen == 1 {
1010 if storedUniFlowParams.CookieSlice[0] == aCookie {
1011 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001012 }
mpagenkof582d6a2021-06-18 15:58:10 +00001013 } else if cookieSliceLen == 0 {
1014 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1015 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1016 return errors.New(errStr)
1017 } else {
1018 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1019 logger.Errorw(ctx, errStr, log.Fields{
1020 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1021 for _, cookie := range storedUniFlowParams.CookieSlice {
1022 if cookie == aCookie {
1023 cookieFound = true
1024 break
1025 }
1026 }
1027 }
1028 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001029 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1030 "device-id": oFsm.deviceID, "cookie": aCookie})
1031 //remove the actual element from the addVlanFlow slice
1032 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1033 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001034 oFsm.NumUniFlows = 0 //no more flows
1035 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001036 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1037 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1038 //request that this profile gets deleted before a new flow add is allowed
1039 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1040 "device-id": oFsm.deviceID})
1041 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001042 oFsm.NumUniFlows--
1043 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1044 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001045 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001046 if !aWasConfigured {
1047 // We did not actually process this flow but was removed before that.
1048 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001049 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001050 }
1051
mpagenkof1d21d12021-06-11 13:14:45 +00001052 //cut off the requested flow by slicing out this element
1053 oFsm.uniVlanFlowParamsSlice = append(
1054 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1055 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1056 "device-id": oFsm.deviceID})
1057 }
1058 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1059 }
1060 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001061 if !cookieFound {
1062 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1063 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1064 return errors.New(errStr)
1065 }
mpagenkodee02a62021-07-21 10:56:10 +00001066 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1067 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001068 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001069 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1070 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1071 return err
1072 }
mpagenkof582d6a2021-06-18 15:58:10 +00001073 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001074}
1075
1076// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001077func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1078 //here we have to check, if there are still other flows referencing to the actual ProfileId
1079 // before we can request that this profile gets deleted before a new flow add is allowed
1080 tpIDInOtherFlows := false
1081 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1082 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1083 tpIDInOtherFlows = true
1084 break // search loop can be left
1085 }
1086 }
1087 if tpIDInOtherFlows {
1088 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1089 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1090 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001091 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 +00001092 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001093 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1094 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001095 if oFsm.pUniTechProf != nil {
1096 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001097 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001098 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001099 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001100 }
1101}
1102
mpagenkof1d21d12021-06-11 13:14:45 +00001103func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1104 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001105
1106 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001107 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001108 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001109 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001110 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001112 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001113 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001114 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001115 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001116 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001117 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001118 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001119 go func(a_pAFsm *cmn.AdapterFsm) {
1120 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001121 }(pConfigVlanStateAFsm)
1122 return
1123 }
mpagenkof1d21d12021-06-11 13:14:45 +00001124 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001125 go func(a_pAFsm *cmn.AdapterFsm) {
1126 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001127 }(pConfigVlanStateAFsm)
1128 return
1129 }
1130 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1131 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1132 //should never happen, else: recovery would be needed from outside the FSM
1133}
1134
1135func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1136 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001137 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001138 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001139 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001140 //possibly the entry is not valid anymore based on intermediate delete requests
1141 //just a basic protection ...
1142 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1143 oFsm.mutexFlowParams.Unlock()
1144 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1145 "device-id": oFsm.deviceID})
1146 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001147 go func(a_pAFsm *cmn.AdapterFsm) {
1148 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001149 }(pConfigVlanStateAFsm)
1150 return
1151 }
mpagenko9a304ea2020-12-16 15:54:01 +00001152 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1153 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001154 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1155 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001156 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001157 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001158 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1159 // synchronous FSM 'event/state' functions may rely on this mutex
1160 // but it must be released already before calling getTechProfileDone() as it may already be locked
1161 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001162 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001163 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001164 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001165 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001166 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001167
mpagenko9a304ea2020-12-16 15:54:01 +00001168 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001169 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1170 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001171 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001172 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001173 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001174 } else {
1175 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001176 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001177 }
1178 }
mpagenko551a4d42020-12-08 18:09:20 +00001179 }(pConfigVlanStateAFsm, loTechProfDone)
1180 } else {
1181 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1182 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1183 //should never happen, else: recovery would be needed from outside the FSM
1184 return
mpagenkodff5dda2020-08-28 11:52:01 +00001185 }
1186}
1187
dbainbri4d3a0dc2020-12-02 00:33:42 +00001188func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001189 //mutex protection is required for possible concurrent access to FSM members
1190 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001191 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001192 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001193 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001194 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001195 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001196 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001197 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001198 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001199 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001200 go func(a_pAFsm *cmn.AdapterFsm) {
1201 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001202 }(pConfigVlanStateAFsm)
1203 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001204 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1205 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001206 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001207 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001208 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001209 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001210 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001211 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001212 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001213 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001214 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001215 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1216 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001217 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001218 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001219 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001220 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1221 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1222 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001223 },
1224 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001226 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001227 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001228 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1229 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001230 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001231 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001232 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1233 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001234 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001235 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001236 go func(a_pAFsm *cmn.AdapterFsm) {
1237 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001238 }(pConfigVlanStateAFsm)
1239 }
1240 return
1241 }
mpagenkodff5dda2020-08-28 11:52:01 +00001242 //accept also nil as (error) return value for writing to LastTx
1243 // - this avoids misinterpretation of new received OMCI messages
1244 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1245 // send shall return (dual format) error code that can be used here for immediate error treatment
1246 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001247 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001248 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001249 }
1250}
1251
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1253 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001254 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001255 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001256 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001257 //using the first element in the slice because it's the first flow per definition here
1258 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001259 //This is correct passing scenario
1260 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001261 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001262 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1263 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001264 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001265 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1266 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001267 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001268 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001270 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001271 vlanID)
1272 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001274 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001275 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001276 }
1277 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001278 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001279 if oFsm.actualUniFlowParam.Meter != nil {
1280 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001281 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001282 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1283 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001284 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001285 if errCreateTrafficDescriptor != nil {
1286 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1287 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001289 }
1290 }
1291 }
1292
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001293 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001295 }
1296 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001297}
1298
dbainbri4d3a0dc2020-12-02 00:33:42 +00001299func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001300
mpagenkof1d21d12021-06-11 13:14:45 +00001301 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001302
mpagenkof1fc3862021-02-16 10:09:52 +00001303 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001304 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001305 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001306 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001307 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001308 }
1309
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001311 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001312 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001313 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1314 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1315 //should never happen, else: recovery would be needed from outside the FSM
1316 return
1317 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001319 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1320 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001321 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001322 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001323 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1324 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001325 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001326 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001327 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001328 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001329 }(pConfigVlanStateBaseFsm)
1330 return
1331 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001332 if oFsm.lastFlowToReconcile {
1333 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1334 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1335 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1336 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1337 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1338 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1340 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001341 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001342 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001343 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001344 return
1345 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001346 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1347 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001348 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001349 // this is a restart with a complete new flow, we can re-use the initial flow config control
1350 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001351 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001352 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001353 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001354 }(pConfigVlanStateBaseFsm)
1355 return
1356 }
1357
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001358 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001359 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001361 //check introduced after having observed some panic in this processing
1362 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001364 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1365 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001366 go func(a_pAFsm *cmn.AdapterFsm) {
1367 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001368 }(pConfigVlanStateAFsm)
1369 return
1370 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001371 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001372 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001373 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001374 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001375 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001376 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1377 // synchronous FSM 'event/state' functions may rely on this mutex
1378 // but it must be released already before calling getTechProfileDone() as it may already be locked
1379 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1380 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001381 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001382 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001383 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001384 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1385
mpagenko9a304ea2020-12-16 15:54:01 +00001386 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001387 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1388 if aTechProfDone {
1389 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001391 } else {
1392 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001393 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001394 }
1395 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001396 return
1397 }
mpagenkof1d21d12021-06-11 13:14:45 +00001398 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001400 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001401 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1402 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001403 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001404 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001405 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001406 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001407 }
1408}
1409
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001411
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001412 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001413 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001414 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001415 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001416 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1417 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001418 return
1419 }
mpagenko15ff4a52021-03-02 10:09:20 +00001420 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001422 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001423 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001424 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001425
Girish Gowdrae95687a2021-09-08 16:30:58 -07001426 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001427 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001429 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001430 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001431 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1432 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1433 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1434 // 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 +00001435 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001436 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1437 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001438 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001439 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001441 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001442 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001443 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001444 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001445 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001446
mpagenko01e726e2020-10-23 09:45:29 +00001447 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001448 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1449 oFsm.numVlanFilterEntries = 1
1450 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001451 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001452 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001453 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1454 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1455 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001456 },
1457 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001458 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001459 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1460 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001461 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001462 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001463 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001464 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1465 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001466 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001467 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001468 go func(a_pAFsm *cmn.AdapterFsm) {
1469 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001470 }(pConfigVlanStateAFsm)
1471 }
1472 return
1473 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001474 //accept also nil as (error) return value for writing to LastTx
1475 // - this avoids misinterpretation of new received OMCI messages
1476 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1477 // send shall return (dual format) error code that can be used here for immediate error treatment
1478 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001479 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001480 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001481 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001482 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1483 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001484 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001485
dbainbri4d3a0dc2020-12-02 00:33:42 +00001486 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001487 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001488 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001489 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001490 // setVid is assumed to be masked already by the caller to 12 bit
1491 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001492 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001493 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001494
1495 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1496 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1497 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001498 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001499
1500 oFsm.numVlanFilterEntries++
1501 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001502 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001503 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001504 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1505 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1506 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001507 },
1508 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001509 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001510 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1511 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001512 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001513 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001514 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001515 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1516 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001517 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001518 return
1519 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001520 //accept also nil as (error) return value for writing to LastTx
1521 // - this avoids misinterpretation of new received OMCI messages
1522 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1523 // send shall return (dual format) error code that can be used here for immediate error treatment
1524 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001525 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001526 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001527 }
1528 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001530 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001531 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001532 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001533 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001534 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001535 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001536 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001537 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001538 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001539 return
1540 }
1541 }
mpagenkof1d21d12021-06-11 13:14:45 +00001542
mpagenkof1fc3862021-02-16 10:09:52 +00001543 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001544 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001545 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001546 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001547 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1548 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001549 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001550 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001551 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001552 //This is correct passing scenario
1553 if errEvto == nil {
1554 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001555 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001556 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001557 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001558 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001559 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001560 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001561 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001562 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001563 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001564 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001565 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001566 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001567 }
1568 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001569 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001570 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001572 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1573 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001574 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001575 if errCreateTrafficDescriptor != nil {
1576 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1577 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001578 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001579 }
1580 }
1581 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001583 }
1584 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001585}
1586
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001588 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001589 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001590 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1591 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001592
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001593 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1594 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001595 loVlanEntryClear := uint8(0)
1596 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1597 //shallow copy is sufficient as no reference variables are used within struct
1598 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001599 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001601 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1602 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1603 "device-id": oFsm.deviceID})
1604
1605 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1606 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001608 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1609 } else {
1610 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1611 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001612 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001613 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1614 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001616 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001617 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001618 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001619 loVlanEntryClear = 1 //full VlanFilter clear request
1620 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001621 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001622 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1623 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001624 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001625 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001626 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1627 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001628 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001629 return
1630 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001631 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001632 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001633 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001635 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001636 }
mpagenko01e726e2020-10-23 09:45:29 +00001637 } else {
1638 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1639 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001640 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001641 log.Fields{"current vlan list": oFsm.vlanFilterList,
1642 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1643 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1644 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1645 loVlanEntryRmPos = i
1646 break //abort search
1647 }
1648 }
1649 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001650 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001651 //valid entry was found - to be eclipsed
1652 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1653 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1654 if i < loVlanEntryRmPos {
1655 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1656 } else if i < (cVtfdTableSize - 1) {
1657 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1658 } else {
1659 vtfdFilterList[i] = 0 //set last byte if needed
1660 }
1661 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001662 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001663 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001664 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001665 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001666
mpagenkofc4f56e2020-11-04 17:17:49 +00001667 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001668 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001669 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1671 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001672 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001673 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001674 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1675 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001676 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001677 return
1678 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001679 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001680 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001683 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001684 }
mpagenko01e726e2020-10-23 09:45:29 +00001685 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001687 log.Fields{"device-id": oFsm.deviceID})
1688 }
1689 }
1690 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001691 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1692 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001694 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001695 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001696 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001697 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001698 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001699 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001700 }(pConfigVlanStateBaseFsm)
1701 return
1702 }
mpagenko01e726e2020-10-23 09:45:29 +00001703 }
1704
mpagenko15ff4a52021-03-02 10:09:20 +00001705 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001706 if loVlanEntryClear == 1 {
1707 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1708 oFsm.numVlanFilterEntries = 0
1709 } else if loVlanEntryClear == 2 {
1710 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1711 // this loop now includes the 0 element on previous last valid entry
1712 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1713 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1714 }
1715 oFsm.numVlanFilterEntries--
1716 }
mpagenko15ff4a52021-03-02 10:09:20 +00001717 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001718 }
1719 }
1720
mpagenkofc4f56e2020-11-04 17:17:49 +00001721 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001723 } else {
1724 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001725 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001726 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001727 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001728 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001729 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001730 }(pConfigVlanStateBaseFsm)
1731 }
mpagenkodff5dda2020-08-28 11:52:01 +00001732}
1733
dbainbri4d3a0dc2020-12-02 00:33:42 +00001734func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001735 var tpID uint8
1736 // Extract the tpID
1737 if len(e.Args) > 0 {
1738 tpID = e.Args[0].(uint8)
1739 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1740 } else {
1741 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1742 }
mpagenko01e726e2020-10-23 09:45:29 +00001743 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001744 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001745
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001746 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001747 if pConfigVlanStateAFsm == nil {
1748 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1749 log.Fields{"device-id": oFsm.deviceID})
1750 //would have to be fixed from outside somehow
1751 return
1752 }
1753
mpagenkof1d21d12021-06-11 13:14:45 +00001754 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1755 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001756 //call from 'configured' state of the rule
1757 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1758 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1759 oFsm.mutexFlowParams.Unlock()
1760 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001761 go func(a_pAFsm *cmn.AdapterFsm) {
1762 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001763 }(pConfigVlanStateAFsm)
1764 return
1765 }
mpagenkof1d21d12021-06-11 13:14:45 +00001766 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1767 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1768 oFsm.mutexFlowParams.Unlock()
1769 removeChannel <- true
1770 oFsm.mutexFlowParams.Lock()
1771 }
1772
mpagenkof1fc3862021-02-16 10:09:52 +00001773 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1774 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1775 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1776
Girish Gowdrae95687a2021-09-08 16:30:58 -07001777 // Store the reference to the flow response channel before this entry in the slice is deleted
1778 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1779
mpagenko01e726e2020-10-23 09:45:29 +00001780 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1781 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001783 "device-id": oFsm.deviceID})
1784 } else {
1785 //cut off the actual flow by slicing out the first element
1786 oFsm.uniRemoveFlowsSlice = append(
1787 oFsm.uniRemoveFlowsSlice[:0],
1788 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001790 "device-id": oFsm.deviceID})
1791 }
1792 oFsm.mutexFlowParams.Unlock()
1793
mpagenkof1fc3862021-02-16 10:09:52 +00001794 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001795 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001796 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001797 go func(a_pAFsm *cmn.AdapterFsm) {
1798 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001799 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001800
mpagenkobb47bc22021-04-20 13:29:09 +00001801 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001802 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001803 if deletedCookie == oFsm.delayNewRuleCookie {
1804 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1805 select {
1806 case <-oFsm.chCookieDeleted:
1807 logger.Debug(ctx, "flushed CookieDeleted")
1808 default:
1809 }
1810 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1811 }
mpagenkobb47bc22021-04-20 13:29:09 +00001812 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1813 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1814 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 -08001815 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001816 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1817 oFsm.flowDeleteChannel <- true
1818 oFsm.signalOnFlowDelete = false
1819 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001820 }
mpagenkobb47bc22021-04-20 13:29:09 +00001821 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001822
1823 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001824 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001825}
1826
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1828 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001829
mpagenko0f543222021-11-03 16:24:14 +00001830 oFsm.mutexPLastTxMeInstance.Lock()
1831 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1832 oFsm.mutexPLastTxMeInstance.Unlock()
1833
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001835 if pConfigVlanStateAFsm != nil {
1836 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001837 fsmAbortMsg := cmn.Message{
1838 Type: cmn.TestMsg,
1839 Data: cmn.TestMessage{
1840 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001841 },
1842 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001843 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001844
mpagenko0f543222021-11-03 16:24:14 +00001845 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1846 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1847
1848 oFsm.mutexFlowParams.RLock()
1849 if oFsm.delayNewRuleCookie != 0 {
1850 // looks like the waiting AddFlow is stuck
1851 oFsm.mutexFlowParams.RUnlock()
1852 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1853 select {
1854 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1855 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001856 }
mpagenko0f543222021-11-03 16:24:14 +00001857 oFsm.mutexFlowParams.RLock()
1858 }
1859 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1860 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1861 if removeUniFlowParams.isSuspendedOnAdd {
1862 removeChannel := removeUniFlowParams.removeChannel
1863 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1864 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1865 oFsm.mutexFlowParams.RUnlock()
1866 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1867 select {
1868 case removeChannel <- false:
1869 default:
1870 }
1871 oFsm.mutexFlowParams.RLock()
1872 }
1873 // Send response on response channel if the caller is waiting on it.
1874 var err error = nil
1875 if !oFsm.isCanceled {
1876 //only if the FSM is not canceled on external request use some error indication for the respChan
1877 // so only at real internal FSM abortion some error code is sent back
1878 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1879 err = fmt.Errorf("internal-error")
1880 }
1881 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1882 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1883 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1884 }
1885 }
1886
1887 if oFsm.pDeviceHandler != nil {
1888 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1889 if !oFsm.isCanceled {
1890 //if the FSM is not canceled on external request use "internal-error" for the respChan
1891 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1892 // Send response on response channel if the caller is waiting on it with according error indication.
1893 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1894 }
1895 //permanently remove possibly stored persistent data
1896 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1897 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1898 } else {
1899 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1900 // no need to remove specific data in this case here
1901 // TODO: cancelation may also abort a running flowAdd activity in which case it would be better
1902 // to also resopnd on the respChan with some error ("config canceled"), but that is a bit hard to decide here
1903 // so just left open by now
1904 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1905 }
1906 }
1907 oFsm.mutexFlowParams.RUnlock()
1908
1909 //try to let the FSM proceed to 'disabled'
1910 // Can't call FSM Event directly, decoupling it
1911 go func(a_pAFsm *cmn.AdapterFsm) {
1912 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1913 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1914 }
1915 }(pConfigVlanStateAFsm)
1916 return
1917 }
1918 oFsm.mutexFlowParams.RUnlock()
1919 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1920 log.Fields{"device-id": oFsm.deviceID})
1921 return
mpagenkodff5dda2020-08-28 11:52:01 +00001922 }
mpagenko0f543222021-11-03 16:24:14 +00001923 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1924 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001925}
1926
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1928 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001929
mpagenkodff5dda2020-08-28 11:52:01 +00001930 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001931 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001932 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001933 return
mpagenkodff5dda2020-08-28 11:52:01 +00001934 }
mpagenko0f543222021-11-03 16:24:14 +00001935 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1936 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001937}
1938
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1940 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001941loop:
1942 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001943 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001945 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001946 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301947 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301949 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001950 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301951 break loop
1952 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301954
1955 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 case cmn.TestMsg:
1957 msg, _ := message.Data.(cmn.TestMessage)
1958 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001960 break loop
1961 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001963 case cmn.OMCI:
1964 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301966 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301968 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001969 }
1970 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001972}
1973
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001974func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001976 "msgType": msg.OmciMsg.MessageType})
1977
1978 switch msg.OmciMsg.MessageType {
1979 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001980 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00001982 logger.Warnw(ctx, "CreateResponse handling aborted",
1983 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001984 return
1985 }
mpagenkodff5dda2020-08-28 11:52:01 +00001986 } //CreateResponseType
1987 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001988 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001989 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1990 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001992 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001993 return
1994 }
1995 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1996 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001998 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001999 return
2000 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002001 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002002 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002004 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00002005 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2006 return
2007 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002008 oFsm.mutexPLastTxMeInstance.RLock()
2009 if oFsm.pLastTxMeInstance != nil {
2010 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2011 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2012 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002013 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002014 { // let the MultiEntity config proceed by stopping the wait function
2015 oFsm.mutexPLastTxMeInstance.RUnlock()
2016 oFsm.omciMIdsResponseReceived <- true
2017 return
2018 }
2019 default:
2020 {
2021 logger.Warnw(ctx, "Unsupported ME name received!",
2022 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2023 }
mpagenkodff5dda2020-08-28 11:52:01 +00002024 }
2025 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002026 } else {
2027 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002028 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002029 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002030 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002031 case omci.DeleteResponseType:
2032 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002034 logger.Warnw(ctx, "DeleteResponse handling aborted",
2035 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002036 return
2037 }
2038 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002039 default:
2040 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002042 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002043 return
2044 }
2045 }
2046}
2047
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002049 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2050 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002051 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002052 log.Fields{"device-id": oFsm.deviceID})
2053 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2054 oFsm.deviceID)
2055 }
2056 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2057 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002059 log.Fields{"device-id": oFsm.deviceID})
2060 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2061 oFsm.deviceID)
2062 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002063 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002064 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002065 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002066 "Error": msgObj.Result})
2067 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2068 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2069 oFsm.deviceID)
2070 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002071 oFsm.mutexPLastTxMeInstance.RLock()
2072 if oFsm.pLastTxMeInstance != nil {
2073 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2074 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2075 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2076 switch oFsm.pLastTxMeInstance.GetName() {
2077 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2078 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002079 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002080 {
2081 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002082 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002083 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002084 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002085 } else { // let the MultiEntity config proceed by stopping the wait function
2086 oFsm.omciMIdsResponseReceived <- true
2087 }
2088 return nil
2089 }
2090 default:
2091 {
2092 logger.Warnw(ctx, "Unsupported ME name received!",
2093 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002094 }
2095 }
2096 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002097 } else {
2098 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002099 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002100 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002101 return nil
2102}
2103
dbainbri4d3a0dc2020-12-02 00:33:42 +00002104func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002105 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2106 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002108 log.Fields{"device-id": oFsm.deviceID})
2109 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2110 oFsm.deviceID)
2111 }
2112 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2113 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002115 log.Fields{"device-id": oFsm.deviceID})
2116 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2117 oFsm.deviceID)
2118 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002120 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002122 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2123 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2124 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2125 oFsm.deviceID)
2126 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002127 oFsm.mutexPLastTxMeInstance.RLock()
2128 if oFsm.pLastTxMeInstance != nil {
2129 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2130 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2131 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002132 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002133 { // let the MultiEntity config proceed by stopping the wait function
2134 oFsm.mutexPLastTxMeInstance.RUnlock()
2135 oFsm.omciMIdsResponseReceived <- true
2136 return nil
2137 }
2138 default:
2139 {
2140 logger.Warnw(ctx, "Unsupported ME name received!",
2141 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2142 }
mpagenko01e726e2020-10-23 09:45:29 +00002143 }
2144 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002145 } else {
2146 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002147 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002148 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002149 return nil
2150}
2151
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002153 oFsm.mutexFlowParams.RLock()
2154 evtocdID := oFsm.evtocdID
2155 oFsm.mutexFlowParams.RUnlock()
2156
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002157 if aFlowEntryNo == 0 {
2158 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002159 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2160 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002161 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002162 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002163 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002164 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002165 associationType := 2 // default to UniPPTP
2166 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002167 associationType = 10
2168 }
2169 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002170 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002171 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002172 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002173 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2174 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002175 },
2176 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002177 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002178 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2179 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002180 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002181 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002182 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2183 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002184 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002185 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2186 }
mpagenkodff5dda2020-08-28 11:52:01 +00002187 //accept also nil as (error) return value for writing to LastTx
2188 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002189 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002191
2192 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002193 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002194 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002195 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002196 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002197 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002198 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2199 }
2200
2201 // Set the EVTOCD ME default params
2202 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002203 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002204 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002205 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2206 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2207 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002208 },
2209 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002210 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002211 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2212 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2213 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002214 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002215 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002216 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2217 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002218 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002219 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2220 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002221 //accept also nil as (error) return value for writing to LastTx
2222 // - this avoids misinterpretation of new received OMCI messages
2223 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002224 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002225
2226 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002229 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002230 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002231 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002232 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002233 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002234 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002235
mpagenko551a4d42020-12-08 18:09:20 +00002236 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302237 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2238 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002239 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002240 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002241 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002242 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002243 sliceEvtocdRule := make([]uint8, 16)
2244 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2245 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2246 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2247 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2248 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2249
2250 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2251 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2252 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2253 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2254 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2255
2256 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2257 0<<cTreatTTROffset| // Do not pop any tags
2258 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2259 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2260 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2261
2262 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2263 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2264 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2265 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2266
2267 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002268 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002269 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002270 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002271 },
2272 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002273 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002274 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2275 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2276 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002277 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002278 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002279 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2280 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002281 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002282 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2283 }
mpagenkodff5dda2020-08-28 11:52:01 +00002284 //accept also nil as (error) return value for writing to LastTx
2285 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002286 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002287 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002288
2289 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002290 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002291 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002293 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002294 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002295 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2296
mpagenkodff5dda2020-08-28 11:52:01 +00002297 }
2298 } else {
2299 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2300 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002301 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2302 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2303 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2304 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302305 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002306 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002307
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302308 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2309 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2310 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
2311 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
2312 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2313 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2314 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2315 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2316 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002317
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302318 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2319 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2320 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2321 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2322 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002323
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302324 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2325 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2326 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2327 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2328 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2329
2330 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2331 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2332 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2333 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2334
2335 } else {
2336 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2337 //As of now only a match and no action can be done on the inner tag .
2338 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2339 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2340 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2341 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2342 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2343 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2344 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2345
2346 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2347 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2348 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2349 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2350 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2351
2352 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2353 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2354 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2355 setVid<<cTreatVidOffset| // Set VID
2356 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2357
2358 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2359 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2360 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2361 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2362 }
mpagenko551a4d42020-12-08 18:09:20 +00002363 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002364 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002365 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002366 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002367 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002368 },
2369 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002370 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002371 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2372 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2373 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002374 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002375 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002376 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2377 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002378 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002379 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2380 }
mpagenkodff5dda2020-08-28 11:52:01 +00002381 //accept also nil as (error) return value for writing to LastTx
2382 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002383 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002384 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002385
2386 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002387 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002388 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302389 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002390 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002391 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302392 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002393 }
2394 } else {
2395 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2396 { // just for local var's
2397 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002399 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002400 sliceEvtocdRule := make([]uint8, 16)
2401 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2402 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2403 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2404 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2405 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2406
2407 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2408 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2409 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2410 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2411 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2412
2413 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2414 0<<cTreatTTROffset| // Do not pop any tags
2415 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2416 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2417 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2418
2419 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2420 0<<cTreatPrioOffset| // vlan prio set to 0
2421 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002422 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002423 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2424
mpagenko551a4d42020-12-08 18:09:20 +00002425 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002426 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002427 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002428 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002429 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002430 },
2431 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002432 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002433 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2434 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2435 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002436 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002437 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002438 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2439 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002440 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002441 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2442 }
mpagenkodff5dda2020-08-28 11:52:01 +00002443 //accept also nil as (error) return value for writing to LastTx
2444 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002445 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002446 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002447
2448 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002449 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002450 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002451 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002452 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002453 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002454 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2455
mpagenkodff5dda2020-08-28 11:52:01 +00002456 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002457 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002458 { // just for local var's
2459 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002460 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002461 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002462 sliceEvtocdRule := make([]uint8, 16)
2463 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2464 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2465 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2466 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2467 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2468
2469 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2470 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2471 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2472 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2473 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2474
2475 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2476 1<<cTreatTTROffset| // pop the prio-tag
2477 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2478 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2479 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2480
mpagenko551a4d42020-12-08 18:09:20 +00002481 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002482 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2483 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2484 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002485 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002486 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002487 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002488
2489 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002490 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002491 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002492 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002493 },
2494 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002495 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002496 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2497 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2498 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002499 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002500 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002501 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2502 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002503 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002504 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2505 }
mpagenkodff5dda2020-08-28 11:52:01 +00002506 //accept also nil as (error) return value for writing to LastTx
2507 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002508 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002509 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002510
2511 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002512 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002513 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002514 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002515 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002516 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002517 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2518
mpagenkodff5dda2020-08-28 11:52:01 +00002519 }
2520 } //just for local var's
2521 }
2522 }
2523
mpagenkofc4f56e2020-11-04 17:17:49 +00002524 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002525 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002526 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002527 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002528 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002529 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002530}
2531
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002532func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002533 oFsm.mutexFlowParams.RLock()
2534 evtocdID := oFsm.evtocdID
2535 oFsm.mutexFlowParams.RUnlock()
2536
mpagenko01e726e2020-10-23 09:45:29 +00002537 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2538 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2539 //transparent transmission was set
2540 //perhaps the config is not needed for removal,
2541 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002542 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002543 "device-id": oFsm.deviceID})
2544 sliceEvtocdRule := make([]uint8, 16)
2545 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2546 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2547 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2548 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2549 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2550
2551 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2552 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2553 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2554 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2555 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2556
2557 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2558 0<<cTreatTTROffset| // Do not pop any tags
2559 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2560 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2561 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2562
2563 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2564 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2565 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2566 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2567
2568 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002569 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002570 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002571 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002572 },
2573 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002574 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002575 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2576 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2577 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002578 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002579 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002580 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2581 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002582 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002583 return
2584 }
mpagenko01e726e2020-10-23 09:45:29 +00002585 //accept also nil as (error) return value for writing to LastTx
2586 // - this avoids misinterpretation of new received OMCI messages
2587 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002588 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002589
2590 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002591 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002592 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002593 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002594 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002595 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002596 return
2597 }
2598 } else {
2599 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002600 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002601 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002602 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002603 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302604 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002605
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302606 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2607 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2608 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2609 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2610 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2611 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2612 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2613 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002614
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302615 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2616 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2617 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2618 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2619 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002620
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302621 // delete indication for the indicated Filter
2622 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2623 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2624
2625 } else {
2626 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2627 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2628 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
2629 sliceEvtocdRule := make([]uint8, 16)
2630 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2631 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2632 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2633 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2634 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2635
2636 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2637 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2638 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2639 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2640 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2641
2642 // delete indication for the indicated Filter
2643 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2644 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2645 }
mpagenko01e726e2020-10-23 09:45:29 +00002646 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002647 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002648 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002649 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002650 },
2651 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002652 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002653 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2654 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2655 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002656 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002657 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002658 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2659 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002660 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002661 return
2662 }
mpagenko01e726e2020-10-23 09:45:29 +00002663 //accept also nil as (error) return value for writing to LastTx
2664 // - this avoids misinterpretation of new received OMCI messages
2665 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002666 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002667
2668 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002669 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002670 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302671 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2672 log.Fields{"device-id": oFsm.deviceID,
2673 "match-vlan": aRuleParams.MatchVid,
2674 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002676 return
2677 }
2678 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002679 // VOL-3685
2680 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2681 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2682 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2683 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2684 // later when the flow is being re-installed.
2685 // Of course this is applicable to case only where single service (or single tcont) is in use and
2686 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2687 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2688 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002689 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002690 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002691 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002692 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2693 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002694 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002695 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002696 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002697 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002698 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2699 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2700 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002701 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002702 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002703 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2704 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002706 return
2707 }
mpagenko01e726e2020-10-23 09:45:29 +00002708 //accept also nil as (error) return value for writing to LastTx
2709 // - this avoids misinterpretation of new received OMCI messages
2710 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002711 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002712
2713 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002714 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002715 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002716 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002717 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002718 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002719 return
2720 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002721 } else {
2722 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2723 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002724 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002726 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002727 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2728 { // just for local var's
2729 // this defines stacking scenario: untagged->singletagged
2730 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2731 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2732 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2733 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002734 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", 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
mpagenko01e726e2020-10-23 09:45:29 +00002742
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002743 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2744 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2745 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2746 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2747 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002748
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002749 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2750 0<<cTreatTTROffset| // Do not pop any tags
2751 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2752 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2753 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002754
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2756 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2757 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2758 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002759
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002760 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002761 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002762 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002763 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002764 },
2765 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002766 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002767 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2768 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2769 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002770 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002771 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002772 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2773 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002774 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002775 return
2776 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002777 //accept also nil as (error) return value for writing to LastTx
2778 // - this avoids misinterpretation of new received OMCI messages
2779 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002780 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002781
2782 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002783 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002784 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002785 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002786 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002787 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002788 return
2789 }
2790 } // just for local var's
2791 { // just for local var's
2792 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002793 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002794 "device-id": oFsm.deviceID})
2795 sliceEvtocdRule := make([]uint8, 16)
2796 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2797 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2798 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2799 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2800 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2801
2802 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2803 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2804 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2805 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2806 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2807
2808 // delete indication for the indicated Filter
2809 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2810 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2811
2812 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002813 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002814 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002815 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002816 },
2817 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002818 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002819 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2820 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2821 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002822 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002823 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002824 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2825 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002826 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002827 return
2828 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002829 //accept also nil as (error) return value for writing to LastTx
2830 // - this avoids misinterpretation of new received OMCI messages
2831 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002832 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002833
2834 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002835 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002836 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002838 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002839 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002840 return
2841 }
mpagenko01e726e2020-10-23 09:45:29 +00002842 }
2843 } //just for local var's
2844 }
2845 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002846 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002848 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002849}
2850
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002852 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002853 if oFsm.isCanceled {
2854 // FSM already canceled before entering wait
2855 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2856 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002857 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002858 }
mpagenko7d6bb022021-03-11 15:07:55 +00002859 oFsm.isAwaitingResponse = true
2860 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002861 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302862 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002863 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002864 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002865 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002867 oFsm.mutexIsAwaitingResponse.Lock()
2868 oFsm.isAwaitingResponse = false
2869 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002870 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002871 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302872 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002873 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002874 oFsm.mutexIsAwaitingResponse.Lock()
2875 oFsm.isAwaitingResponse = false
2876 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002877 return nil
2878 }
mpagenko7d6bb022021-03-11 15:07:55 +00002879 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002880 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002881 oFsm.mutexIsAwaitingResponse.Lock()
2882 oFsm.isAwaitingResponse = false
2883 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002884 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002885 }
2886}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002887
mpagenko551a4d42020-12-08 18:09:20 +00002888func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002889 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002890 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002891 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002892 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002894 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002895 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002896 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2897 }
2898
dbainbri4d3a0dc2020-12-02 00:33:42 +00002899 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002900 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002901 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002902 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002903 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002904 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2905 }
2906
dbainbri4d3a0dc2020-12-02 00:33:42 +00002907 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002908 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002909 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002910 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002911 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002912 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2913 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002915 if errMacBpCdEID != nil {
2916 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2917 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002918 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002919 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002920
Mahir Gunyel6781f962021-05-16 23:30:08 -07002921 }
2922 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002923 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2924 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002926 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002927 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002928 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2929 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2930 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2931 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002932 },
2933 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002934 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2936 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002937 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002938 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002939 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2940 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002941 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002942 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2943 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002944 //accept also nil as (error) return value for writing to LastTx
2945 // - this avoids misinterpretation of new received OMCI messages
2946 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002947 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002948 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002949 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002950 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002951 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2952 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2954 }
2955
2956 // ==> Start creating VTFD for mcast vlan
2957
2958 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2959 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002960 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002961
dbainbri4d3a0dc2020-12-02 00:33:42 +00002962 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002963 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002964 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002965 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2966
2967 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2968 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2969 // new vlan associated with a different TP.
2970 vtfdFilterList[0] = uint16(vlanID)
2971
2972 meParams = me.ParamData{
2973 EntityID: mcastVtfdID,
2974 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002975 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
2976 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
2977 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002978 },
2979 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002980 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002981 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2982 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002983 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002984 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002985 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2986 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002987 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002988 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2989 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002990 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002991 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002992 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002993 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002994 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002995 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002996 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002997 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2998 }
2999
3000 return nil
3001}
3002
dbainbri4d3a0dc2020-12-02 00:33:42 +00003003func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003004 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003005 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003006 logger.Errorw(ctx, "error generrating me instance id",
3007 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003008 return err
3009 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003010 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3011 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003012 meParams := me.ParamData{
3013 EntityID: instID,
3014 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003015 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003016 //Direct reference to the Operation profile
3017 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003018 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003019 },
3020 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003021 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003022 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3023 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3024 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003025 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003026 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003027 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3028 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003029 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003030 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3031 oFsm.deviceID, err)
3032 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003033 //accept also nil as (error) return value for writing to LastTx
3034 // - this avoids misinterpretation of new received OMCI messages
3035 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003036 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003037 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003038 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003039 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003040 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003041 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3042 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3043 }
3044 return nil
3045}
3046
dbainbri4d3a0dc2020-12-02 00:33:42 +00003047func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003048 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003049 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003050 logger.Errorw(ctx, "error generating me instance id",
3051 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003052 return err
3053 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003054 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3055 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003056 meParams := me.ParamData{
3057 EntityID: instID,
3058 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003059 me.MulticastOperationsProfile_IgmpVersion: 2,
3060 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003061 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003062 me.MulticastOperationsProfile_ImmediateLeave: 0,
3063 me.MulticastOperationsProfile_Robustness: 2,
3064 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3065 me.MulticastOperationsProfile_QueryInterval: 125,
3066 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3067 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003068 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003069 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003070 },
3071 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003072 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003073 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3074 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3075 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003076 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003077 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003078 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3079 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003080 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003081 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3082 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003083 //accept also nil as (error) return value for writing to LastTx
3084 // - this avoids misinterpretation of new received OMCI messages
3085 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003086 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003087 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003088 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003089 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003090 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003091 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003092 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003093 }
3094 return nil
3095}
3096
dbainbri4d3a0dc2020-12-02 00:33:42 +00003097func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003098 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003099 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003100 logger.Errorw(ctx, "error generating me instance id",
3101 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003102 return err
3103 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003104 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3105 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003106 //TODO check that this is correct
3107 // Table control
3108 //setCtrl = 1
3109 //rowPartId = 0
3110 //test = 0
3111 //rowKey = 0
3112 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003113 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003114 dynamicAccessCL := make([]uint8, 24)
3115 copy(dynamicAccessCL, tableCtrl)
3116 //Multicast GemPortId
3117 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3118 // python version waits for installation of flows, see line 723 onward of
3119 // brcm_openomci_onu_handler.py
3120 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3121 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003122 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003123 //TODO start and end are hardcoded, get from TP
3124 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003125 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003126 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003127 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003128 //imputed group bandwidth
3129 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3130
3131 meParams := me.ParamData{
3132 EntityID: instID,
3133 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003134 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003135 },
3136 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003137 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003138 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3139 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3140 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003141 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003142 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003143 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3144 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003145 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003146 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3147 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003148 //accept also nil as (error) return value for writing to LastTx
3149 // - this avoids misinterpretation of new received OMCI messages
3150 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003151 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003152 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003153 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003154 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003155 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003156 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003157 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003158 }
3159 return nil
3160}
Girish Gowdra26a40922021-01-29 17:14:34 -08003161
khenaidoo42dcdfd2021-10-19 17:34:12 -04003162func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003163 tpID uint8, uniID uint8, gemPortID uint16) error {
3164 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3165 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3166 // I created unique TD ID by flow direction.
3167 // TODO! Traffic descriptor ME ID will check
3168 trafficDescriptorID := gemPortID
3169 if aMeter == nil {
3170 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3171 }
3172 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3173 if err != nil {
3174 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3175 return err
3176 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003177 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003178 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003179 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003180 pbs := trafficShapingInfo.Pbs
3181
3182 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3183 meParams := me.ParamData{
3184 EntityID: trafficDescriptorID,
3185 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003186 me.TrafficDescriptor_Cir: cir,
3187 me.TrafficDescriptor_Pir: pir,
3188 me.TrafficDescriptor_Cbs: cbs,
3189 me.TrafficDescriptor_Pbs: pbs,
3190 me.TrafficDescriptor_ColourMode: 1,
3191 me.TrafficDescriptor_IngressColourMarking: 3,
3192 me.TrafficDescriptor_EgressColourMarking: 3,
3193 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003194 },
3195 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003196 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003197 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3198 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003199 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003200 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003201 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3202 return err
3203 }
3204 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003205 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003206 err = oFsm.waitforOmciResponse(ctx)
3207 if err != nil {
3208 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3209 return err
3210 }
3211
Girish Gowdra09e5f212021-09-30 16:28:36 -07003212 // 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
3213 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003214 if err != nil {
3215 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3216 return err
3217 }
3218 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3219
3220 return nil
3221}
3222
Girish Gowdra09e5f212021-09-30 16:28:36 -07003223func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3224 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3225 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003226 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003227 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003228 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003229 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003230 },
3231 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003232 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003233 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3234 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003235 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003236 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003237 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3238 return err
3239 }
3240 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003241 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003242 err = oFsm.waitforOmciResponse(ctx)
3243 if err != nil {
3244 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3245 return err
3246 }
3247 return nil
3248}
3249
Girish Gowdra26a40922021-01-29 17:14:34 -08003250// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003251func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3252 if oFsm == nil {
3253 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3254 return false
3255 }
mpagenkobb47bc22021-04-20 13:29:09 +00003256 oFsm.mutexFlowParams.Lock()
3257 defer oFsm.mutexFlowParams.Unlock()
3258 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3259 //flow removal is still ongoing/pending
3260 oFsm.signalOnFlowDelete = true
3261 oFsm.flowDeleteChannel = aFlowDeleteChannel
3262 return true
3263 }
3264 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003265}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003266
3267func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3268 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3269 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3270 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3271 log.Fields{"device-id": oFsm.deviceID})
3272 } else {
3273 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3274 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3275 "index": oFsm.numVlanFilterEntries,
3276 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3277 "device-id": oFsm.deviceID})
3278 oFsm.numVlanFilterEntries++
3279 }
3280}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003281
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003282// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3283func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003284 if respChan != nil {
3285 // 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
3286 select {
3287 case *respChan <- err:
3288 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3289 default:
3290 }
3291 }
3292}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003293
3294// PrepareForGarbageCollection - remove references to prepare for garbage collection
3295func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3296 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3297 oFsm.pDeviceHandler = nil
3298 oFsm.pOnuDeviceEntry = nil
3299 oFsm.pOmciCC = nil
3300}