blob: bfe1bc9ccff64348c9ee576588dce5a05972608e [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
Joey Armstrong89c812c2024-01-12 19:00:20 -05002 * Copyright 2020-2024 Open Networking Foundation (ONF) and the ONF Contributors
mpagenkodff5dda2020-08-28 11:52:01 +00003 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
praneeth kumar nalmas3947c582023-12-13 15:38:50 +053017// Package avcfg provides anig and vlan configuration functionality
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000018package avcfg
mpagenkodff5dda2020-08-28 11:52:01 +000019
20import (
21 "context"
22 "encoding/binary"
mpagenkof582d6a2021-06-18 15:58:10 +000023 "errors"
Andrea Campanella6515c582020-10-05 11:25:00 +020024 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030025 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028 "time"
29
khenaidoo7d3c5582021-08-11 18:09:44 -040030 meters "github.com/opencord/voltha-lib-go/v7/pkg/meters"
ozgecanetsia82b91a62021-05-21 18:54:49 +030031
mpagenko01e726e2020-10-23 09:45:29 +000032 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000033 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000034 "github.com/opencord/omci-lib-go/v2"
35 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040036 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000037 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
38 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
khenaidoo7d3c5582021-08-11 18:09:44 -040039 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000040)
41
42const (
43 // internal predefined values
44 cDefaultDownstreamMode = 0
45 cDefaultTpid = 0x8100
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
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530146// UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147//
148// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000149type UniVlanConfigFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000150 pDeviceHandler cmn.IdeviceHandler
151 pOnuDeviceEntry cmn.IonuDeviceEntry
mpagenko01e726e2020-10-23 09:45:29 +0000152 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000153 pOmciCC *cmn.OmciCC
154 pOnuUniPort *cmn.OnuUniPort
155 pUniTechProf *OnuUniTechProf
156 pOnuDB *devdb.OnuDeviceDB
157 requestEvent cmn.OnuDeviceEvent
mpagenkodff5dda2020-08-28 11:52:01 +0000158 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000159 PAdaptFsm *cmn.AdapterFsm
mpagenkodff5dda2020-08-28 11:52:01 +0000160 acceptIncrementalEvtoOption bool
mpagenkocf48e452021-04-23 09:23:00 +0000161 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000162 isAwaitingResponse bool
163 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000164 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000165 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
Girish Gowdrae95687a2021-09-08 16:30:58 -0700166 actualUniFlowParam cmn.UniVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000167 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000168 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000169 NumUniFlows uint8 // expected number of flows should be less than 12
170 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000171 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000173 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000174 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000175 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000176 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000177 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000178 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000179 signalOnFlowDelete bool
180 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000181 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
182 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200183 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
184 // thus notification needs to be sent on chan.
185 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000186}
187
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530188// NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
189//
190// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000191func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
192 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
193 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530194 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 +0000195 instFsm := &UniVlanConfigFsm{
196 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000197 pOnuDeviceEntry: apOnuDeviceEntry,
198 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000199 pOmciCC: apDevOmciCC,
200 pOnuUniPort: apUniPort,
201 pUniTechProf: apUniTechProf,
202 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000203 requestEvent: aRequestEvent,
204 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000205 NumUniFlows: 0,
206 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000207 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200208 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000209 }
210
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000211 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
212 if instFsm.PAdaptFsm == nil {
213 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000214 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700215 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000216 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000217 return nil
218 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000219 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
220 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000221 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000222 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
223 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
224 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
225 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
226 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
227 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
228 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
229 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
230 Dst: VlanStConfigDone},
231 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
232 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
233 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
234 Dst: VlanStConfigIncrFlow},
235 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
236 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
237 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000238 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000239 {Name: VlanEvTimeoutSimple, Src: []string{
240 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
241 {Name: VlanEvTimeoutMids, Src: []string{
242 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000243 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000244 // exceptional treatment for all states except VlanStResetting
245 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
246 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +0530247 VlanStRemoveFlow, VlanStCleanupDone, VlanStPreparing},
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000249 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000251 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000252 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
253 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
254 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000255 },
mpagenkodff5dda2020-08-28 11:52:01 +0000256 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000257 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
258 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
259 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
260 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
261 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
262 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
263 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
264 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
265 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
266 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
267 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000268 },
269 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000270 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000271 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000272 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700273 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000274 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000275 return nil
276 }
277
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530278 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aMatchPcp, aSetVlan, aSetPcp, innerCvlan, aMeter, respChan)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000279 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000280 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000281 return instFsm
282}
283
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530284// initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000285func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530286 aMatchVlan uint16, aMatchPcp uint8, aSetVlan uint16, aSetPcp uint8, innerCvlan uint16, aMeter *of.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000287 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530288 TpID: aTpID,
289 MatchVid: uint32(aMatchVlan),
290 MatchPcp: uint32(aMatchPcp),
291 SetVid: uint32(aSetVlan),
292 SetPcp: uint32(aSetPcp),
293 InnerCvlan: innerCvlan,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000294 }
295 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwarc7c29d82022-03-03 18:38:45 +0530296 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297
mpagenko01e726e2020-10-23 09:45:29 +0000298 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299 //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 +0000300 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
302 } else {
303 if !oFsm.acceptIncrementalEvtoOption {
304 //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 +0000305 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000306 }
307 }
308
mpagenko01e726e2020-10-23 09:45:29 +0000309 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000311 loRuleParams.TagsToRemove = 0 //no tag pop action
312 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
313 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000314 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
315 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
316 // might collide with NoMatchVid/CopyPrio(/setVid) setting
317 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000318 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000319 }
320 }
mpagenko01e726e2020-10-23 09:45:29 +0000321
Girish Gowdrae95687a2021-09-08 16:30:58 -0700322 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000323 loFlowParams.CookieSlice = make([]uint64, 0)
324 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300325 if aMeter != nil {
326 loFlowParams.Meter = aMeter
327 }
mpagenko01e726e2020-10-23 09:45:29 +0000328
329 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000330 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000331 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000332 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000333 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
334 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
335 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
336 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000338
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000339 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000340 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
341 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000342 //cmp also usage in EVTOCDE create in omci_cc
343 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000344 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000345 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
346
347 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000348 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000349 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000351 return err
352 }
353
354 return nil
355}
356
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530357// CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000358func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000359 if oFsm == nil {
360 logger.Error(ctx, "no valid UniVlanConfigFsm!")
361 return
362 }
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530363 logger.Debugw(ctx, "CancelProcessing entered", log.Fields{"device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +0000364 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000365 oFsm.mutexIsAwaitingResponse.Lock()
366 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000367 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000368 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
369 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
370 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000371 //use channel to indicate that the response waiting shall be aborted
372 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000373 } else {
374 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000375 }
mpagenkocf48e452021-04-23 09:23:00 +0000376
mpagenko7d6bb022021-03-11 15:07:55 +0000377 // 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 +0000378 PAdaptFsm := oFsm.PAdaptFsm
379 if PAdaptFsm != nil {
380 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000381 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000382 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000383 }
mpagenko7d6bb022021-03-11 15:07:55 +0000384 }
385}
386
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530387// GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000388func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
389 if oFsm == nil {
390 logger.Error(ctx, "no valid UniVlanConfigFsm!")
391 return 0
392 }
mpagenko551a4d42020-12-08 18:09:20 +0000393 //mutex protection is required for possible concurrent access to FSM members
394 oFsm.mutexFlowParams.RLock()
395 defer oFsm.mutexFlowParams.RUnlock()
396 return oFsm.TpIDWaitingFor
397}
398
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530399// SetUniFlowParams verifies on existence of flow parameters to be configured,
mpagenko01e726e2020-10-23 09:45:29 +0000400// optionally udates the cookie list or appends a new flow if there is space
401// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000402// ignore complexity by now
403// nolint: gocyclo
404func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530405 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 +0000406 if oFsm == nil {
407 logger.Error(ctx, "no valid UniVlanConfigFsm!")
408 return fmt.Errorf("no-valid-UniVlanConfigFsm")
409 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000410 loRuleParams := cmn.UniVlanRuleParams{
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530411 TpID: aTpID,
412 MatchVid: uint32(aMatchVlan),
413 MatchPcp: uint32(aMatchPcp),
414 SetVid: uint32(aSetVlan),
415 SetPcp: uint32(aSetPcp),
416 InnerCvlan: aInnerCvlan,
mpagenko01e726e2020-10-23 09:45:29 +0000417 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700418 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000419 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +0530420 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
mpagenko01e726e2020-10-23 09:45:29 +0000421 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
422 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
423 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
424 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
425 } else {
426 if !oFsm.acceptIncrementalEvtoOption {
427 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
428 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
429 }
430 }
431
432 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
433 // no prio/vid filtering requested
434 loRuleParams.TagsToRemove = 0 //no tag pop action
435 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
436 if loRuleParams.SetPcp == cCopyPrioFromInner {
437 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
438 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
439 // might collide with NoMatchVid/CopyPrio(/setVid) setting
440 // this was some precondition setting taken over from py adapter ..
441 loRuleParams.SetPcp = 0
442 }
443 }
444
mpagenkof1d21d12021-06-11 13:14:45 +0000445 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
446 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
447 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
448 oFsm.mutexFlowParams.RLock()
449 if len(oFsm.uniRemoveFlowsSlice) > 0 {
450 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
451 if removeUniFlowParams.vlanRuleParams == loRuleParams {
452 // the flow to add is the same as the one already in progress of deleting
453 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000454 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
455 if flow >= len(oFsm.uniRemoveFlowsSlice) {
456 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
457 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
458 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700459 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000460 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700461 return err
462
mpagenkof582d6a2021-06-18 15:58:10 +0000463 }
mpagenkof1d21d12021-06-11 13:14:45 +0000464 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
465 oFsm.mutexFlowParams.RUnlock()
466 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
467 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
468 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700469 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000470 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700471 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000472 }
473 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000474 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000475 }
476 }
477 }
478 oFsm.mutexFlowParams.RUnlock()
479
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000480 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000481 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000482 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200483 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000484 //mutex protection is required for possible concurrent access to FSM members
485 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000486 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
487 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
488 // countable run time optimization (perhaps with including the hash in kvStore storage?)
489 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000490 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300492 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
493 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
494 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000495 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000496 var cookieMatch bool
497 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
498 cookieMatch = false
499 for _, cookie := range storedUniFlowParams.CookieSlice {
500 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000502 "device-id": oFsm.deviceID, "cookie": cookie})
503 cookieMatch = true
504 break //found new cookie - no further search for this requested cookie
505 }
506 }
507 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000508 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
509 if delayedCookie != 0 {
510 //a delay for adding the cookie to this rule is requested
511 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
512 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000513 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
514 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
515 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700516 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000517 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700518 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000519 }
mpagenkobc4170a2021-08-17 16:42:10 +0000520 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000521 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000522 } else {
523 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
524 "device-id": oFsm.deviceID, "cookie": newCookie})
525 //as range works with copies of the slice we have to write to the original slice!!
526 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
527 newCookie)
528 flowCookieModify = true
529 }
mpagenko01e726e2020-10-23 09:45:29 +0000530 }
531 } //for all new cookies
532 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000533 }
534 }
mpagenkof1fc3862021-02-16 10:09:52 +0000535 oFsm.mutexFlowParams.Unlock()
536
537 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000538 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
539 if !deleteSuccess {
540 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
541 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700542 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000543 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700544 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000545 }
mpagenkof1fc3862021-02-16 10:09:52 +0000546 requestAppendRule = true //default assumption here is that rule is to be appended
547 flowCookieModify = true //and that the the flow data base is to be updated
548 if delayedCookie != 0 { //it was suspended
549 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
550 }
551 }
552 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
553 if requestAppendRule {
554 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000555 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700556 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000557 loFlowParams.CookieSlice = make([]uint64, 0)
558 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300559 if aMeter != nil {
560 loFlowParams.Meter = aMeter
561 }
mpagenko01e726e2020-10-23 09:45:29 +0000562 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000563 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000564 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000565 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
566 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000567 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
568 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000569
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000570 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000571 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
572 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000573 oFsm.NumUniFlows++
574 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000575
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000576 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000577 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000579 //attention: take care to release the mutexFlowParams when calling the FSM directly -
580 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000581 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000582 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
583 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000584 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000585 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700586 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000587 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700588 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000589 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000590 }
591 return nil
592 }
mpagenko01e726e2020-10-23 09:45:29 +0000593 // note: theoretical it would be possible to clear the same rule from the remove slice
594 // (for entries that have not yet been started with removal)
595 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
596 // 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 +0000597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000598 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000599 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000600 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000601 // this is a restart with a complete new flow, we can re-use the initial flow config control
602 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000603 //attention: take care to release the mutexFlowParams when calling the FSM directly -
604 // synchronous FSM 'event/state' functions may rely on this mutex
605 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000606 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000607 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
608 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
609 }
mpagenko551a4d42020-12-08 18:09:20 +0000610 } else {
611 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000612 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000613 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000614 //check introduced after having observed some panic here
615 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000617 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
618 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000620 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700621 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000622 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700623
624 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000625 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700626 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000627 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700628 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000629 //attention: take care to release the mutexFlowParams when calling the FSM directly -
630 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000631 // but it must be released already before calling getTechProfileDone() as it may already be locked
632 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000633 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000634 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000635 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000636 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000637 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
638
mpagenkobb47bc22021-04-20 13:29:09 +0000639 var fsmErr error
640 if loTechProfDone {
641 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000642 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000643 } else {
644 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000645 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000646 }
647 if fsmErr != nil {
648 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
649 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000650 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700651 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000652 }
mpagenko551a4d42020-12-08 18:09:20 +0000653 }
mpagenkobb47bc22021-04-20 13:29:09 +0000654 } else {
655 // if not in the appropriate state a new entry will be automatically considered later
656 // when the configDone state is reached
657 oFsm.mutexFlowParams.Unlock()
658 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000659 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000660 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000661 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000662 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700663 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000664 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700665 return err
mpagenko01e726e2020-10-23 09:45:29 +0000666 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000667 } else {
668 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000669 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700670 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000671 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700672
mpagenko15ff4a52021-03-02 10:09:20 +0000673 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000674 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000675 //all requested rules really have been configured
676 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000677 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000678 if oFsm.pDeviceHandler != nil {
679 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000681 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000682 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
683 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000684 }
685 } else {
686 // avoid device reason update as the rule config connected to this flow may still be in progress
687 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000688 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000689 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000690 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000691 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000692 }
693 }
mpagenko01e726e2020-10-23 09:45:29 +0000694
mpagenkof1fc3862021-02-16 10:09:52 +0000695 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000696 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000697 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000698 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000699 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000700 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000701 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000702 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000703 }
mpagenko15ff4a52021-03-02 10:09:20 +0000704 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000705 }
706 return nil
707}
708
mpagenkof1d21d12021-06-11 13:14:45 +0000709func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
710 oFsm.mutexFlowParams.Lock()
711 deleteChannel := apRemoveFlowParams.removeChannel
712 apRemoveFlowParams.isSuspendedOnAdd = true
713 oFsm.mutexFlowParams.Unlock()
714
715 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
716 select {
717 case success := <-deleteChannel:
718 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
719 if success {
720 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
721 "device-id": oFsm.deviceID})
722 return nil
723 }
724 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
725 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
726 oFsm.mutexFlowParams.Lock()
727 if apRemoveFlowParams != nil {
728 apRemoveFlowParams.isSuspendedOnAdd = false
729 }
730 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000731 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000732 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000733 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000734 }
mpagenkof1d21d12021-06-11 13:14:45 +0000735}
736
mpagenkof1fc3862021-02-16 10:09:52 +0000737// VOL-3828 flow config sequence workaround ########### start ##########
738func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
739 //assumes mutexFlowParams.Lock() protection from caller!
740 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
741 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000742 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000743 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
744 newCookie := aCookieSlice[0]
745 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
746 for _, cookie := range storedUniFlowParams.CookieSlice {
747 if cookie == newCookie {
748 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
749 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
750 oFsm.delayNewRuleCookie = newCookie
751 return newCookie //found new cookie in some existing rule
752 }
753 } // for all stored cookies of the actual inspected rule
754 } //for all rules
755 }
756 return 0 //no delay requested
757}
mpagenkobc4170a2021-08-17 16:42:10 +0000758func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000759 oFsm.mutexFlowParams.RLock()
760 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
761 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
762 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000763 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000764 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000765 case cookieDeleted = <-oFsm.chCookieDeleted:
766 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
767 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000768 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000769 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
770 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
771 }
772 oFsm.mutexFlowParams.Lock()
773 oFsm.delayNewRuleCookie = 0
774 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000775 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000776}
mpagenkobc4170a2021-08-17 16:42:10 +0000777func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000778 oFsm.mutexFlowParams.Lock()
779 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
780 oFsm.mutexFlowParams.Unlock()
781
mpagenkobc4170a2021-08-17 16:42:10 +0000782 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000783 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000784 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000785 }
mpagenkobc4170a2021-08-17 16:42:10 +0000786 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000787}
788
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530789// returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000790func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000791 flowEntryMatch := false
792 oFsm.mutexFlowParams.Lock()
793 defer oFsm.mutexFlowParams.Unlock()
794 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
795 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
796 flowEntryMatch = true
797 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
798 "device-id": oFsm.deviceID})
799 cookieMatch := false
800 for _, cookie := range storedUniFlowParams.CookieSlice {
801 if cookie == aCookie {
802 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
803 "device-id": oFsm.deviceID, "cookie": cookie})
804 cookieMatch = true
805 break //found new cookie - no further search for this requested cookie
806 }
807 }
808 if !cookieMatch {
809 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
810 "device-id": oFsm.deviceID, "cookie": aCookie})
811 //as range works with copies of the slice we have to write to the original slice!!
812 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
813 aCookie)
814 return true, false //flowModified, NoRuleAppend
815 }
816 break // found rule - no further rule search
817 }
818 }
819 if !flowEntryMatch { //it is a new rule
820 return true, true //flowModified, RuleAppend
821 }
822 return false, false //flowNotModified, NoRuleAppend
823}
824
825// VOL-3828 flow config sequence workaround ########### end ##########
826
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530827// RemoveUniFlowParams verifies on existence of flow cookie,
mpagenko01e726e2020-10-23 09:45:29 +0000828// if found removes cookie from flow cookie list and if this is empty
829// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700830func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000831 if oFsm == nil {
832 logger.Error(ctx, "no valid UniVlanConfigFsm!")
833 return fmt.Errorf("no-valid-UniVlanConfigFsm")
834 }
mpagenkof1fc3862021-02-16 10:09:52 +0000835 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000836 flowCookieMatch := false
837 //mutex protection is required for possible concurrent access to FSM members
838 oFsm.mutexFlowParams.Lock()
839 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000840remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000841 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
842 for i, cookie := range storedUniFlowParams.CookieSlice {
843 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000844 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000845 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000846 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000847 //remove the cookie from the cookie slice and verify it is getting empty
848 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000849 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700850 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000851 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000852 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000853 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000854 //cut off the requested cookie by slicing out this element
855 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
856 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
857 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000858 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
859 // state transition notification is checked in deviceHandler
860 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000861 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
862 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000863 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000864 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000865 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000866 if deletedCookie == oFsm.delayNewRuleCookie {
867 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
868 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
869 //simply use the first one
870 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
871 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
872 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
873 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700874 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000875 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000876 //permanently store the modified flow config for reconcile case and immediately write to KvStore
877 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000878 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000879 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
880 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
881 return err
882 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000883 }
mpagenko01e726e2020-10-23 09:45:29 +0000884 }
mpagenkof1fc3862021-02-16 10:09:52 +0000885 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000886 }
887 }
mpagenko01e726e2020-10-23 09:45:29 +0000888 } //search all flows
889 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000890 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000891 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
892 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000893 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
894 // state transition notification is checked in deviceHandler
895 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000896 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000897 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000898 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700899 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000900 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000901 return nil
902 } //unknown cookie
903
904 return nil
905}
906
mpagenkof582d6a2021-06-18 15:58:10 +0000907// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000908// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000909func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700910 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000911 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000912 var cancelPendingConfig bool = false
913 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
914 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
915 "device-id": oFsm.deviceID})
916 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
917 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
918 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
919 // 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 +0000920 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000921 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
922 log.Fields{"device-id": oFsm.deviceID})
923 cancelPendingConfig = true
924 } else {
925 //create a new element for the removeVlanFlow slice
926 loRemoveParams = uniRemoveVlanFlowParams{
927 vlanRuleParams: aUniFlowParams.VlanRuleParams,
928 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700929 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000930 }
931 loRemoveParams.removeChannel = make(chan bool)
932 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
933 }
934
935 usedTpID := aUniFlowParams.VlanRuleParams.TpID
936 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
937 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
938 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
939 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000940 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
941 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000942 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
943 "device-id": oFsm.deviceID})
944 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000945 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000946 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000947 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000948 }
949 } else {
950 if !cancelPendingConfig {
951 oFsm.updateTechProfileToDelete(ctx, usedTpID)
952 }
953 }
954 //trigger the FSM to remove the relevant rule
955 if cancelPendingConfig {
956 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000957 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000958 //call from 'non-configured' state of the rules
959 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
960 //something quite inconsistent detected, perhaps just try to recover with FSM reset
961 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000962 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000963 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
964 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
965 }
966 return false //data base update could not be done, return like cookie not found
967 }
968
969 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
970 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
971 // synchronous FSM 'event/state' functions may rely on this mutex
972 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000973 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000974 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
975 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
976 }
977 oFsm.mutexFlowParams.Lock()
978 return true
979 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000980 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000981 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000982 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000983 "tp-id": loRemoveParams.vlanRuleParams.TpID,
984 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
985 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
986 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
987 // synchronous FSM 'event/state' functions may rely on this mutex
988 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000989 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000990 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
991 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
992 }
993 oFsm.mutexFlowParams.Lock()
994 } // if not in the appropriate state a new entry will be automatically considered later
995 // when the configDone state is reached
996 return true
997}
998
praneeth kumar nalmas3947c582023-12-13 15:38:50 +0530999// removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1000//
1001// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1002// from the start of the deletion request to avoid to much interference
1003// so when called, there can only be one cookie active for this flow
1004//
mpagenkof1d21d12021-06-11 13:14:45 +00001005// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001006func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001007 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1008 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001009 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001010removeFromSlice_loop:
1011 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001012 // if UniFlowParams exists, cookieSlice should always have at least one element
1013 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1014 if cookieSliceLen == 1 {
1015 if storedUniFlowParams.CookieSlice[0] == aCookie {
1016 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001017 }
mpagenkof582d6a2021-06-18 15:58:10 +00001018 } else if cookieSliceLen == 0 {
1019 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1020 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1021 return errors.New(errStr)
1022 } else {
1023 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1024 logger.Errorw(ctx, errStr, log.Fields{
1025 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1026 for _, cookie := range storedUniFlowParams.CookieSlice {
1027 if cookie == aCookie {
1028 cookieFound = true
1029 break
1030 }
1031 }
1032 }
1033 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001034 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1035 "device-id": oFsm.deviceID, "cookie": aCookie})
1036 //remove the actual element from the addVlanFlow slice
1037 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1038 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001039 oFsm.NumUniFlows = 0 //no more flows
1040 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001041 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1042 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1043 //request that this profile gets deleted before a new flow add is allowed
1044 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1045 "device-id": oFsm.deviceID})
1046 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 oFsm.NumUniFlows--
1048 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1049 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001050 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001051 if !aWasConfigured {
1052 // We did not actually process this flow but was removed before that.
1053 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001054 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001055 }
1056
mpagenkof1d21d12021-06-11 13:14:45 +00001057 //cut off the requested flow by slicing out this element
1058 oFsm.uniVlanFlowParamsSlice = append(
1059 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1060 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1061 "device-id": oFsm.deviceID})
1062 }
1063 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1064 }
1065 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001066 if !cookieFound {
1067 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1068 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1069 return errors.New(errStr)
1070 }
mpagenkodee02a62021-07-21 10:56:10 +00001071 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1072 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001073 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001074 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1075 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1076 return err
1077 }
mpagenkof582d6a2021-06-18 15:58:10 +00001078 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001079}
1080
1081// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001082func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1083 //here we have to check, if there are still other flows referencing to the actual ProfileId
1084 // before we can request that this profile gets deleted before a new flow add is allowed
1085 tpIDInOtherFlows := false
1086 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1087 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1088 tpIDInOtherFlows = true
1089 break // search loop can be left
1090 }
1091 }
1092 if tpIDInOtherFlows {
1093 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1094 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1095 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001096 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 +00001097 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001098 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1099 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001100 if oFsm.pUniTechProf != nil {
1101 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001102 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001103 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001104 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001105 }
1106}
1107
mpagenkof1d21d12021-06-11 13:14:45 +00001108func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1109 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001110
1111 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001112 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001113 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001114 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001115 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001117 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001119 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001120 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001121 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001122 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001123 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 go func(a_pAFsm *cmn.AdapterFsm) {
1125 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001126 }(pConfigVlanStateAFsm)
1127 return
1128 }
mpagenkof1d21d12021-06-11 13:14:45 +00001129 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130 go func(a_pAFsm *cmn.AdapterFsm) {
1131 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001132 }(pConfigVlanStateAFsm)
1133 return
1134 }
1135 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1136 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1137 //should never happen, else: recovery would be needed from outside the FSM
1138}
1139
1140func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1141 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001142 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001143 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001144 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001145 //possibly the entry is not valid anymore based on intermediate delete requests
1146 //just a basic protection ...
1147 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1148 oFsm.mutexFlowParams.Unlock()
1149 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1150 "device-id": oFsm.deviceID})
1151 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001152 go func(a_pAFsm *cmn.AdapterFsm) {
1153 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001154 }(pConfigVlanStateAFsm)
1155 return
1156 }
mpagenko9a304ea2020-12-16 15:54:01 +00001157 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1158 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001159 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1160 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001161 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001162 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001163 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1164 // synchronous FSM 'event/state' functions may rely on this mutex
1165 // but it must be released already before calling getTechProfileDone() as it may already be locked
1166 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001167 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001168 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001169 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001170 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001171 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001172
mpagenko9a304ea2020-12-16 15:54:01 +00001173 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001174 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1175 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001176 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001177 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001179 } else {
1180 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001181 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001182 }
1183 }
mpagenko551a4d42020-12-08 18:09:20 +00001184 }(pConfigVlanStateAFsm, loTechProfDone)
1185 } else {
1186 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1187 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1188 //should never happen, else: recovery would be needed from outside the FSM
1189 return
mpagenkodff5dda2020-08-28 11:52:01 +00001190 }
1191}
1192
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001194 //mutex protection is required for possible concurrent access to FSM members
1195 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001196 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001197 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001198 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001199 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001200 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001201 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001202 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001203 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001204 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001205 go func(a_pAFsm *cmn.AdapterFsm) {
1206 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001207 }(pConfigVlanStateAFsm)
1208 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001209 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1210 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001211 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001212 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001213 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001214 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001215 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001216 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001217 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001218 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001219 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001220 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1221 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001222 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001223 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001224 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001225 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList, //omci lib wants a slice for serialization
1226 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1227 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001228 },
1229 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001231 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001232 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001233 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1234 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001235 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001236 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001237 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1238 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001239 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001240 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 go func(a_pAFsm *cmn.AdapterFsm) {
1242 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001243 }(pConfigVlanStateAFsm)
1244 }
1245 return
1246 }
mpagenkodff5dda2020-08-28 11:52:01 +00001247 //accept also nil as (error) return value for writing to LastTx
1248 // - this avoids misinterpretation of new received OMCI messages
1249 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1250 // send shall return (dual format) error code that can be used here for immediate error treatment
1251 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001252 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001253 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001254 }
1255}
1256
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1258 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001259 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001260 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001261 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001262 //using the first element in the slice because it's the first flow per definition here
1263 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001264 //This is correct passing scenario
1265 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001266 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001267 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1268 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001269 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001270 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1271 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001272 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001273 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001275 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001276 vlanID)
1277 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001278 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001279 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001281 }
1282 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001283 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001284 if oFsm.actualUniFlowParam.Meter != nil {
1285 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001286 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001287 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1288 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001289 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001290 if errCreateTrafficDescriptor != nil {
1291 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1292 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001294 }
1295 }
1296 }
1297
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001298 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001299 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001300 }
1301 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001302}
1303
dbainbri4d3a0dc2020-12-02 00:33:42 +00001304func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001305
mpagenkof1d21d12021-06-11 13:14:45 +00001306 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001307
mpagenkof1fc3862021-02-16 10:09:52 +00001308 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001309 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001310 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
mpagenko101ac942021-11-16 15:01:29 +00001311 if len(oFsm.uniVlanFlowParamsSlice) > 0 && !oFsm.pDeviceHandler.IsReconciling() {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001312 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001313 }
1314
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001315 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001316 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001317 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001318 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1319 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1320 //should never happen, else: recovery would be needed from outside the FSM
1321 return
1322 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001324 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1325 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001326 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001328 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1329 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001330 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001331 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001332 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001333 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001334 }(pConfigVlanStateBaseFsm)
1335 return
1336 }
Holger Hildebrandt7741f272022-01-18 08:17:39 +00001337 if oFsm.lastFlowToReconcile {
1338 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1339 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1340 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1341 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
1342 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(uint16(oFsm.pOnuUniPort.UniID))
1343 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001344 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1345 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001346 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001347 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001348 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001349 return
1350 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001351 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1352 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001353 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001354 // this is a restart with a complete new flow, we can re-use the initial flow config control
1355 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001356 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001357 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001358 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001359 }(pConfigVlanStateBaseFsm)
1360 return
1361 }
1362
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001363 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001364 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001365 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001366 //check introduced after having observed some panic in this processing
1367 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001368 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001369 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1370 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 go func(a_pAFsm *cmn.AdapterFsm) {
1372 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001373 }(pConfigVlanStateAFsm)
1374 return
1375 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001376 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001377 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001378 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001379 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001380 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001381 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1382 // synchronous FSM 'event/state' functions may rely on this mutex
1383 // but it must be released already before calling getTechProfileDone() as it may already be locked
1384 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1385 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001386 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001387 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001388 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001389 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1390
mpagenko9a304ea2020-12-16 15:54:01 +00001391 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001392 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1393 if aTechProfDone {
1394 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001395 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001396 } else {
1397 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001398 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001399 }
1400 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001401 return
1402 }
mpagenkof1d21d12021-06-11 13:14:45 +00001403 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001405 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001406 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1407 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001408 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001409 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001410 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001412 }
1413}
1414
dbainbri4d3a0dc2020-12-02 00:33:42 +00001415func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001416
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001418 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001420 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001421 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1422 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001423 return
1424 }
mpagenko15ff4a52021-03-02 10:09:20 +00001425 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001426 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001427 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001428 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001429 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001430
Girish Gowdrae95687a2021-09-08 16:30:58 -07001431 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001432 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001434 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001435 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001436 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1437 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1438 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1439 // 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 +00001440 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001441 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1442 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001443 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001444 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001446 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001447 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001448 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001449 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001450 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001451
mpagenko01e726e2020-10-23 09:45:29 +00001452 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001453 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1454 oFsm.numVlanFilterEntries = 1
1455 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001456 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001457 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001458 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1459 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1460 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001461 },
1462 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001463 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001464 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1465 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001466 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001467 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001468 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001469 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1470 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001471 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001472 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001473 go func(a_pAFsm *cmn.AdapterFsm) {
1474 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001475 }(pConfigVlanStateAFsm)
1476 }
1477 return
1478 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001479 //accept also nil as (error) return value for writing to LastTx
1480 // - this avoids misinterpretation of new received OMCI messages
1481 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1482 // send shall return (dual format) error code that can be used here for immediate error treatment
1483 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001484 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001485 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001486 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001487 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1488 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001489 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001490
dbainbri4d3a0dc2020-12-02 00:33:42 +00001491 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001492 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001493 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001494 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001495 // setVid is assumed to be masked already by the caller to 12 bit
1496 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001497 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001498 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001499
1500 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1501 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1502 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001503 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001504
1505 oFsm.numVlanFilterEntries++
1506 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001507 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001508 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00001509 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
1510 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
1511 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001512 },
1513 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001514 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001515 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1516 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001517 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001518 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001519 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001520 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1521 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001522 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001523 return
1524 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001525 //accept also nil as (error) return value for writing to LastTx
1526 // - this avoids misinterpretation of new received OMCI messages
1527 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1528 // send shall return (dual format) error code that can be used here for immediate error treatment
1529 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001530 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001531 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001532 }
1533 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001534 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001535 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001536 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001538 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001539 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001540 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001541 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001542 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001543 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001544 return
1545 }
1546 }
mpagenkof1d21d12021-06-11 13:14:45 +00001547
mpagenkof1fc3862021-02-16 10:09:52 +00001548 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001549 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001550 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001551 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001552 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1553 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001554 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001555 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001556 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001557 //This is correct passing scenario
1558 if errEvto == nil {
1559 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001560 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001561 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001562 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001565 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001566 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001570 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001572 }
1573 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001574 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001575 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001576 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001577 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1578 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001580 if errCreateTrafficDescriptor != nil {
1581 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1582 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001583 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001584 }
1585 }
1586 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001587 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001588 }
1589 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001590}
1591
dbainbri4d3a0dc2020-12-02 00:33:42 +00001592func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001593 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001595 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1596 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001597
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001598 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1599 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001600 loVlanEntryClear := uint8(0)
1601 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1602 //shallow copy is sufficient as no reference variables are used within struct
1603 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001604 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001606 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1607 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1608 "device-id": oFsm.deviceID})
1609
1610 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1611 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001613 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1614 } else {
1615 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1616 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001617 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001618 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1619 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001621 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001622 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001624 loVlanEntryClear = 1 //full VlanFilter clear request
1625 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001626 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001627 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1628 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001629 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001630 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001631 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1632 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001634 return
1635 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001636 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001637 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001640 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001641 }
mpagenko01e726e2020-10-23 09:45:29 +00001642 } else {
1643 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1644 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001646 log.Fields{"current vlan list": oFsm.vlanFilterList,
1647 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1648 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1649 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1650 loVlanEntryRmPos = i
1651 break //abort search
1652 }
1653 }
1654 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001655 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001656 //valid entry was found - to be eclipsed
1657 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1658 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1659 if i < loVlanEntryRmPos {
1660 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1661 } else if i < (cVtfdTableSize - 1) {
1662 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1663 } else {
1664 vtfdFilterList[i] = 0 //set last byte if needed
1665 }
1666 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001667 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001668 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001669 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001670 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001671
mpagenkofc4f56e2020-11-04 17:17:49 +00001672 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001673 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001674 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001675 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1676 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001677 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001678 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001679 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1680 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001682 return
1683 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001684 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001685 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001686 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001688 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001689 }
mpagenko01e726e2020-10-23 09:45:29 +00001690 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001691 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001692 log.Fields{"device-id": oFsm.deviceID})
1693 }
1694 }
1695 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001696 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1697 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001698 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001699 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001700 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001701 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001702 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001703 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001704 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001705 }(pConfigVlanStateBaseFsm)
1706 return
1707 }
mpagenko01e726e2020-10-23 09:45:29 +00001708 }
1709
mpagenko15ff4a52021-03-02 10:09:20 +00001710 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001711 if loVlanEntryClear == 1 {
1712 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1713 oFsm.numVlanFilterEntries = 0
1714 } else if loVlanEntryClear == 2 {
1715 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1716 // this loop now includes the 0 element on previous last valid entry
1717 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1718 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1719 }
1720 oFsm.numVlanFilterEntries--
1721 }
mpagenko15ff4a52021-03-02 10:09:20 +00001722 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001723 }
1724 }
1725
mpagenkofc4f56e2020-11-04 17:17:49 +00001726 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001728 } else {
1729 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001731 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001732 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001733 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001734 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001735 }(pConfigVlanStateBaseFsm)
1736 }
mpagenkodff5dda2020-08-28 11:52:01 +00001737}
1738
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001740 var tpID uint8
1741 // Extract the tpID
1742 if len(e.Args) > 0 {
1743 tpID = e.Args[0].(uint8)
1744 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1745 } else {
1746 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1747 }
mpagenko01e726e2020-10-23 09:45:29 +00001748 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001749 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001750
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001751 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001752 if pConfigVlanStateAFsm == nil {
1753 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1754 log.Fields{"device-id": oFsm.deviceID})
1755 //would have to be fixed from outside somehow
1756 return
1757 }
1758
mpagenkof1d21d12021-06-11 13:14:45 +00001759 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1760 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001761 //call from 'configured' state of the rule
1762 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1763 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1764 oFsm.mutexFlowParams.Unlock()
1765 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001766 go func(a_pAFsm *cmn.AdapterFsm) {
1767 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001768 }(pConfigVlanStateAFsm)
1769 return
1770 }
mpagenkof1d21d12021-06-11 13:14:45 +00001771 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1772 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1773 oFsm.mutexFlowParams.Unlock()
1774 removeChannel <- true
1775 oFsm.mutexFlowParams.Lock()
1776 }
1777
mpagenkof1fc3862021-02-16 10:09:52 +00001778 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1779 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1780 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1781
Girish Gowdrae95687a2021-09-08 16:30:58 -07001782 // Store the reference to the flow response channel before this entry in the slice is deleted
1783 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1784
mpagenko01e726e2020-10-23 09:45:29 +00001785 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1786 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001788 "device-id": oFsm.deviceID})
1789 } else {
1790 //cut off the actual flow by slicing out the first element
1791 oFsm.uniRemoveFlowsSlice = append(
1792 oFsm.uniRemoveFlowsSlice[:0],
1793 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001794 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001795 "device-id": oFsm.deviceID})
1796 }
1797 oFsm.mutexFlowParams.Unlock()
1798
mpagenkof1fc3862021-02-16 10:09:52 +00001799 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001800 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001801 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001802 go func(a_pAFsm *cmn.AdapterFsm) {
1803 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001804 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001805
mpagenkobb47bc22021-04-20 13:29:09 +00001806 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001807 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001808 if deletedCookie == oFsm.delayNewRuleCookie {
1809 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1810 select {
1811 case <-oFsm.chCookieDeleted:
1812 logger.Debug(ctx, "flushed CookieDeleted")
1813 default:
1814 }
1815 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1816 }
mpagenkobb47bc22021-04-20 13:29:09 +00001817 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1818 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1819 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 -08001820 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001821 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1822 oFsm.flowDeleteChannel <- true
1823 oFsm.signalOnFlowDelete = false
1824 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001825 }
mpagenkobb47bc22021-04-20 13:29:09 +00001826 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001827
1828 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001829 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001830}
1831
dbainbri4d3a0dc2020-12-02 00:33:42 +00001832func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1833 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001834
mpagenko0f543222021-11-03 16:24:14 +00001835 oFsm.mutexPLastTxMeInstance.Lock()
1836 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1837 oFsm.mutexPLastTxMeInstance.Unlock()
1838
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001839 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001840 if pConfigVlanStateAFsm != nil {
1841 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001842 fsmAbortMsg := cmn.Message{
1843 Type: cmn.TestMsg,
1844 Data: cmn.TestMessage{
1845 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001846 },
1847 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001848 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001849
mpagenko0f543222021-11-03 16:24:14 +00001850 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1851 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1852
1853 oFsm.mutexFlowParams.RLock()
1854 if oFsm.delayNewRuleCookie != 0 {
1855 // looks like the waiting AddFlow is stuck
1856 oFsm.mutexFlowParams.RUnlock()
1857 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1858 select {
1859 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1860 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001861 }
mpagenko0f543222021-11-03 16:24:14 +00001862 oFsm.mutexFlowParams.RLock()
1863 }
1864 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1865 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1866 if removeUniFlowParams.isSuspendedOnAdd {
1867 removeChannel := removeUniFlowParams.removeChannel
1868 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1869 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1870 oFsm.mutexFlowParams.RUnlock()
1871 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1872 select {
1873 case removeChannel <- false:
1874 default:
1875 }
1876 oFsm.mutexFlowParams.RLock()
1877 }
1878 // Send response on response channel if the caller is waiting on it.
1879 var err error = nil
1880 if !oFsm.isCanceled {
1881 //only if the FSM is not canceled on external request use some error indication for the respChan
1882 // so only at real internal FSM abortion some error code is sent back
1883 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1884 err = fmt.Errorf("internal-error")
1885 }
1886 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1887 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1888 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1889 }
1890 }
1891
1892 if oFsm.pDeviceHandler != nil {
1893 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1894 if !oFsm.isCanceled {
1895 //if the FSM is not canceled on external request use "internal-error" for the respChan
1896 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1897 // Send response on response channel if the caller is waiting on it with according error indication.
1898 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1899 }
1900 //permanently remove possibly stored persistent data
1901 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1902 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1903 } else {
1904 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1905 // no need to remove specific data in this case here
nikesh.krishnanc7c0bce2023-12-20 21:36:35 +05301906 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1907 // Send response on response channel if the caller is waiting on it with according error indication.
1908 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("config-cancelled"))
1909 }
mpagenko0f543222021-11-03 16:24:14 +00001910 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1911 }
1912 }
1913 oFsm.mutexFlowParams.RUnlock()
1914
1915 //try to let the FSM proceed to 'disabled'
1916 // Can't call FSM Event directly, decoupling it
1917 go func(a_pAFsm *cmn.AdapterFsm) {
1918 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1919 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1920 }
1921 }(pConfigVlanStateAFsm)
1922 return
1923 }
1924 oFsm.mutexFlowParams.RUnlock()
1925 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1926 log.Fields{"device-id": oFsm.deviceID})
1927 return
mpagenkodff5dda2020-08-28 11:52:01 +00001928 }
mpagenko0f543222021-11-03 16:24:14 +00001929 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1930 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001931}
1932
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1934 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001935
mpagenkodff5dda2020-08-28 11:52:01 +00001936 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001937 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001939 return
mpagenkodff5dda2020-08-28 11:52:01 +00001940 }
mpagenko0f543222021-11-03 16:24:14 +00001941 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1942 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001943}
1944
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1946 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001947loop:
1948 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001949 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001951 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001952 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301953 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001954 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301955 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001956 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301957 break loop
1958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301960
1961 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001962 case cmn.TestMsg:
1963 msg, _ := message.Data.(cmn.TestMessage)
1964 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001965 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001966 break loop
1967 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001969 case cmn.OMCI:
1970 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001971 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301972 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301974 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001975 }
1976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001978}
1979
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001980func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001982 "msgType": msg.OmciMsg.MessageType})
1983
1984 switch msg.OmciMsg.MessageType {
1985 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001986 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00001988 logger.Warnw(ctx, "CreateResponse handling aborted",
1989 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001990 return
1991 }
mpagenkodff5dda2020-08-28 11:52:01 +00001992 } //CreateResponseType
1993 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001994 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001995 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1996 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001998 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001999 return
2000 }
2001 msgObj, msgOk := msgLayer.(*omci.SetResponse)
2002 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002003 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002004 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002005 return
2006 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00002008 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002010 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002011 // possibly force FSM into abort or ignore some errors for some messages?
2012 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2013 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenkodff5dda2020-08-28 11:52:01 +00002014 return
2015 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002016 oFsm.mutexPLastTxMeInstance.RLock()
2017 if oFsm.pLastTxMeInstance != nil {
2018 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2019 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2020 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002021 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002022 { // let the MultiEntity config proceed by stopping the wait function
2023 oFsm.mutexPLastTxMeInstance.RUnlock()
2024 oFsm.omciMIdsResponseReceived <- true
2025 return
2026 }
2027 default:
2028 {
2029 logger.Warnw(ctx, "Unsupported ME name received!",
2030 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2031 }
mpagenkodff5dda2020-08-28 11:52:01 +00002032 }
2033 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002034 } else {
2035 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002036 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002037 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002038 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002039 case omci.DeleteResponseType:
2040 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002041 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
Holger Hildebrandtabfef032022-02-25 12:40:20 +00002042 logger.Warnw(ctx, "DeleteResponse handling aborted",
2043 log.Fields{"device-id": oFsm.deviceID, "err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002044 return
2045 }
2046 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002047 default:
2048 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002050 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002051 return
2052 }
2053 }
2054}
2055
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002057 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2058 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002060 log.Fields{"device-id": oFsm.deviceID})
2061 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2062 oFsm.deviceID)
2063 }
2064 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2065 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002067 log.Fields{"device-id": oFsm.deviceID})
2068 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2069 oFsm.deviceID)
2070 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002071 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002072 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002074 "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002075 // possibly force FSM into abort or ignore some errors for some messages?
2076 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2077 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002078 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2079 oFsm.deviceID)
2080 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002081 oFsm.mutexPLastTxMeInstance.RLock()
2082 if oFsm.pLastTxMeInstance != nil {
2083 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2084 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2085 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2086 switch oFsm.pLastTxMeInstance.GetName() {
2087 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2088 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002089 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002090 {
2091 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002092 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002093 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002094 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002095 } else { // let the MultiEntity config proceed by stopping the wait function
2096 oFsm.omciMIdsResponseReceived <- true
2097 }
2098 return nil
2099 }
2100 default:
2101 {
2102 logger.Warnw(ctx, "Unsupported ME name received!",
2103 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002104 }
2105 }
2106 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002107 } else {
2108 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002109 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002110 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002111 return nil
2112}
2113
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002115 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2116 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002118 log.Fields{"device-id": oFsm.deviceID})
2119 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2120 oFsm.deviceID)
2121 }
2122 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2123 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002124 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002125 log.Fields{"device-id": oFsm.deviceID})
2126 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2127 oFsm.deviceID)
2128 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
Akash Soni8eff4632024-12-11 13:41:46 +05302130 if msgObj.Result == me.UnknownInstance {
2131 logger.Warnw(ctx, "UniVlanConfigFsm - Unknow Instance",
2132 log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj, "Error": msgObj.Result})
2133 } else if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002135 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002136 // possibly force FSM into abort or ignore some errors for some messages?
2137 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureResponseErr, msgObj.EntityClass,
2138 msgObj.EntityInstance, msgObj.EntityClass.String(), msgObj.Result)
mpagenko01e726e2020-10-23 09:45:29 +00002139 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2140 oFsm.deviceID)
2141 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002142 oFsm.mutexPLastTxMeInstance.RLock()
2143 if oFsm.pLastTxMeInstance != nil {
2144 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2145 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2146 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002147 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002148 { // let the MultiEntity config proceed by stopping the wait function
2149 oFsm.mutexPLastTxMeInstance.RUnlock()
2150 oFsm.omciMIdsResponseReceived <- true
2151 return nil
2152 }
2153 default:
2154 {
2155 logger.Warnw(ctx, "Unsupported ME name received!",
2156 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2157 }
mpagenko01e726e2020-10-23 09:45:29 +00002158 }
2159 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002160 } else {
2161 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002162 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002163 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002164 return nil
2165}
2166
dbainbri4d3a0dc2020-12-02 00:33:42 +00002167func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002168 oFsm.mutexFlowParams.RLock()
2169 evtocdID := oFsm.evtocdID
2170 oFsm.mutexFlowParams.RUnlock()
2171
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002172 if aFlowEntryNo == 0 {
2173 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002174 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2175 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002176 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002177 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002178 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002179 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002180 associationType := 2 // default to UniPPTP
2181 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002182 associationType = 10
2183 }
2184 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002185 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002186 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002187 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002188 me.ExtendedVlanTaggingOperationConfigurationData_AssociationType: uint8(associationType),
2189 me.ExtendedVlanTaggingOperationConfigurationData_AssociatedMePointer: oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002190 },
2191 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002192 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002193 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2194 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002195 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002196 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002197 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2198 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002199 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002200 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2201 }
mpagenkodff5dda2020-08-28 11:52:01 +00002202 //accept also nil as (error) return value for writing to LastTx
2203 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002204 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002205 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002206
2207 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002208 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002209 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002211 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002212 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002213 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2214 }
2215
2216 // Set the EVTOCD ME default params
2217 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002218 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002219 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002220 me.ExtendedVlanTaggingOperationConfigurationData_InputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2221 me.ExtendedVlanTaggingOperationConfigurationData_OutputTpid: uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2222 me.ExtendedVlanTaggingOperationConfigurationData_DownstreamMode: uint8(cDefaultDownstreamMode),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002223 },
2224 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002225 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2227 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2228 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002229 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002230 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002231 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2232 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002233 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002234 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2235 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002236 //accept also nil as (error) return value for writing to LastTx
2237 // - this avoids misinterpretation of new received OMCI messages
2238 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002239 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002240
2241 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002242 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002243 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002245 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002246 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002247 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002248 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002249 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002250
mpagenko551a4d42020-12-08 18:09:20 +00002251 oFsm.mutexFlowParams.RLock()
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302252 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) &&
2253 uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenkodff5dda2020-08-28 11:52:01 +00002254 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002255 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002256 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002257 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002258 sliceEvtocdRule := make([]uint8, 16)
2259 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2260 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2261 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2262 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2263 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2264
2265 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2266 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2267 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2268 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2269 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2270
2271 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2272 0<<cTreatTTROffset| // Do not pop any tags
2273 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2274 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2275 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2276
2277 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2278 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2279 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2280 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2281
2282 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002283 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002284 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002285 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002286 },
2287 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002288 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002289 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2290 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2291 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002292 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002293 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002294 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2295 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002296 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002297 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2298 }
mpagenkodff5dda2020-08-28 11:52:01 +00002299 //accept also nil as (error) return value for writing to LastTx
2300 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002301 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002302 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002303
2304 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002305 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002306 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002307 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002308 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002309 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002310 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2311
mpagenkodff5dda2020-08-28 11:52:01 +00002312 }
2313 } else {
2314 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2315 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002316 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2317 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2318 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2319 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302320 innerCvlan := oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan
mpagenkodff5dda2020-08-28 11:52:01 +00002321 sliceEvtocdRule := make([]uint8, 16)
mpagenkodff5dda2020-08-28 11:52:01 +00002322
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302323 if uint32(oFsm.actualUniFlowParam.VlanRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
2324 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2325 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
2326 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
2327 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2328 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2329 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2330 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2331 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenkodff5dda2020-08-28 11:52:01 +00002332
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302333 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2334 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2335 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2336 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2337 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenkodff5dda2020-08-28 11:52:01 +00002338
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302339 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2340 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2341 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2342 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2343 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2344
2345 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2346 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2347 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
2348 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2349
2350 } else {
2351 //Double tagged case, if innerCvlan is 4096 then transparent, else match on the innerCvlan
2352 //As of now only a match and no action can be done on the inner tag .
2353 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD double tagged translation rule", log.Fields{
2354 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "inner-cvlan:": innerCvlan, "device-id": oFsm.deviceID})
2355 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2356 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2357 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or filter priority
2358 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2359 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2360
2361 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2362 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2363 uint32(innerCvlan)<<cFilterVidOffset| // transparent of innercvlan is 4096 or filter with innercvlan
2364 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2365 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2366
2367 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2368 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
2369 cCopyPrioFromOuter<<cTreatPrioOffset| // add tag and copy prio from outer from the received frame
2370 setVid<<cTreatVidOffset| // Set VID
2371 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2372
2373 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2374 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2375 uint32(innerCvlan)<<cTreatVidOffset| //as configured in flow
2376 cDontCareTpid<<cTreatTpidOffset) // Set TPID = 0x8100
2377 }
mpagenko551a4d42020-12-08 18:09:20 +00002378 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002379 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002380 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002381 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002382 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002383 },
2384 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002385 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002386 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2387 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2388 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002389 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002390 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002391 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2392 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002393 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002394 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2395 }
mpagenkodff5dda2020-08-28 11:52:01 +00002396 //accept also nil as (error) return value for writing to LastTx
2397 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002398 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002399 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002400
2401 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002402 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002403 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302404 logger.Errorw(ctx, "Evtocd set rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002405 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002406 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302407 return fmt.Errorf("evtocd set rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002408 }
2409 } else {
2410 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2411 { // just for local var's
2412 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002413 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002414 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002415 sliceEvtocdRule := make([]uint8, 16)
2416 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2417 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2418 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2419 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2420 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2421
2422 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2423 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2424 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2425 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2426 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2427
2428 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2429 0<<cTreatTTROffset| // Do not pop any tags
2430 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2431 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2432 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2433
2434 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2435 0<<cTreatPrioOffset| // vlan prio set to 0
2436 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002437 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002438 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2439
mpagenko551a4d42020-12-08 18:09:20 +00002440 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002441 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002442 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002443 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002444 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002445 },
2446 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002447 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002448 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2449 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2450 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002451 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002452 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002453 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2454 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002455 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002456 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2457 }
mpagenkodff5dda2020-08-28 11:52:01 +00002458 //accept also nil as (error) return value for writing to LastTx
2459 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002460 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002462
2463 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002464 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002465 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002466 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002467 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002468 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002469 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2470
mpagenkodff5dda2020-08-28 11:52:01 +00002471 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002472 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002473 { // just for local var's
2474 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002475 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002476 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002477 sliceEvtocdRule := make([]uint8, 16)
2478 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2479 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2480 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2481 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2482 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2483
2484 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2485 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2486 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2487 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2488 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2489
2490 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2491 1<<cTreatTTROffset| // pop the prio-tag
2492 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2493 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2494 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2495
mpagenko551a4d42020-12-08 18:09:20 +00002496 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002497 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2498 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2499 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002500 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002501 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002502 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002503
2504 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002505 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002506 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002507 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenkodff5dda2020-08-28 11:52:01 +00002508 },
2509 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002510 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002511 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2512 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2513 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002514 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002515 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002516 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2517 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002519 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2520 }
mpagenkodff5dda2020-08-28 11:52:01 +00002521 //accept also nil as (error) return value for writing to LastTx
2522 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002523 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002524 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002525
2526 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002527 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002528 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002529 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002530 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002531 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002532 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2533
mpagenkodff5dda2020-08-28 11:52:01 +00002534 }
2535 } //just for local var's
2536 }
2537 }
2538
mpagenkofc4f56e2020-11-04 17:17:49 +00002539 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002540 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002541 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002542 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002543 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002544 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002545}
2546
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002547func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002548 oFsm.mutexFlowParams.RLock()
2549 evtocdID := oFsm.evtocdID
2550 oFsm.mutexFlowParams.RUnlock()
2551
mpagenko01e726e2020-10-23 09:45:29 +00002552 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2553 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2554 //transparent transmission was set
2555 //perhaps the config is not needed for removal,
2556 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002557 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002558 "device-id": oFsm.deviceID})
2559 sliceEvtocdRule := make([]uint8, 16)
2560 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2561 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2562 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2563 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2564 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2565
2566 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2567 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2568 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2569 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2570 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2571
2572 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2573 0<<cTreatTTROffset| // Do not pop any tags
2574 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2575 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2576 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2577
2578 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2579 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2580 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2581 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2582
2583 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002584 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002585 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002586 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002587 },
2588 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002589 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002590 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2591 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2592 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002593 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002594 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002595 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2596 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002597 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002598 return
2599 }
mpagenko01e726e2020-10-23 09:45:29 +00002600 //accept also nil as (error) return value for writing to LastTx
2601 // - this avoids misinterpretation of new received OMCI messages
2602 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002603 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002604
2605 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002606 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002607 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002608 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002609 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002610 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002611 return
2612 }
2613 } else {
2614 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002615 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002616 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002617 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002618 sliceEvtocdRule := make([]uint8, 16)
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302619 if uint32(aRuleParams.InnerCvlan) == uint32(of.OfpVlanId_OFPVID_NONE) {
mpagenko01e726e2020-10-23 09:45:29 +00002620
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302621 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
2622 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
2623 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2624 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2625 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2626 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2627 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2628 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002629
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302630 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2631 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2632 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2633 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2634 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002635
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302636 // delete indication for the indicated Filter
2637 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2638 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2639
2640 } else {
2641 // this defines VID translation scenario: dobletagged-doubletagged (if not transparent)
2642 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear double tagged rule", log.Fields{
2643 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid, "innerCvlan": aRuleParams.InnerCvlan})
2644 sliceEvtocdRule := make([]uint8, 16)
2645 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2646 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2647 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2648 aRuleParams.MatchVid<<cFilterVidOffset| // Do not filter on outer vid
2649 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2650
2651 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2652 cPrioIgnoreTag<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2653 cDoNotFilterVid<<cFilterVidOffset| // DNFonVid or ignore tag
2654 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2655 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2656
2657 // delete indication for the indicated Filter
2658 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2659 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2660 }
mpagenko01e726e2020-10-23 09:45:29 +00002661 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002662 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002663 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002664 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
mpagenko01e726e2020-10-23 09:45:29 +00002665 },
2666 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002667 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002668 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2669 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2670 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002671 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002672 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002673 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2674 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002675 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002676 return
2677 }
mpagenko01e726e2020-10-23 09:45:29 +00002678 //accept also nil as (error) return value for writing to LastTx
2679 // - this avoids misinterpretation of new received OMCI messages
2680 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002681 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002682
2683 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002684 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002685 if err != nil {
Abhilash Laxmeshwar81b5ccf2022-03-17 15:04:18 +05302686 logger.Errorw(ctx, "Evtocd clear rule failed, aborting VlanConfig FSM!",
2687 log.Fields{"device-id": oFsm.deviceID,
2688 "match-vlan": aRuleParams.MatchVid,
2689 "InnerCvlan": aRuleParams.InnerCvlan})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002690 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002691 return
2692 }
2693 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002694 // VOL-3685
2695 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2696 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2697 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2698 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2699 // later when the flow is being re-installed.
2700 // Of course this is applicable to case only where single service (or single tcont) is in use and
2701 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2702 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2703 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002704 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002705 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002706 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002707 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2708 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002709 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002710 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002711 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002712 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002713 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2714 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2715 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002716 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002717 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002718 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2719 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002720 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002721 return
2722 }
mpagenko01e726e2020-10-23 09:45:29 +00002723 //accept also nil as (error) return value for writing to LastTx
2724 // - this avoids misinterpretation of new received OMCI messages
2725 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002726 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002727
2728 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002729 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002730 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002731 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002732 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002733 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002734 return
2735 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002736 } else {
2737 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2738 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002739 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002740 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002741 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002742 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2743 { // just for local var's
2744 // this defines stacking scenario: untagged->singletagged
2745 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2746 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2747 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2748 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002749 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002750 "device-id": oFsm.deviceID})
2751 sliceEvtocdRule := make([]uint8, 16)
2752 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2753 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2754 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2755 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2756 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002757
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002758 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2759 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2760 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2761 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2762 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002763
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002764 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2765 0<<cTreatTTROffset| // Do not pop any tags
2766 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2767 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2768 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002769
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002770 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2771 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2772 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2773 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002774
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002775 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002776 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002777 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002778 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002779 },
2780 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002781 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002782 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2783 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2784 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002785 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002786 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002787 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2788 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002789 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002790 return
2791 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002792 //accept also nil as (error) return value for writing to LastTx
2793 // - this avoids misinterpretation of new received OMCI messages
2794 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002795 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002796
2797 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002798 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002799 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002801 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002803 return
2804 }
2805 } // just for local var's
2806 { // just for local var's
2807 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002808 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002809 "device-id": oFsm.deviceID})
2810 sliceEvtocdRule := make([]uint8, 16)
2811 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2812 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2813 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2814 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2815 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2816
2817 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2818 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2819 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2820 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2821 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2822
2823 // delete indication for the indicated Filter
2824 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2825 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2826
2827 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002828 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002829 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002830 me.ExtendedVlanTaggingOperationConfigurationData_ReceivedFrameVlanTaggingOperationTable: sliceEvtocdRule,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002831 },
2832 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002833 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002834 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2835 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2836 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002837 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002838 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002839 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2840 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002842 return
2843 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844 //accept also nil as (error) return value for writing to LastTx
2845 // - this avoids misinterpretation of new received OMCI messages
2846 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002847 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848
2849 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002850 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002851 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002852 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002853 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002854 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002855 return
2856 }
mpagenko01e726e2020-10-23 09:45:29 +00002857 }
2858 } //just for local var's
2859 }
2860 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002861 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002862 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002863 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002864}
2865
dbainbri4d3a0dc2020-12-02 00:33:42 +00002866func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002867 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002868 if oFsm.isCanceled {
2869 // FSM already canceled before entering wait
2870 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2871 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002872 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002873 }
mpagenko7d6bb022021-03-11 15:07:55 +00002874 oFsm.isAwaitingResponse = true
2875 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002876 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302877 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002878 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002879 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002880 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002882 oFsm.mutexIsAwaitingResponse.Lock()
2883 oFsm.isAwaitingResponse = false
2884 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt7e138462023-03-29 12:12:14 +00002885 oFsm.mutexPLastTxMeInstance.RLock()
2886 if oFsm.pLastTxMeInstance != nil {
2887 oFsm.pOmciCC.NotifyAboutOnuConfigFailure(ctx, cmn.OnuConfigFailureTimeout, oFsm.pLastTxMeInstance.GetClassID(),
2888 oFsm.pLastTxMeInstance.GetEntityID(), oFsm.pLastTxMeInstance.GetClassID().String(), 0)
2889 }
2890 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002891 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002892 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302893 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002894 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002895 oFsm.mutexIsAwaitingResponse.Lock()
2896 oFsm.isAwaitingResponse = false
2897 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002898 return nil
2899 }
mpagenko7d6bb022021-03-11 15:07:55 +00002900 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002901 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002902 oFsm.mutexIsAwaitingResponse.Lock()
2903 oFsm.isAwaitingResponse = false
2904 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002906 }
2907}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002908
mpagenko551a4d42020-12-08 18:09:20 +00002909func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002911 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002912 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002913 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002914 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002915 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002916 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002917 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2918 }
2919
dbainbri4d3a0dc2020-12-02 00:33:42 +00002920 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002921 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002922 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002923 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002924 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2926 }
2927
dbainbri4d3a0dc2020-12-02 00:33:42 +00002928 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002929 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002930 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002931 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002932 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002933 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2934 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002935 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002936 if errMacBpCdEID != nil {
2937 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2938 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002939 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002940 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002941
Mahir Gunyel6781f962021-05-16 23:30:08 -07002942 }
2943 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002944 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2945 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002947 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002948 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002949 me.MacBridgePortConfigurationData_BridgeIdPointer: cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
2950 me.MacBridgePortConfigurationData_PortNum: 0xf0, //fixed unique ANI side indication
2951 me.MacBridgePortConfigurationData_TpType: 6, //MCGemIWTP
2952 me.MacBridgePortConfigurationData_TpPointer: multicastGemPortID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 },
2954 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002955 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002956 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2957 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002958 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002959 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002960 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2961 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002962 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002963 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2964 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002965 //accept also nil as (error) return value for writing to LastTx
2966 // - this avoids misinterpretation of new received OMCI messages
2967 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002968 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002969 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002970 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002971 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002972 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2973 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002974 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2975 }
2976
2977 // ==> Start creating VTFD for mcast vlan
2978
2979 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2980 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002981 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002982
dbainbri4d3a0dc2020-12-02 00:33:42 +00002983 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002984 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002985 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002986 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2987
2988 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2989 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2990 // new vlan associated with a different TP.
2991 vtfdFilterList[0] = uint16(vlanID)
2992
2993 meParams = me.ParamData{
2994 EntityID: mcastVtfdID,
2995 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00002996 me.VlanTaggingFilterData_VlanFilterList: vtfdFilterList,
2997 me.VlanTaggingFilterData_ForwardOperation: uint8(0x10), //VID investigation
2998 me.VlanTaggingFilterData_NumberOfEntries: oFsm.numVlanFilterEntries,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002999 },
3000 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003001 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003002 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
3003 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003004 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003005 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003006 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
3007 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003008 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003009 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
3010 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003011 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003012 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00003013 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003014 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003015 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003016 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003017 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003018 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
3019 }
3020
3021 return nil
3022}
3023
dbainbri4d3a0dc2020-12-02 00:33:42 +00003024func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003025 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003026 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07003027 logger.Errorw(ctx, "error generrating me instance id",
3028 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003029 return err
3030 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003031 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
3032 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003033 meParams := me.ParamData{
3034 EntityID: instID,
3035 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003036 me.MulticastSubscriberConfigInfo_MeType: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003037 //Direct reference to the Operation profile
3038 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03003039 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003040 },
3041 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003042 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
3044 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3045 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003046 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003047 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003048 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
3049 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003050 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003051 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
3052 oFsm.deviceID, err)
3053 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003054 //accept also nil as (error) return value for writing to LastTx
3055 // - this avoids misinterpretation of new received OMCI messages
3056 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003057 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003058 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00003059 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003060 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003061 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003062 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
3063 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
3064 }
3065 return nil
3066}
3067
dbainbri4d3a0dc2020-12-02 00:33:42 +00003068func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003069 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003070 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003071 logger.Errorw(ctx, "error generating me instance id",
3072 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003073 return err
3074 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003075 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
3076 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003077 meParams := me.ParamData{
3078 EntityID: instID,
3079 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003080 me.MulticastOperationsProfile_IgmpVersion: 2,
3081 me.MulticastOperationsProfile_IgmpFunction: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003082 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003083 me.MulticastOperationsProfile_ImmediateLeave: 0,
3084 me.MulticastOperationsProfile_Robustness: 2,
3085 me.MulticastOperationsProfile_QuerierIpAddress: 0,
3086 me.MulticastOperationsProfile_QueryInterval: 125,
3087 me.MulticastOperationsProfile_QueryMaxResponseTime: 100,
3088 me.MulticastOperationsProfile_LastMemberQueryInterval: 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003089 //0 means false
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003090 me.MulticastOperationsProfile_UnauthorizedJoinRequestBehaviour: 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003091 },
3092 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003093 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003094 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3095 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3096 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003097 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003098 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003099 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3100 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003101 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003102 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3103 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003104 //accept also nil as (error) return value for writing to LastTx
3105 // - this avoids misinterpretation of new received OMCI messages
3106 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003107 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003108 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003109 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003110 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003111 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003112 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003113 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003114 }
3115 return nil
3116}
3117
dbainbri4d3a0dc2020-12-02 00:33:42 +00003118func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003119 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003120 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003121 logger.Errorw(ctx, "error generating me instance id",
3122 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003123 return err
3124 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003125 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3126 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003127 //TODO check that this is correct
3128 // Table control
3129 //setCtrl = 1
3130 //rowPartId = 0
3131 //test = 0
3132 //rowKey = 0
3133 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003134 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003135 dynamicAccessCL := make([]uint8, 24)
3136 copy(dynamicAccessCL, tableCtrl)
3137 //Multicast GemPortId
3138 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3139 // python version waits for installation of flows, see line 723 onward of
3140 // brcm_openomci_onu_handler.py
3141 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3142 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003143 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003144 //TODO start and end are hardcoded, get from TP
3145 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003146 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003147 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003148 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003149 //imputed group bandwidth
3150 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3151
3152 meParams := me.ParamData{
3153 EntityID: instID,
3154 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003155 me.MulticastOperationsProfile_DynamicAccessControlListTable: dynamicAccessCL,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003156 },
3157 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003158 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003159 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3160 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3161 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003162 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003163 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003164 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3165 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003166 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003167 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3168 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003169 //accept also nil as (error) return value for writing to LastTx
3170 // - this avoids misinterpretation of new received OMCI messages
3171 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003172 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003173 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003174 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003175 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003176 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003177 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003178 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003179 }
3180 return nil
3181}
Girish Gowdra26a40922021-01-29 17:14:34 -08003182
khenaidoo42dcdfd2021-10-19 17:34:12 -04003183func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *of.OfpMeterConfig,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003184 tpID uint8, uniID uint8, gemPortID uint16) error {
3185 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3186 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3187 // I created unique TD ID by flow direction.
3188 // TODO! Traffic descriptor ME ID will check
3189 trafficDescriptorID := gemPortID
3190 if aMeter == nil {
3191 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3192 }
3193 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3194 if err != nil {
3195 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3196 return err
3197 }
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003198 cir := (trafficShapingInfo.Cir + trafficShapingInfo.Gir) * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003199 cbs := trafficShapingInfo.Cbs
ozgecanetsiaf5c76842021-11-18 10:43:47 +03003200 pir := trafficShapingInfo.Pir * 125 // kbps --> bps --> Bps
ozgecanetsia82b91a62021-05-21 18:54:49 +03003201 pbs := trafficShapingInfo.Pbs
3202
3203 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3204 meParams := me.ParamData{
3205 EntityID: trafficDescriptorID,
3206 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003207 me.TrafficDescriptor_Cir: cir,
3208 me.TrafficDescriptor_Pir: pir,
3209 me.TrafficDescriptor_Cbs: cbs,
3210 me.TrafficDescriptor_Pbs: pbs,
3211 me.TrafficDescriptor_ColourMode: 1,
3212 me.TrafficDescriptor_IngressColourMarking: 3,
3213 me.TrafficDescriptor_EgressColourMarking: 3,
3214 me.TrafficDescriptor_MeterType: 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003215 },
3216 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003217 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003218 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3219 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003220 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003221 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003222 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3223 return err
3224 }
3225 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003226 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003227 err = oFsm.waitforOmciResponse(ctx)
3228 if err != nil {
3229 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3230 return err
3231 }
3232
Girish Gowdra09e5f212021-09-30 16:28:36 -07003233 // 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
3234 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003235 if err != nil {
3236 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3237 return err
3238 }
3239 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3240
3241 return nil
3242}
3243
Girish Gowdra09e5f212021-09-30 16:28:36 -07003244func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3245 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3246 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003247 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003248 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003249 Attributes: me.AttributeValueMap{
Holger Hildebrandt3ac49bd2022-02-07 17:46:43 +00003250 me.GemPortNetworkCtp_TrafficDescriptorProfilePointerForUpstream: trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003251 },
3252 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003253 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003254 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3255 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003256 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003257 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003258 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3259 return err
3260 }
3261 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003262 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003263 err = oFsm.waitforOmciResponse(ctx)
3264 if err != nil {
3265 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3266 return err
3267 }
3268 return nil
3269}
3270
Girish Gowdra26a40922021-01-29 17:14:34 -08003271// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003272func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3273 if oFsm == nil {
3274 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3275 return false
3276 }
mpagenkobb47bc22021-04-20 13:29:09 +00003277 oFsm.mutexFlowParams.Lock()
3278 defer oFsm.mutexFlowParams.Unlock()
3279 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3280 //flow removal is still ongoing/pending
3281 oFsm.signalOnFlowDelete = true
3282 oFsm.flowDeleteChannel = aFlowDeleteChannel
3283 return true
3284 }
3285 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003286}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003287
3288func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3289 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3290 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3291 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3292 log.Fields{"device-id": oFsm.deviceID})
3293 } else {
3294 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3295 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3296 "index": oFsm.numVlanFilterEntries,
3297 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3298 "device-id": oFsm.deviceID})
3299 oFsm.numVlanFilterEntries++
3300 }
3301}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003302
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003303// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3304func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003305 if respChan != nil {
3306 // 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
3307 select {
3308 case *respChan <- err:
3309 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3310 default:
3311 }
3312 }
3313}
Holger Hildebrandte7cc6092022-02-01 11:37:03 +00003314
3315// PrepareForGarbageCollection - remove references to prepare for garbage collection
3316func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3317 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3318 oFsm.pDeviceHandler = nil
3319 oFsm.pOnuDeviceEntry = nil
3320 oFsm.pOmciCC = nil
3321}