blob: 5613306ec6a642d29b90c7eb6641eeb449b9d910 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000017//Package avcfg provides anig and vlan configuration functionality
18package avcfg
mpagenkodff5dda2020-08-28 11:52:01 +000019
20import (
21 "context"
22 "encoding/binary"
mpagenkof582d6a2021-06-18 15:58:10 +000023 "errors"
Andrea Campanella6515c582020-10-05 11:25:00 +020024 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030025 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028 "time"
29
khenaidoo7d3c5582021-08-11 18:09:44 -040030 meters "github.com/opencord/voltha-lib-go/v7/pkg/meters"
31 "github.com/opencord/voltha-protos/v5/go/voltha"
ozgecanetsia82b91a62021-05-21 18:54:49 +030032
mpagenko01e726e2020-10-23 09:45:29 +000033 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000034 "github.com/looplab/fsm"
mpagenko836a1fd2021-11-01 16:12:42 +000035 "github.com/opencord/omci-lib-go/v2"
36 me "github.com/opencord/omci-lib-go/v2/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040037 "github.com/opencord/voltha-lib-go/v7/pkg/log"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000038 cmn "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/common"
39 "github.com/opencord/voltha-openonu-adapter-go/internal/pkg/devdb"
khenaidoo7d3c5582021-08-11 18:09:44 -040040 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000041)
42
43const (
44 // internal predefined values
45 cDefaultDownstreamMode = 0
46 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000047 cVtfdTableSize = 12 //as per G.988
48 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000049)
50
51const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000052 // internal offsets for requestEvent according to definition in onu_device_entry::cmn.OnuDeviceEvent
mpagenkof1fc3862021-02-16 10:09:52 +000053 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000054 cDeviceEventOffsetAddNoKvStore = cmn.OmciVlanFilterAddDoneNoKvStore - cmn.OmciVlanFilterAddDone
55 cDeviceEventOffsetRemoveWithKvStore = cmn.OmciVlanFilterRemDone - cmn.OmciVlanFilterAddDone
56 cDeviceEventOffsetRemoveNoKvStore = cmn.OmciVlanFilterRemDoneNoKvStore - cmn.OmciVlanFilterAddDone
mpagenkof1fc3862021-02-16 10:09:52 +000057)
58
59const (
mpagenkodff5dda2020-08-28 11:52:01 +000060 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
61 cFilterPrioOffset = 28
62 cFilterVidOffset = 15
63 cFilterTpidOffset = 12
64 cFilterEtherTypeOffset = 0
65 cTreatTTROffset = 30
66 cTreatPrioOffset = 16
67 cTreatVidOffset = 3
68 cTreatTpidOffset = 0
69)
70const (
71 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
72 cFilterOuterOffset = 0
73 cFilterInnerOffset = 4
74 cTreatOuterOffset = 8
75 cTreatInnerOffset = 12
76)
77const (
78 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
79 cPrioIgnoreTag uint32 = 15
80 cPrioDefaultFilter uint32 = 14
81 cPrioDoNotFilter uint32 = 8
82 cDoNotFilterVid uint32 = 4096
83 cDoNotFilterTPID uint32 = 0
84 cDoNotFilterEtherType uint32 = 0
85 cDoNotAddPrio uint32 = 15
86 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053087 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000088 cDontCareVid uint32 = 0
89 cDontCareTpid uint32 = 0
90 cSetOutputTpidCopyDei uint32 = 4
91)
92
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000093// events of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +000094const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +000095 VlanEvStart = "VlanEvStart"
96 VlanEvPrepareDone = "VlanEvPrepareDone"
97 VlanEvWaitTechProf = "VlanEvWaitTechProf"
98 VlanEvCancelOutstandingConfig = "VlanEvCancelOutstandingConfig"
99 VlanEvContinueConfig = "VlanEvContinueConfig"
100 VlanEvStartConfig = "VlanEvStartConfig"
101 VlanEvRxConfigVtfd = "VlanEvRxConfigVtfd"
102 VlanEvRxConfigEvtocd = "VlanEvRxConfigEvtocd"
103 VlanEvWaitTPIncr = "VlanEvWaitTPIncr"
104 VlanEvIncrFlowConfig = "VlanEvIncrFlowConfig"
105 VlanEvRenew = "VlanEvRenew"
106 VlanEvRemFlowConfig = "VlanEvRemFlowConfig"
107 VlanEvRemFlowDone = "VlanEvRemFlowDone"
108 VlanEvFlowDataRemoved = "VlanEvFlowDataRemoved"
109 //VlanEvTimeoutSimple = "VlanEvTimeoutSimple"
110 //VlanEvTimeoutMids = "VlanEvTimeoutMids"
111 VlanEvReset = "VlanEvReset"
112 VlanEvRestart = "VlanEvRestart"
113 VlanEvSkipOmciConfig = "VlanEvSkipOmciConfig"
114 VlanEvSkipIncFlowConfig = "VlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000115)
mpagenko01e726e2020-10-23 09:45:29 +0000116
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000117// states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000118const (
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000119 VlanStDisabled = "VlanStDisabled"
120 VlanStPreparing = "VlanStPreparing"
121 VlanStStarting = "VlanStStarting"
122 VlanStWaitingTechProf = "VlanStWaitingTechProf"
123 VlanStConfigVtfd = "VlanStConfigVtfd"
124 VlanStConfigEvtocd = "VlanStConfigEvtocd"
125 VlanStConfigDone = "VlanStConfigDone"
126 VlanStIncrFlowWaitTP = "VlanStIncrFlowWaitTP"
127 VlanStConfigIncrFlow = "VlanStConfigIncrFlow"
128 VlanStRemoveFlow = "VlanStRemoveFlow"
129 VlanStCleanupDone = "VlanStCleanupDone"
130 VlanStResetting = "VlanStResetting"
mpagenkodff5dda2020-08-28 11:52:01 +0000131)
132
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000133// CVlanFsmIdleState - TODO: add comment
134const CVlanFsmIdleState = VlanStConfigDone // state where no OMCI activity is done (for a longer time)
135// CVlanFsmConfiguredState - TODO: add comment
136const CVlanFsmConfiguredState = VlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenko01e726e2020-10-23 09:45:29 +0000137
138type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000139 isSuspendedOnAdd bool
140 removeChannel chan bool
141 cookie uint64 //just the last cookie valid for removal
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000142 vlanRuleParams cmn.UniVlanRuleParams
Girish Gowdrae95687a2021-09-08 16:30:58 -0700143 respChan *chan error
mpagenko01e726e2020-10-23 09:45:29 +0000144}
145
mpagenkobb47bc22021-04-20 13:29:09 +0000146//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000148type UniVlanConfigFsm struct {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000149 pDeviceHandler cmn.IdeviceHandler
150 pOnuDeviceEntry cmn.IonuDeviceEntry
mpagenko01e726e2020-10-23 09:45:29 +0000151 deviceID string
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000152 pOmciCC *cmn.OmciCC
153 pOnuUniPort *cmn.OnuUniPort
154 pUniTechProf *OnuUniTechProf
155 pOnuDB *devdb.OnuDeviceDB
156 requestEvent cmn.OnuDeviceEvent
mpagenkodff5dda2020-08-28 11:52:01 +0000157 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000158 PAdaptFsm *cmn.AdapterFsm
mpagenkodff5dda2020-08-28 11:52:01 +0000159 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000160 clearPersistency 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
mpagenko01e726e2020-10-23 09:45:29 +0000188//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
189// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000190func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
191 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
192 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700193 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000194 instFsm := &UniVlanConfigFsm{
195 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000196 pOnuDeviceEntry: apOnuDeviceEntry,
197 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000198 pOmciCC: apDevOmciCC,
199 pOnuUniPort: apUniPort,
200 pUniTechProf: apUniTechProf,
201 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000202 requestEvent: aRequestEvent,
203 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000204 NumUniFlows: 0,
205 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000206 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000207 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200208 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000209 }
210
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000211 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
212 if instFsm.PAdaptFsm == nil {
213 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000214 "device-id": instFsm.deviceID})
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,
247 VlanStRemoveFlow, VlanStCleanupDone},
248 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
Girish Gowdrae95687a2021-09-08 16:30:58 -0700278 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter, respChan)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000279
dbainbri4d3a0dc2020-12-02 00:33:42 +0000280 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000281 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000282 return instFsm
283}
284
mpagenko01e726e2020-10-23 09:45:29 +0000285//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000286func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700287 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000288 loRuleParams := cmn.UniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000289 TpID: aTpID,
290 MatchVid: uint32(aMatchVlan),
291 SetVid: uint32(aSetVlan),
292 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000293 }
294 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000295 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
296 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
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
mpagenko7d6bb022021-03-11 15:07:55 +0000357//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 }
mpagenko7d6bb022021-03-11 15:07:55 +0000363 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000364 oFsm.mutexIsAwaitingResponse.Lock()
365 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000366 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000367 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
368 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
369 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000370 //use channel to indicate that the response waiting shall be aborted
371 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000372 } else {
373 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000374 }
mpagenkocf48e452021-04-23 09:23:00 +0000375
mpagenko7d6bb022021-03-11 15:07:55 +0000376 // 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 +0000377 PAdaptFsm := oFsm.PAdaptFsm
378 if PAdaptFsm != nil {
379 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000380 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000381 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000382 }
mpagenko7d6bb022021-03-11 15:07:55 +0000383 }
384}
385
mpagenko551a4d42020-12-08 18:09:20 +0000386//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000387func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
388 if oFsm == nil {
389 logger.Error(ctx, "no valid UniVlanConfigFsm!")
390 return 0
391 }
mpagenko551a4d42020-12-08 18:09:20 +0000392 //mutex protection is required for possible concurrent access to FSM members
393 oFsm.mutexFlowParams.RLock()
394 defer oFsm.mutexFlowParams.RUnlock()
395 return oFsm.TpIDWaitingFor
396}
397
mpagenko2418ab02020-11-12 12:58:06 +0000398//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000399func (oFsm *UniVlanConfigFsm) RequestClearPersistency(ctx context.Context, aClear bool) {
400 if oFsm == nil {
401 logger.Error(ctx, "no valid UniVlanConfigFsm!")
402 return
403 }
mpagenko2418ab02020-11-12 12:58:06 +0000404 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000405 oFsm.mutexFlowParams.Lock()
406 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000407 oFsm.clearPersistency = aClear
408}
409
mpagenko01e726e2020-10-23 09:45:29 +0000410//SetUniFlowParams verifies on existence of flow parameters to be configured,
411// optionally udates the cookie list or appends a new flow if there is space
412// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000413// ignore complexity by now
414// nolint: gocyclo
415func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700416 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000417 if oFsm == nil {
418 logger.Error(ctx, "no valid UniVlanConfigFsm!")
419 return fmt.Errorf("no-valid-UniVlanConfigFsm")
420 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000421 loRuleParams := cmn.UniVlanRuleParams{
mpagenko01e726e2020-10-23 09:45:29 +0000422 TpID: aTpID,
423 MatchVid: uint32(aMatchVlan),
424 SetVid: uint32(aSetVlan),
425 SetPcp: uint32(aSetPcp),
426 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700427 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000428 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
429 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
430 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000431 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
432 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
433 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
434 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
435 } else {
436 if !oFsm.acceptIncrementalEvtoOption {
437 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
438 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
439 }
440 }
441
442 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
443 // no prio/vid filtering requested
444 loRuleParams.TagsToRemove = 0 //no tag pop action
445 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
446 if loRuleParams.SetPcp == cCopyPrioFromInner {
447 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
448 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
449 // might collide with NoMatchVid/CopyPrio(/setVid) setting
450 // this was some precondition setting taken over from py adapter ..
451 loRuleParams.SetPcp = 0
452 }
453 }
454
mpagenkof1d21d12021-06-11 13:14:45 +0000455 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
456 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
457 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
458 oFsm.mutexFlowParams.RLock()
459 if len(oFsm.uniRemoveFlowsSlice) > 0 {
460 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
461 if removeUniFlowParams.vlanRuleParams == loRuleParams {
462 // the flow to add is the same as the one already in progress of deleting
463 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000464 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
465 if flow >= len(oFsm.uniRemoveFlowsSlice) {
466 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
467 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
468 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700469 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %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
472
mpagenkof582d6a2021-06-18 15:58:10 +0000473 }
mpagenkof1d21d12021-06-11 13:14:45 +0000474 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
475 oFsm.mutexFlowParams.RUnlock()
476 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
477 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
478 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700479 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000480 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700481 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000482 }
483 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000484 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000485 }
486 }
487 }
488 oFsm.mutexFlowParams.RUnlock()
489
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000490 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000491 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000492 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200493 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000494 //mutex protection is required for possible concurrent access to FSM members
495 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000496 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
497 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
498 // countable run time optimization (perhaps with including the hash in kvStore storage?)
499 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000500 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000501 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300502 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
503 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
504 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000505 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000506 var cookieMatch bool
507 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
508 cookieMatch = false
509 for _, cookie := range storedUniFlowParams.CookieSlice {
510 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000511 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000512 "device-id": oFsm.deviceID, "cookie": cookie})
513 cookieMatch = true
514 break //found new cookie - no further search for this requested cookie
515 }
516 }
517 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000518 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
519 if delayedCookie != 0 {
520 //a delay for adding the cookie to this rule is requested
521 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
522 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000523 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
524 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
525 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700526 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000527 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700528 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000529 }
mpagenkobc4170a2021-08-17 16:42:10 +0000530 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000531 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000532 } else {
533 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
534 "device-id": oFsm.deviceID, "cookie": newCookie})
535 //as range works with copies of the slice we have to write to the original slice!!
536 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
537 newCookie)
538 flowCookieModify = true
539 }
mpagenko01e726e2020-10-23 09:45:29 +0000540 }
541 } //for all new cookies
542 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000543 }
544 }
mpagenkof1fc3862021-02-16 10:09:52 +0000545 oFsm.mutexFlowParams.Unlock()
546
547 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000548 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
549 if !deleteSuccess {
550 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
551 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700552 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000553 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700554 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000555 }
mpagenkof1fc3862021-02-16 10:09:52 +0000556 requestAppendRule = true //default assumption here is that rule is to be appended
557 flowCookieModify = true //and that the the flow data base is to be updated
558 if delayedCookie != 0 { //it was suspended
559 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
560 }
561 }
562 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
563 if requestAppendRule {
564 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000565 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700566 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000567 loFlowParams.CookieSlice = make([]uint64, 0)
568 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300569 if aMeter != nil {
570 loFlowParams.Meter = aMeter
571 }
mpagenko01e726e2020-10-23 09:45:29 +0000572 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000573 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000575 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
576 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000577 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
578 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000579
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000580 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000581 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
582 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000583 oFsm.NumUniFlows++
584 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000585
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000586 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000587 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000588 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000589 //attention: take care to release the mutexFlowParams when calling the FSM directly -
590 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000591 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000592 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
593 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000594 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000595 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700596 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000597 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700598 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000599 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000600 }
601 return nil
602 }
mpagenko01e726e2020-10-23 09:45:29 +0000603 // note: theoretical it would be possible to clear the same rule from the remove slice
604 // (for entries that have not yet been started with removal)
605 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
606 // 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 +0000607
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000608 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000609 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000610 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000611 // this is a restart with a complete new flow, we can re-use the initial flow config control
612 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000613 //attention: take care to release the mutexFlowParams when calling the FSM directly -
614 // synchronous FSM 'event/state' functions may rely on this mutex
615 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000616 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000617 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
618 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
619 }
mpagenko551a4d42020-12-08 18:09:20 +0000620 } else {
621 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000622 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000623 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000624 //check introduced after having observed some panic here
625 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000626 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000627 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
628 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700629 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000630 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700631 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000632 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700633
634 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000635 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700636 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000637 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700638 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000639 //attention: take care to release the mutexFlowParams when calling the FSM directly -
640 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000641 // but it must be released already before calling getTechProfileDone() as it may already be locked
642 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000643 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000644 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000645 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000646 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000647 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
648
mpagenkobb47bc22021-04-20 13:29:09 +0000649 var fsmErr error
650 if loTechProfDone {
651 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000652 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000653 } else {
654 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000655 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000656 }
657 if fsmErr != nil {
658 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
659 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000660 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700661 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000662 }
mpagenko551a4d42020-12-08 18:09:20 +0000663 }
mpagenkobb47bc22021-04-20 13:29:09 +0000664 } else {
665 // if not in the appropriate state a new entry will be automatically considered later
666 // when the configDone state is reached
667 oFsm.mutexFlowParams.Unlock()
668 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000669 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000670 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000671 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000672 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700673 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000674 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700675 return err
mpagenko01e726e2020-10-23 09:45:29 +0000676 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000677 } else {
678 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000679 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700680 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000681 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700682
mpagenko15ff4a52021-03-02 10:09:20 +0000683 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000684 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000685 //all requested rules really have been configured
686 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000687 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000688 if oFsm.pDeviceHandler != nil {
689 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000690 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000691 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000692 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
693 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000694 }
695 } else {
696 // avoid device reason update as the rule config connected to this flow may still be in progress
697 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000698 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000699 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000700 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000701 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000702 }
703 }
mpagenko01e726e2020-10-23 09:45:29 +0000704
mpagenkof1fc3862021-02-16 10:09:52 +0000705 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000706 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000707 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000708 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000709 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000710 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000711 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000712 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000713 }
mpagenko15ff4a52021-03-02 10:09:20 +0000714 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000715 }
716 return nil
717}
718
mpagenkof1d21d12021-06-11 13:14:45 +0000719func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
720 oFsm.mutexFlowParams.Lock()
721 deleteChannel := apRemoveFlowParams.removeChannel
722 apRemoveFlowParams.isSuspendedOnAdd = true
723 oFsm.mutexFlowParams.Unlock()
724
725 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
726 select {
727 case success := <-deleteChannel:
728 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
729 if success {
730 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
731 "device-id": oFsm.deviceID})
732 return nil
733 }
734 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
735 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
736 oFsm.mutexFlowParams.Lock()
737 if apRemoveFlowParams != nil {
738 apRemoveFlowParams.isSuspendedOnAdd = false
739 }
740 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000741 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000742 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000743 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000744 }
mpagenkof1d21d12021-06-11 13:14:45 +0000745}
746
mpagenkof1fc3862021-02-16 10:09:52 +0000747// VOL-3828 flow config sequence workaround ########### start ##########
748func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
749 //assumes mutexFlowParams.Lock() protection from caller!
750 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
751 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000752 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000753 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
754 newCookie := aCookieSlice[0]
755 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
756 for _, cookie := range storedUniFlowParams.CookieSlice {
757 if cookie == newCookie {
758 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
759 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
760 oFsm.delayNewRuleCookie = newCookie
761 return newCookie //found new cookie in some existing rule
762 }
763 } // for all stored cookies of the actual inspected rule
764 } //for all rules
765 }
766 return 0 //no delay requested
767}
mpagenkobc4170a2021-08-17 16:42:10 +0000768func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000769 oFsm.mutexFlowParams.RLock()
770 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
771 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
772 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000773 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000774 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000775 case cookieDeleted = <-oFsm.chCookieDeleted:
776 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
777 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000778 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000779 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
780 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
781 }
782 oFsm.mutexFlowParams.Lock()
783 oFsm.delayNewRuleCookie = 0
784 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000785 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000786}
mpagenkobc4170a2021-08-17 16:42:10 +0000787func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000788 oFsm.mutexFlowParams.Lock()
789 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
790 oFsm.mutexFlowParams.Unlock()
791
mpagenkobc4170a2021-08-17 16:42:10 +0000792 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000793 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000794 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000795 }
mpagenkobc4170a2021-08-17 16:42:10 +0000796 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000797}
798
799//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000800func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000801 flowEntryMatch := false
802 oFsm.mutexFlowParams.Lock()
803 defer oFsm.mutexFlowParams.Unlock()
804 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
805 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
806 flowEntryMatch = true
807 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
808 "device-id": oFsm.deviceID})
809 cookieMatch := false
810 for _, cookie := range storedUniFlowParams.CookieSlice {
811 if cookie == aCookie {
812 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
813 "device-id": oFsm.deviceID, "cookie": cookie})
814 cookieMatch = true
815 break //found new cookie - no further search for this requested cookie
816 }
817 }
818 if !cookieMatch {
819 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
820 "device-id": oFsm.deviceID, "cookie": aCookie})
821 //as range works with copies of the slice we have to write to the original slice!!
822 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
823 aCookie)
824 return true, false //flowModified, NoRuleAppend
825 }
826 break // found rule - no further rule search
827 }
828 }
829 if !flowEntryMatch { //it is a new rule
830 return true, true //flowModified, RuleAppend
831 }
832 return false, false //flowNotModified, NoRuleAppend
833}
834
835// VOL-3828 flow config sequence workaround ########### end ##########
836
mpagenko01e726e2020-10-23 09:45:29 +0000837//RemoveUniFlowParams verifies on existence of flow cookie,
838// if found removes cookie from flow cookie list and if this is empty
839// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700840func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000841 if oFsm == nil {
842 logger.Error(ctx, "no valid UniVlanConfigFsm!")
843 return fmt.Errorf("no-valid-UniVlanConfigFsm")
844 }
mpagenkof1fc3862021-02-16 10:09:52 +0000845 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000846 flowCookieMatch := false
847 //mutex protection is required for possible concurrent access to FSM members
848 oFsm.mutexFlowParams.Lock()
849 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000850remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000851 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
852 for i, cookie := range storedUniFlowParams.CookieSlice {
853 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000854 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000855 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000856 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000857 //remove the cookie from the cookie slice and verify it is getting empty
858 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000859 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700860 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000861 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000862 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000863 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000864 //cut off the requested cookie by slicing out this element
865 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
866 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
867 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000868 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
869 // state transition notification is checked in deviceHandler
870 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000871 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
872 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000873 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000874 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000875 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000876 if deletedCookie == oFsm.delayNewRuleCookie {
877 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
878 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
879 //simply use the first one
880 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
881 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
882 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
883 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700884 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000885 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000886 //permanently store the modified flow config for reconcile case and immediately write to KvStore
887 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000888 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000889 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
890 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
891 return err
892 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000893 }
mpagenko01e726e2020-10-23 09:45:29 +0000894 }
mpagenkof1fc3862021-02-16 10:09:52 +0000895 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000896 }
897 }
mpagenko01e726e2020-10-23 09:45:29 +0000898 } //search all flows
899 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000900 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000901 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
902 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000903 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
904 // state transition notification is checked in deviceHandler
905 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000906 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000907 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000908 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700909 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000910 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000911 return nil
912 } //unknown cookie
913
914 return nil
915}
916
mpagenkof582d6a2021-06-18 15:58:10 +0000917// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000918// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000919func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700920 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000921 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000922 var cancelPendingConfig bool = false
923 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
924 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
925 "device-id": oFsm.deviceID})
926 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
927 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
928 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
929 // 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 +0000930 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000931 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
932 log.Fields{"device-id": oFsm.deviceID})
933 cancelPendingConfig = true
934 } else {
935 //create a new element for the removeVlanFlow slice
936 loRemoveParams = uniRemoveVlanFlowParams{
937 vlanRuleParams: aUniFlowParams.VlanRuleParams,
938 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700939 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000940 }
941 loRemoveParams.removeChannel = make(chan bool)
942 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
943 }
944
945 usedTpID := aUniFlowParams.VlanRuleParams.TpID
946 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
947 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
948 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
949 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000950 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
951 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000952 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
953 "device-id": oFsm.deviceID})
954 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000955 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000956 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000957 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000958 }
959 } else {
960 if !cancelPendingConfig {
961 oFsm.updateTechProfileToDelete(ctx, usedTpID)
962 }
963 }
964 //trigger the FSM to remove the relevant rule
965 if cancelPendingConfig {
966 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000967 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000968 //call from 'non-configured' state of the rules
969 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
970 //something quite inconsistent detected, perhaps just try to recover with FSM reset
971 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000972 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000973 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
974 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
975 }
976 return false //data base update could not be done, return like cookie not found
977 }
978
979 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
980 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
981 // synchronous FSM 'event/state' functions may rely on this mutex
982 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000983 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000984 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
985 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
986 }
987 oFsm.mutexFlowParams.Lock()
988 return true
989 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000990 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000991 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000992 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000993 "tp-id": loRemoveParams.vlanRuleParams.TpID,
994 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
995 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
996 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
997 // synchronous FSM 'event/state' functions may rely on this mutex
998 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000999 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +00001000 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
1001 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
1002 }
1003 oFsm.mutexFlowParams.Lock()
1004 } // if not in the appropriate state a new entry will be automatically considered later
1005 // when the configDone state is reached
1006 return true
1007}
1008
mpagenkof1d21d12021-06-11 13:14:45 +00001009//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
1010// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
1011// from the start of the deletion request to avoid to much interference
1012// so when called, there can only be one cookie active for this flow
1013// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001014func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001015 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1016 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001017 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001018removeFromSlice_loop:
1019 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001020 // if UniFlowParams exists, cookieSlice should always have at least one element
1021 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1022 if cookieSliceLen == 1 {
1023 if storedUniFlowParams.CookieSlice[0] == aCookie {
1024 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001025 }
mpagenkof582d6a2021-06-18 15:58:10 +00001026 } else if cookieSliceLen == 0 {
1027 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1028 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1029 return errors.New(errStr)
1030 } else {
1031 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1032 logger.Errorw(ctx, errStr, log.Fields{
1033 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1034 for _, cookie := range storedUniFlowParams.CookieSlice {
1035 if cookie == aCookie {
1036 cookieFound = true
1037 break
1038 }
1039 }
1040 }
1041 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001042 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1043 "device-id": oFsm.deviceID, "cookie": aCookie})
1044 //remove the actual element from the addVlanFlow slice
1045 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1046 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001047 oFsm.NumUniFlows = 0 //no more flows
1048 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001049 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1050 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1051 //request that this profile gets deleted before a new flow add is allowed
1052 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1053 "device-id": oFsm.deviceID})
1054 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001055 oFsm.NumUniFlows--
1056 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1057 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001058 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001059 if !aWasConfigured {
1060 // We did not actually process this flow but was removed before that.
1061 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001062 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001063 }
1064
mpagenkof1d21d12021-06-11 13:14:45 +00001065 //cut off the requested flow by slicing out this element
1066 oFsm.uniVlanFlowParamsSlice = append(
1067 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1068 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1069 "device-id": oFsm.deviceID})
1070 }
1071 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1072 }
1073 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001074 if !cookieFound {
1075 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1076 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1077 return errors.New(errStr)
1078 }
mpagenkodee02a62021-07-21 10:56:10 +00001079 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1080 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001081 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001082 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1083 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1084 return err
1085 }
mpagenkof582d6a2021-06-18 15:58:10 +00001086 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001087}
1088
1089// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001090func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1091 //here we have to check, if there are still other flows referencing to the actual ProfileId
1092 // before we can request that this profile gets deleted before a new flow add is allowed
1093 tpIDInOtherFlows := false
1094 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1095 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1096 tpIDInOtherFlows = true
1097 break // search loop can be left
1098 }
1099 }
1100 if tpIDInOtherFlows {
1101 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1102 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1103 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001104 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 +00001105 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001106 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1107 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001108 if oFsm.pUniTechProf != nil {
1109 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001110 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001111 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001112 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001113 }
1114}
1115
mpagenkof1d21d12021-06-11 13:14:45 +00001116func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1117 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001118
1119 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001120 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001121 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001122 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001123 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001125 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001126 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001127 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001128 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001129 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001130 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001131 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001132 go func(a_pAFsm *cmn.AdapterFsm) {
1133 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001134 }(pConfigVlanStateAFsm)
1135 return
1136 }
mpagenkof1d21d12021-06-11 13:14:45 +00001137 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001138 go func(a_pAFsm *cmn.AdapterFsm) {
1139 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001140 }(pConfigVlanStateAFsm)
1141 return
1142 }
1143 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1144 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1145 //should never happen, else: recovery would be needed from outside the FSM
1146}
1147
1148func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1149 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001150 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001151 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001152 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001153 //possibly the entry is not valid anymore based on intermediate delete requests
1154 //just a basic protection ...
1155 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1156 oFsm.mutexFlowParams.Unlock()
1157 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1158 "device-id": oFsm.deviceID})
1159 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001160 go func(a_pAFsm *cmn.AdapterFsm) {
1161 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001162 }(pConfigVlanStateAFsm)
1163 return
1164 }
mpagenko9a304ea2020-12-16 15:54:01 +00001165 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1166 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001167 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1168 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001169 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001170 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001171 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1172 // synchronous FSM 'event/state' functions may rely on this mutex
1173 // but it must be released already before calling getTechProfileDone() as it may already be locked
1174 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001175 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001176 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001177 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001178 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001179 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001180
mpagenko9a304ea2020-12-16 15:54:01 +00001181 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001182 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1183 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001184 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001185 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001186 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001187 } else {
1188 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001189 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001190 }
1191 }
mpagenko551a4d42020-12-08 18:09:20 +00001192 }(pConfigVlanStateAFsm, loTechProfDone)
1193 } else {
1194 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1195 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1196 //should never happen, else: recovery would be needed from outside the FSM
1197 return
mpagenkodff5dda2020-08-28 11:52:01 +00001198 }
1199}
1200
dbainbri4d3a0dc2020-12-02 00:33:42 +00001201func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001202 //mutex protection is required for possible concurrent access to FSM members
1203 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001204 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001205 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001206 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001207 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001209 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001210 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001211 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001212 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001213 go func(a_pAFsm *cmn.AdapterFsm) {
1214 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001215 }(pConfigVlanStateAFsm)
1216 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001217 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1218 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001219 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001220 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001221 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001222 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001223 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001224 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001225 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001226 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001227 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001228 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1229 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001230 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001231 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001232 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001233 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1234 "ForwardOperation": uint8(0x10), //VID investigation
1235 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001236 },
1237 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001239 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001240 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001241 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1242 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001243 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001244 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001245 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1246 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001247 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001248 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001249 go func(a_pAFsm *cmn.AdapterFsm) {
1250 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001251 }(pConfigVlanStateAFsm)
1252 }
1253 return
1254 }
mpagenkodff5dda2020-08-28 11:52:01 +00001255 //accept also nil as (error) return value for writing to LastTx
1256 // - this avoids misinterpretation of new received OMCI messages
1257 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1258 // send shall return (dual format) error code that can be used here for immediate error treatment
1259 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001260 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001261 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001262 }
1263}
1264
dbainbri4d3a0dc2020-12-02 00:33:42 +00001265func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1266 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001267 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001268 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001269 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001270 //using the first element in the slice because it's the first flow per definition here
1271 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001272 //This is correct passing scenario
1273 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001274 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001275 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1276 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001277 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001278 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1279 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001282 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001284 vlanID)
1285 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001286 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001287 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001288 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001289 }
1290 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001291 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001292 if oFsm.actualUniFlowParam.Meter != nil {
1293 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001294 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001295 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1296 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001297 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001298 if errCreateTrafficDescriptor != nil {
1299 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1300 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001301 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001302 }
1303 }
1304 }
1305
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001306 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001307 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001308 }
1309 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001310}
1311
dbainbri4d3a0dc2020-12-02 00:33:42 +00001312func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001313
mpagenkof1d21d12021-06-11 13:14:45 +00001314 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001315
mpagenkof1fc3862021-02-16 10:09:52 +00001316 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001317 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001318 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
Girish Gowdrae95687a2021-09-08 16:30:58 -07001319 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001320 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001321 }
1322
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001323 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001324 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001325 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001326 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1327 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1328 //should never happen, else: recovery would be needed from outside the FSM
1329 return
1330 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001331 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001332 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1333 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001334 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001336 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1337 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001338 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001339 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001340 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001341 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001342 }(pConfigVlanStateBaseFsm)
1343 return
1344 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001345 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1346 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001347 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001348 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001349 oFsm.pOnuDeviceEntry.SetReconcilingFlows(false)
1350 oFsm.pOnuDeviceEntry.SetChReconcilingFlowsFinished(true)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001351 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001352 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001353 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001354 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001355 return
1356 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1358 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001359 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001360 // this is a restart with a complete new flow, we can re-use the initial flow config control
1361 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001362 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001363 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001364 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001365 }(pConfigVlanStateBaseFsm)
1366 return
1367 }
1368
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001369 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001370 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001371 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001372 //check introduced after having observed some panic in this processing
1373 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001374 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001375 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1376 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001377 go func(a_pAFsm *cmn.AdapterFsm) {
1378 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001379 }(pConfigVlanStateAFsm)
1380 return
1381 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001382 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001383 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001384 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001385 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001386 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001387 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1388 // synchronous FSM 'event/state' functions may rely on this mutex
1389 // but it must be released already before calling getTechProfileDone() as it may already be locked
1390 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1391 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001392 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001393 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001394 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001395 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1396
mpagenko9a304ea2020-12-16 15:54:01 +00001397 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001398 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1399 if aTechProfDone {
1400 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001401 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001402 } else {
1403 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001404 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001405 }
1406 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001407 return
1408 }
mpagenkof1d21d12021-06-11 13:14:45 +00001409 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001411 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001412 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1413 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001414 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001415 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001416 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001417 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001418 }
1419}
1420
dbainbri4d3a0dc2020-12-02 00:33:42 +00001421func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001422
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001423 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001424 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001425 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001426 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001427 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1428 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001429 return
1430 }
mpagenko15ff4a52021-03-02 10:09:20 +00001431 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001432 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001433 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001434 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001435 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001436
Girish Gowdrae95687a2021-09-08 16:30:58 -07001437 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001438 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001440 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001441 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001442 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1443 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1444 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1445 // 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 +00001446 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001447 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1448 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001449 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001450 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001451 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001452 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001453 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001454 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001455 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001456 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001457
mpagenko01e726e2020-10-23 09:45:29 +00001458 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001459 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1460 oFsm.numVlanFilterEntries = 1
1461 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001462 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001463 Attributes: me.AttributeValueMap{
1464 "VlanFilterList": vtfdFilterList,
1465 "ForwardOperation": uint8(0x10), //VID investigation
1466 "NumberOfEntries": oFsm.numVlanFilterEntries,
1467 },
1468 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001469 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001470 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1471 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001472 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001473 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001474 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001475 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1476 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001477 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001478 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001479 go func(a_pAFsm *cmn.AdapterFsm) {
1480 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001481 }(pConfigVlanStateAFsm)
1482 }
1483 return
1484 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001485 //accept also nil as (error) return value for writing to LastTx
1486 // - this avoids misinterpretation of new received OMCI messages
1487 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1488 // send shall return (dual format) error code that can be used here for immediate error treatment
1489 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001490 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001491 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001492 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001493 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1494 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001495 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001496
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001498 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001499 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001500 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001501 // setVid is assumed to be masked already by the caller to 12 bit
1502 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001503 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001504 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001505
1506 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1507 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1508 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001509 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001510
1511 oFsm.numVlanFilterEntries++
1512 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001513 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001514 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001515 "VlanFilterList": vtfdFilterList,
1516 "ForwardOperation": uint8(0x10), //VID investigation
1517 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001518 },
1519 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001520 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001521 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1522 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001523 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001524 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001525 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001526 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1527 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001528 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001529 return
1530 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001531 //accept also nil as (error) return value for writing to LastTx
1532 // - this avoids misinterpretation of new received OMCI messages
1533 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1534 // send shall return (dual format) error code that can be used here for immediate error treatment
1535 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001536 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001537 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001538 }
1539 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001541 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001542 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001543 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001544 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001545 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001546 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001547 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001548 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001549 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001550 return
1551 }
1552 }
mpagenkof1d21d12021-06-11 13:14:45 +00001553
mpagenkof1fc3862021-02-16 10:09:52 +00001554 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001555 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001556 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001557 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001558 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1559 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001560 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001561 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001562 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001563 //This is correct passing scenario
1564 if errEvto == nil {
1565 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001566 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001567 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001568 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001569 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001570 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001571 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001572 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001573 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001574 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001576 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001577 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001578 }
1579 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001580 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001581 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001582 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001583 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1584 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001585 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001586 if errCreateTrafficDescriptor != nil {
1587 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1588 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001589 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001590 }
1591 }
1592 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001593 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001594 }
1595 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001596}
1597
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001599 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001601 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1602 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001603
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001604 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1605 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001606 loVlanEntryClear := uint8(0)
1607 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1608 //shallow copy is sufficient as no reference variables are used within struct
1609 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001610 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001611 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001612 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1613 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1614 "device-id": oFsm.deviceID})
1615
1616 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1617 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001619 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1620 } else {
1621 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1622 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001623 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001624 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1625 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001626 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001627 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001628 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001629 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001630 loVlanEntryClear = 1 //full VlanFilter clear request
1631 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001632 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001633 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1634 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001635 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001636 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001637 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1638 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001639 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001640 return
1641 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001642 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001643 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001644 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001646 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001647 }
mpagenko01e726e2020-10-23 09:45:29 +00001648 } else {
1649 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1650 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001651 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001652 log.Fields{"current vlan list": oFsm.vlanFilterList,
1653 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1654 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1655 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1656 loVlanEntryRmPos = i
1657 break //abort search
1658 }
1659 }
1660 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001661 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001662 //valid entry was found - to be eclipsed
1663 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1664 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1665 if i < loVlanEntryRmPos {
1666 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1667 } else if i < (cVtfdTableSize - 1) {
1668 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1669 } else {
1670 vtfdFilterList[i] = 0 //set last byte if needed
1671 }
1672 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001673 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001674 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001675 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001676 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001677
mpagenkofc4f56e2020-11-04 17:17:49 +00001678 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001679 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001680 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001681 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1682 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001683 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001684 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001685 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1686 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001687 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001688 return
1689 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001690 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001691 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001694 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001695 }
mpagenko01e726e2020-10-23 09:45:29 +00001696 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001698 log.Fields{"device-id": oFsm.deviceID})
1699 }
1700 }
1701 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001702 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1703 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001704 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001705 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001706 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001707 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001708 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001709 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001710 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001711 }(pConfigVlanStateBaseFsm)
1712 return
1713 }
mpagenko01e726e2020-10-23 09:45:29 +00001714 }
1715
mpagenko15ff4a52021-03-02 10:09:20 +00001716 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001717 if loVlanEntryClear == 1 {
1718 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1719 oFsm.numVlanFilterEntries = 0
1720 } else if loVlanEntryClear == 2 {
1721 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1722 // this loop now includes the 0 element on previous last valid entry
1723 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1724 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1725 }
1726 oFsm.numVlanFilterEntries--
1727 }
mpagenko15ff4a52021-03-02 10:09:20 +00001728 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001729 }
1730 }
1731
mpagenkofc4f56e2020-11-04 17:17:49 +00001732 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001733 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001734 } else {
1735 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001736 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001737 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001738 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001739 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001740 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001741 }(pConfigVlanStateBaseFsm)
1742 }
mpagenkodff5dda2020-08-28 11:52:01 +00001743}
1744
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001746 var tpID uint8
1747 // Extract the tpID
1748 if len(e.Args) > 0 {
1749 tpID = e.Args[0].(uint8)
1750 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1751 } else {
1752 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1753 }
mpagenko01e726e2020-10-23 09:45:29 +00001754 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001755 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001756
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001757 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001758 if pConfigVlanStateAFsm == nil {
1759 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1760 log.Fields{"device-id": oFsm.deviceID})
1761 //would have to be fixed from outside somehow
1762 return
1763 }
1764
mpagenkof1d21d12021-06-11 13:14:45 +00001765 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1766 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001767 //call from 'configured' state of the rule
1768 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1769 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1770 oFsm.mutexFlowParams.Unlock()
1771 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001772 go func(a_pAFsm *cmn.AdapterFsm) {
1773 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001774 }(pConfigVlanStateAFsm)
1775 return
1776 }
mpagenkof1d21d12021-06-11 13:14:45 +00001777 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1778 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1779 oFsm.mutexFlowParams.Unlock()
1780 removeChannel <- true
1781 oFsm.mutexFlowParams.Lock()
1782 }
1783
mpagenkof1fc3862021-02-16 10:09:52 +00001784 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1785 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1786 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1787
Girish Gowdrae95687a2021-09-08 16:30:58 -07001788 // Store the reference to the flow response channel before this entry in the slice is deleted
1789 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1790
mpagenko01e726e2020-10-23 09:45:29 +00001791 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1792 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001794 "device-id": oFsm.deviceID})
1795 } else {
1796 //cut off the actual flow by slicing out the first element
1797 oFsm.uniRemoveFlowsSlice = append(
1798 oFsm.uniRemoveFlowsSlice[:0],
1799 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001801 "device-id": oFsm.deviceID})
1802 }
1803 oFsm.mutexFlowParams.Unlock()
1804
mpagenkof1fc3862021-02-16 10:09:52 +00001805 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001806 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001807 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001808 go func(a_pAFsm *cmn.AdapterFsm) {
1809 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001810 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001811
mpagenkobb47bc22021-04-20 13:29:09 +00001812 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001813 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001814 if deletedCookie == oFsm.delayNewRuleCookie {
1815 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1816 select {
1817 case <-oFsm.chCookieDeleted:
1818 logger.Debug(ctx, "flushed CookieDeleted")
1819 default:
1820 }
1821 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1822 }
mpagenkobb47bc22021-04-20 13:29:09 +00001823 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1824 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1825 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 -08001826 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001827 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1828 oFsm.flowDeleteChannel <- true
1829 oFsm.signalOnFlowDelete = false
1830 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001831 }
mpagenkobb47bc22021-04-20 13:29:09 +00001832 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001833
1834 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001835 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001836}
1837
dbainbri4d3a0dc2020-12-02 00:33:42 +00001838func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1839 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001840
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001841 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001842 if pConfigVlanStateAFsm != nil {
1843 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001844 fsmAbortMsg := cmn.Message{
1845 Type: cmn.TestMsg,
1846 Data: cmn.TestMessage{
1847 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001848 },
1849 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001850 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001851
mpagenko9a304ea2020-12-16 15:54:01 +00001852 //try to restart the FSM to 'disabled'
1853 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001854 go func(a_pAFsm *cmn.AdapterFsm) {
1855 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1856 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001857 }
1858 }(pConfigVlanStateAFsm)
1859 }
1860}
1861
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1863 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001864 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001865 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001866 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001867
1868 oFsm.mutexFlowParams.RLock()
1869 if oFsm.delayNewRuleCookie != 0 {
1870 // looks like the waiting AddFlow is stuck
1871 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +00001872 oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
mpagenkof1d21d12021-06-11 13:14:45 +00001873 oFsm.mutexFlowParams.RLock()
1874 }
1875 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1876 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1877 if removeUniFlowParams.isSuspendedOnAdd {
1878 removeChannel := removeUniFlowParams.removeChannel
1879 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1880 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1881 oFsm.mutexFlowParams.RUnlock()
1882 removeChannel <- false
1883 oFsm.mutexFlowParams.RLock()
1884 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001885 // Send response on response channel if the caller is waiting on it.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001886 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, fmt.Errorf("internal-error"))
mpagenkof1d21d12021-06-11 13:14:45 +00001887 }
1888 }
1889
mpagenkodff5dda2020-08-28 11:52:01 +00001890 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001891 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1892 // current code removes the complete FSM including all flow/rule configuration done so far
1893 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1894 // maybe a more sophisticated approach is possible without clearing the data
1895 if oFsm.clearPersistency {
1896 //permanently remove possibly stored persistent data
1897 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001898 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1899 // Send response on response channel if the caller is waiting on it.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001900 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
Girish Gowdrae95687a2021-09-08 16:30:58 -07001901 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001902 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1903 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001904 }
1905 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001906 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001907 }
mpagenko9a304ea2020-12-16 15:54:01 +00001908 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001909 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001911 return
mpagenkodff5dda2020-08-28 11:52:01 +00001912 }
mpagenkof1d21d12021-06-11 13:14:45 +00001913 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001914}
1915
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1917 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001918loop:
1919 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001920 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001921 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001922 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001923 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301924 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001925 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301926 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001927 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301928 break loop
1929 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001930 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301931
1932 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001933 case cmn.TestMsg:
1934 msg, _ := message.Data.(cmn.TestMessage)
1935 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001937 break loop
1938 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001940 case cmn.OMCI:
1941 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001942 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301943 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301945 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001946 }
1947 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001949}
1950
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001951func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001952 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001953 "msgType": msg.OmciMsg.MessageType})
1954
1955 switch msg.OmciMsg.MessageType {
1956 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001957 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1959 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001960 return
1961 }
mpagenkodff5dda2020-08-28 11:52:01 +00001962 } //CreateResponseType
1963 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001964 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001965 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1966 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001968 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001969 return
1970 }
1971 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1972 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001974 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001975 return
1976 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001978 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001979 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001980 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001981 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1982 return
1983 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001984 oFsm.mutexPLastTxMeInstance.RLock()
1985 if oFsm.pLastTxMeInstance != nil {
1986 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1987 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1988 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001989 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001990 { // let the MultiEntity config proceed by stopping the wait function
1991 oFsm.mutexPLastTxMeInstance.RUnlock()
1992 oFsm.omciMIdsResponseReceived <- true
1993 return
1994 }
1995 default:
1996 {
1997 logger.Warnw(ctx, "Unsupported ME name received!",
1998 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1999 }
mpagenkodff5dda2020-08-28 11:52:01 +00002000 }
2001 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002002 } else {
2003 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002004 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002005 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002006 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002007 case omci.DeleteResponseType:
2008 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
2010 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002011 return
2012 }
2013 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002014 default:
2015 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002017 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002018 return
2019 }
2020 }
2021}
2022
dbainbri4d3a0dc2020-12-02 00:33:42 +00002023func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002024 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2025 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002027 log.Fields{"device-id": oFsm.deviceID})
2028 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2029 oFsm.deviceID)
2030 }
2031 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2032 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002034 log.Fields{"device-id": oFsm.deviceID})
2035 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2036 oFsm.deviceID)
2037 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002039 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002041 "Error": msgObj.Result})
2042 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2043 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2044 oFsm.deviceID)
2045 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002046 oFsm.mutexPLastTxMeInstance.RLock()
2047 if oFsm.pLastTxMeInstance != nil {
2048 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2049 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2050 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2051 switch oFsm.pLastTxMeInstance.GetName() {
2052 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2053 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002054 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002055 {
2056 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002057 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002058 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002059 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002060 } else { // let the MultiEntity config proceed by stopping the wait function
2061 oFsm.omciMIdsResponseReceived <- true
2062 }
2063 return nil
2064 }
2065 default:
2066 {
2067 logger.Warnw(ctx, "Unsupported ME name received!",
2068 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002069 }
2070 }
2071 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002072 } else {
2073 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002074 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002075 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002076 return nil
2077}
2078
dbainbri4d3a0dc2020-12-02 00:33:42 +00002079func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002080 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2081 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002083 log.Fields{"device-id": oFsm.deviceID})
2084 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2085 oFsm.deviceID)
2086 }
2087 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2088 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002089 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002090 log.Fields{"device-id": oFsm.deviceID})
2091 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2092 oFsm.deviceID)
2093 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002094 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002095 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002097 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2098 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2099 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2100 oFsm.deviceID)
2101 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002102 oFsm.mutexPLastTxMeInstance.RLock()
2103 if oFsm.pLastTxMeInstance != nil {
2104 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2105 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2106 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002107 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002108 { // let the MultiEntity config proceed by stopping the wait function
2109 oFsm.mutexPLastTxMeInstance.RUnlock()
2110 oFsm.omciMIdsResponseReceived <- true
2111 return nil
2112 }
2113 default:
2114 {
2115 logger.Warnw(ctx, "Unsupported ME name received!",
2116 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2117 }
mpagenko01e726e2020-10-23 09:45:29 +00002118 }
2119 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002120 } else {
2121 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002122 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002123 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002124 return nil
2125}
2126
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002128 oFsm.mutexFlowParams.RLock()
2129 evtocdID := oFsm.evtocdID
2130 oFsm.mutexFlowParams.RUnlock()
2131
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002132 if aFlowEntryNo == 0 {
2133 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002134 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2135 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002136 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002137 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002138 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002139 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002140 associationType := 2 // default to UniPPTP
2141 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002142 associationType = 10
2143 }
2144 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002145 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002146 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002147 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002148 "AssociationType": uint8(associationType),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002149 "AssociatedMePointer": oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002150 },
2151 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002152 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002153 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2154 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002155 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002156 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002157 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2158 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002159 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002160 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2161 }
mpagenkodff5dda2020-08-28 11:52:01 +00002162 //accept also nil as (error) return value for writing to LastTx
2163 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002164 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002165 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002166
2167 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002168 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002169 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002170 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002171 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002172 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002173 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2174 }
2175
2176 // Set the EVTOCD ME default params
2177 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002178 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002179 Attributes: me.AttributeValueMap{
2180 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2181 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2182 "DownstreamMode": uint8(cDefaultDownstreamMode),
2183 },
2184 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002185 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002186 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2187 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2188 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002189 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002190 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002191 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2192 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002193 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002194 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2195 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002196 //accept also nil as (error) return value for writing to LastTx
2197 // - this avoids misinterpretation of new received OMCI messages
2198 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002199 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002200
2201 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002202 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002203 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002204 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002205 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002207 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002208 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002209 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002210
mpagenko551a4d42020-12-08 18:09:20 +00002211 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07002212 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002213 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002214 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002215 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002216 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002217 sliceEvtocdRule := make([]uint8, 16)
2218 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2219 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2220 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2221 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2222 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2223
2224 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2225 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2226 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2227 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2228 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2229
2230 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2231 0<<cTreatTTROffset| // Do not pop any tags
2232 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2233 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2234 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2235
2236 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2237 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2238 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2239 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2240
2241 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002242 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002243 Attributes: me.AttributeValueMap{
2244 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2245 },
2246 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002247 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002248 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2249 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2250 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002251 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002252 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002253 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2254 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002255 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002256 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2257 }
mpagenkodff5dda2020-08-28 11:52:01 +00002258 //accept also nil as (error) return value for writing to LastTx
2259 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002260 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002261 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002262
2263 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002264 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002265 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002266 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002267 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002268 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002269 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2270
mpagenkodff5dda2020-08-28 11:52:01 +00002271 }
2272 } else {
2273 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2274 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002275 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2276 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2277 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2278 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002279 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002280 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002281 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002282 sliceEvtocdRule := make([]uint8, 16)
2283 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2284 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2285 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2286 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2287 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2288
2289 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002290 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2291 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002292 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2293 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2294
2295 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002296 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002297 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2298 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2299 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2300
2301 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002302 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2303 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002304 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002305 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002306
2307 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002308 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002309 Attributes: me.AttributeValueMap{
2310 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2311 },
2312 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002313 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002314 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2315 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2316 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002317 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002318 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002319 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2320 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002321 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002322 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2323 }
mpagenkodff5dda2020-08-28 11:52:01 +00002324 //accept also nil as (error) return value for writing to LastTx
2325 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002326 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002327 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002328
2329 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002330 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002331 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002332 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002333 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002335 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002336 }
2337 } else {
2338 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2339 { // just for local var's
2340 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002341 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002342 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002343 sliceEvtocdRule := make([]uint8, 16)
2344 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2345 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2346 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2347 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2348 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2349
2350 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2351 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2352 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2353 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2354 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2355
2356 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2357 0<<cTreatTTROffset| // Do not pop any tags
2358 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2359 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2360 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2361
2362 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2363 0<<cTreatPrioOffset| // vlan prio set to 0
2364 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002365 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002366 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2367
mpagenko551a4d42020-12-08 18:09:20 +00002368 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002369 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002370 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002371 Attributes: me.AttributeValueMap{
2372 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2373 },
2374 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002375 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002376 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2377 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2378 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002379 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002380 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002381 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2382 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002383 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002384 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2385 }
mpagenkodff5dda2020-08-28 11:52:01 +00002386 //accept also nil as (error) return value for writing to LastTx
2387 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002388 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002389 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002390
2391 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002392 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002393 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002395 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002396 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002397 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2398
mpagenkodff5dda2020-08-28 11:52:01 +00002399 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002400 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002401 { // just for local var's
2402 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002404 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002405 sliceEvtocdRule := make([]uint8, 16)
2406 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2407 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2408 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2409 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2410 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2411
2412 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2413 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2414 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2415 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2416 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2417
2418 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2419 1<<cTreatTTROffset| // pop the prio-tag
2420 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2421 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2422 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2423
mpagenko551a4d42020-12-08 18:09:20 +00002424 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002425 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2426 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2427 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002428 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002429 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002430 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002431
2432 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002433 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002434 Attributes: me.AttributeValueMap{
2435 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2436 },
2437 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002438 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002439 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2440 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2441 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002442 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002443 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002444 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2445 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002446 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002447 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2448 }
mpagenkodff5dda2020-08-28 11:52:01 +00002449 //accept also nil as (error) return value for writing to LastTx
2450 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002451 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002452 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002453
2454 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002455 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002456 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002457 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002458 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002460 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2461
mpagenkodff5dda2020-08-28 11:52:01 +00002462 }
2463 } //just for local var's
2464 }
2465 }
2466
mpagenkofc4f56e2020-11-04 17:17:49 +00002467 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002468 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002469 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002470 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002471 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002472 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002473}
2474
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002475func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002476 oFsm.mutexFlowParams.RLock()
2477 evtocdID := oFsm.evtocdID
2478 oFsm.mutexFlowParams.RUnlock()
2479
mpagenko01e726e2020-10-23 09:45:29 +00002480 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2481 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2482 //transparent transmission was set
2483 //perhaps the config is not needed for removal,
2484 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002485 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002486 "device-id": oFsm.deviceID})
2487 sliceEvtocdRule := make([]uint8, 16)
2488 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2489 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2490 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2491 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2492 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2493
2494 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2495 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2496 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2497 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2498 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2499
2500 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2501 0<<cTreatTTROffset| // Do not pop any tags
2502 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2503 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2504 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2505
2506 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2507 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2508 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2509 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2510
2511 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002512 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002513 Attributes: me.AttributeValueMap{
2514 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2515 },
2516 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002517 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002518 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2519 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2520 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002521 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002522 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002523 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2524 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002525 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002526 return
2527 }
mpagenko01e726e2020-10-23 09:45:29 +00002528 //accept also nil as (error) return value for writing to LastTx
2529 // - this avoids misinterpretation of new received OMCI messages
2530 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002531 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002532
2533 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002534 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002535 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002536 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002537 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002539 return
2540 }
2541 } else {
2542 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002543 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002544 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002545 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002546 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002547 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002548 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2549 sliceEvtocdRule := make([]uint8, 16)
2550 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2551 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2552 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2553 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2554 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2555
2556 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2557 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2558 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2559 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2560 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2561
2562 // delete indication for the indicated Filter
2563 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2564 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2565
2566 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002567 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002568 Attributes: me.AttributeValueMap{
2569 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2570 },
2571 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002572 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002573 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2574 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2575 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002576 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002577 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002578 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2579 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002580 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002581 return
2582 }
mpagenko01e726e2020-10-23 09:45:29 +00002583 //accept also nil as (error) return value for writing to LastTx
2584 // - this avoids misinterpretation of new received OMCI messages
2585 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002586 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002587
2588 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002589 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002590 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002591 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002592 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002594 return
2595 }
2596 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002597 // VOL-3685
2598 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2599 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2600 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2601 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2602 // later when the flow is being re-installed.
2603 // Of course this is applicable to case only where single service (or single tcont) is in use and
2604 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2605 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2606 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002607 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002608 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002610 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2611 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002612 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002613 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002614 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002615 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002616 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2617 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2618 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002619 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002620 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002621 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2622 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002623 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002624 return
2625 }
mpagenko01e726e2020-10-23 09:45:29 +00002626 //accept also nil as (error) return value for writing to LastTx
2627 // - this avoids misinterpretation of new received OMCI messages
2628 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002629 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002630
2631 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002632 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002633 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002634 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002635 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002637 return
2638 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002639 } else {
2640 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2641 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002642 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002644 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002645 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2646 { // just for local var's
2647 // this defines stacking scenario: untagged->singletagged
2648 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2649 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2650 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2651 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002652 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002653 "device-id": oFsm.deviceID})
2654 sliceEvtocdRule := make([]uint8, 16)
2655 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2656 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2657 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2658 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2659 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002660
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002661 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2662 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2663 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2664 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2665 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002666
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002667 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2668 0<<cTreatTTROffset| // Do not pop any tags
2669 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2670 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2671 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002672
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002673 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2674 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2675 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2676 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002677
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002678 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002679 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002680 Attributes: me.AttributeValueMap{
2681 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2682 },
2683 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002684 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002685 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2686 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2687 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002688 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002689 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002690 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2691 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002692 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002693 return
2694 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002695 //accept also nil as (error) return value for writing to LastTx
2696 // - this avoids misinterpretation of new received OMCI messages
2697 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002698 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002699
2700 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002701 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002702 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002703 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002704 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002706 return
2707 }
2708 } // just for local var's
2709 { // just for local var's
2710 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002711 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002712 "device-id": oFsm.deviceID})
2713 sliceEvtocdRule := make([]uint8, 16)
2714 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2715 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2716 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2717 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2718 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2719
2720 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2721 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2722 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2723 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2724 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2725
2726 // delete indication for the indicated Filter
2727 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2728 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2729
2730 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002731 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002732 Attributes: me.AttributeValueMap{
2733 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2734 },
2735 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002736 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002737 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2738 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2739 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002740 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002741 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002742 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2743 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002744 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002745 return
2746 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002747 //accept also nil as (error) return value for writing to LastTx
2748 // - this avoids misinterpretation of new received OMCI messages
2749 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002750 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002751
2752 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002753 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002754 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002756 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002758 return
2759 }
mpagenko01e726e2020-10-23 09:45:29 +00002760 }
2761 } //just for local var's
2762 }
2763 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002764 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002765 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002766 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002767}
2768
dbainbri4d3a0dc2020-12-02 00:33:42 +00002769func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002770 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002771 if oFsm.isCanceled {
2772 // FSM already canceled before entering wait
2773 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2774 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002775 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002776 }
mpagenko7d6bb022021-03-11 15:07:55 +00002777 oFsm.isAwaitingResponse = true
2778 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002779 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302780 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002781 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002782 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002783 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002784 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002785 oFsm.mutexIsAwaitingResponse.Lock()
2786 oFsm.isAwaitingResponse = false
2787 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002788 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002789 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302790 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002791 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002792 oFsm.mutexIsAwaitingResponse.Lock()
2793 oFsm.isAwaitingResponse = false
2794 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002795 return nil
2796 }
mpagenko7d6bb022021-03-11 15:07:55 +00002797 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002798 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002799 oFsm.mutexIsAwaitingResponse.Lock()
2800 oFsm.isAwaitingResponse = false
2801 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002802 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002803 }
2804}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002805
mpagenko551a4d42020-12-08 18:09:20 +00002806func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002808 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002809 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002810 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002811 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002812 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002813 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002814 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2815 }
2816
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002818 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002819 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002820 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002821 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002822 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2823 }
2824
dbainbri4d3a0dc2020-12-02 00:33:42 +00002825 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002826 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002828 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002829 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002830 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2831 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002832 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002833 if errMacBpCdEID != nil {
2834 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2835 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002836 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002837 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002838
Mahir Gunyel6781f962021-05-16 23:30:08 -07002839 }
2840 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2842 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002844 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 Attributes: me.AttributeValueMap{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002846 "BridgeIdPointer": cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002847 "PortNum": 0xf0, //fixed unique ANI side indication
2848 "TpType": 6, //MCGemIWTP
2849 "TpPointer": multicastGemPortID,
2850 },
2851 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002852 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002853 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2854 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002855 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002856 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002857 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2858 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002859 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002860 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2861 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002862 //accept also nil as (error) return value for writing to LastTx
2863 // - this avoids misinterpretation of new received OMCI messages
2864 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002865 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002866 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002868 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002869 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2870 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002871 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2872 }
2873
2874 // ==> Start creating VTFD for mcast vlan
2875
2876 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2877 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002878 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002879
dbainbri4d3a0dc2020-12-02 00:33:42 +00002880 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002881 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002882 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002883 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2884
2885 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2886 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2887 // new vlan associated with a different TP.
2888 vtfdFilterList[0] = uint16(vlanID)
2889
2890 meParams = me.ParamData{
2891 EntityID: mcastVtfdID,
2892 Attributes: me.AttributeValueMap{
2893 "VlanFilterList": vtfdFilterList,
2894 "ForwardOperation": uint8(0x10), //VID investigation
2895 "NumberOfEntries": oFsm.numVlanFilterEntries,
2896 },
2897 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002898 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002899 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2900 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002901 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002902 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002903 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2904 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002905 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002906 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2907 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002908 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002909 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002910 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002911 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002912 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002913 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002914 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002915 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2916 }
2917
2918 return nil
2919}
2920
dbainbri4d3a0dc2020-12-02 00:33:42 +00002921func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002922 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002923 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002924 logger.Errorw(ctx, "error generrating me instance id",
2925 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002926 return err
2927 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002928 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2929 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 meParams := me.ParamData{
2931 EntityID: instID,
2932 Attributes: me.AttributeValueMap{
2933 "MeType": 0,
2934 //Direct reference to the Operation profile
2935 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002936 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002937 },
2938 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002939 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002940 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
2941 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2942 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002943 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002944 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002945 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2946 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002947 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002948 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2949 oFsm.deviceID, err)
2950 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002951 //accept also nil as (error) return value for writing to LastTx
2952 // - this avoids misinterpretation of new received OMCI messages
2953 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002954 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002955 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002956 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002957 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002958 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002959 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2960 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2961 }
2962 return nil
2963}
2964
dbainbri4d3a0dc2020-12-02 00:33:42 +00002965func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002966 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002967 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002968 logger.Errorw(ctx, "error generating me instance id",
2969 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002970 return err
2971 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002972 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2973 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002974 meParams := me.ParamData{
2975 EntityID: instID,
2976 Attributes: me.AttributeValueMap{
2977 "IgmpVersion": 2,
2978 "IgmpFunction": 0,
2979 //0 means false
2980 "ImmediateLeave": 0,
2981 "Robustness": 2,
2982 "QuerierIp": 0,
2983 "QueryInterval": 125,
2984 "QuerierMaxResponseTime": 100,
2985 "LastMemberResponseTime": 10,
2986 //0 means false
2987 "UnauthorizedJoinBehaviour": 0,
2988 },
2989 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002990 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002991 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
2992 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2993 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002994 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002995 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002996 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2997 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002998 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002999 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3000 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003001 //accept also nil as (error) return value for writing to LastTx
3002 // - this avoids misinterpretation of new received OMCI messages
3003 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003004 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003005 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003006 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003007 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003008 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003009 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003010 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003011 }
3012 return nil
3013}
3014
dbainbri4d3a0dc2020-12-02 00:33:42 +00003015func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003016 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003017 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003018 logger.Errorw(ctx, "error generating me instance id",
3019 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003020 return err
3021 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003022 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3023 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003024 //TODO check that this is correct
3025 // Table control
3026 //setCtrl = 1
3027 //rowPartId = 0
3028 //test = 0
3029 //rowKey = 0
3030 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003031 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003032 dynamicAccessCL := make([]uint8, 24)
3033 copy(dynamicAccessCL, tableCtrl)
3034 //Multicast GemPortId
3035 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3036 // python version waits for installation of flows, see line 723 onward of
3037 // brcm_openomci_onu_handler.py
3038 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3039 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003040 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003041 //TODO start and end are hardcoded, get from TP
3042 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003043 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003044 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003045 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003046 //imputed group bandwidth
3047 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3048
3049 meParams := me.ParamData{
3050 EntityID: instID,
3051 Attributes: me.AttributeValueMap{
3052 "DynamicAccessControlListTable": dynamicAccessCL,
3053 },
3054 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003055 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003056 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3057 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3058 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003059 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003060 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003061 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3062 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003063 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003064 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3065 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003066 //accept also nil as (error) return value for writing to LastTx
3067 // - this avoids misinterpretation of new received OMCI messages
3068 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003069 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003070 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003071 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003072 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003073 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003074 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003075 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003076 }
3077 return nil
3078}
Girish Gowdra26a40922021-01-29 17:14:34 -08003079
ozgecanetsia82b91a62021-05-21 18:54:49 +03003080func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3081 tpID uint8, uniID uint8, gemPortID uint16) error {
3082 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3083 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3084 // I created unique TD ID by flow direction.
3085 // TODO! Traffic descriptor ME ID will check
3086 trafficDescriptorID := gemPortID
3087 if aMeter == nil {
3088 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3089 }
3090 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3091 if err != nil {
3092 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3093 return err
3094 }
3095 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3096 cbs := trafficShapingInfo.Cbs
3097 pir := trafficShapingInfo.Pir
3098 pbs := trafficShapingInfo.Pbs
3099
3100 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3101 meParams := me.ParamData{
3102 EntityID: trafficDescriptorID,
3103 Attributes: me.AttributeValueMap{
3104 "Cir": cir,
3105 "Pir": pir,
3106 "Cbs": cbs,
3107 "Pbs": pbs,
3108 "ColourMode": 1,
3109 "IngressColourMarking": 3,
3110 "EgressColourMarking": 3,
3111 "MeterType": 1,
3112 },
3113 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003114 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003115 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3116 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003117 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003118 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003119 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3120 return err
3121 }
3122 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003123 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003124 err = oFsm.waitforOmciResponse(ctx)
3125 if err != nil {
3126 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3127 return err
3128 }
3129
Girish Gowdra09e5f212021-09-30 16:28:36 -07003130 // 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
3131 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003132 if err != nil {
3133 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3134 return err
3135 }
3136 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3137
3138 return nil
3139}
3140
Girish Gowdra09e5f212021-09-30 16:28:36 -07003141func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3142 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3143 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003144 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003145 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003146 Attributes: me.AttributeValueMap{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003147 "TrafficDescriptorProfilePointerForUpstream": trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003148 },
3149 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003150 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003151 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3152 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003153 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003154 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003155 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3156 return err
3157 }
3158 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003159 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003160 err = oFsm.waitforOmciResponse(ctx)
3161 if err != nil {
3162 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3163 return err
3164 }
3165 return nil
3166}
3167
Girish Gowdra26a40922021-01-29 17:14:34 -08003168// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003169func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3170 if oFsm == nil {
3171 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3172 return false
3173 }
mpagenkobb47bc22021-04-20 13:29:09 +00003174 oFsm.mutexFlowParams.Lock()
3175 defer oFsm.mutexFlowParams.Unlock()
3176 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3177 //flow removal is still ongoing/pending
3178 oFsm.signalOnFlowDelete = true
3179 oFsm.flowDeleteChannel = aFlowDeleteChannel
3180 return true
3181 }
3182 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003183}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003184
3185func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3186 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3187 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3188 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3189 log.Fields{"device-id": oFsm.deviceID})
3190 } else {
3191 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3192 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3193 "index": oFsm.numVlanFilterEntries,
3194 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3195 "device-id": oFsm.deviceID})
3196 oFsm.numVlanFilterEntries++
3197 }
3198}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003199
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003200// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3201func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003202 if respChan != nil {
3203 // 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
3204 select {
3205 case *respChan <- err:
3206 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3207 default:
3208 }
3209 }
3210}