blob: ce6d13a9433300c52787d77caf413832f379bc7b [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
mpagenkocf48e452021-04-23 09:23:00 +0000160 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000161 isAwaitingResponse bool
162 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000163 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000164 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
Girish Gowdrae95687a2021-09-08 16:30:58 -0700165 actualUniFlowParam cmn.UniVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000166 uniVlanFlowParamsSlice []cmn.UniVlanFlowParams
mpagenko01e726e2020-10-23 09:45:29 +0000167 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000168 NumUniFlows uint8 // expected number of flows should be less than 12
169 ConfiguredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000170 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000171 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000172 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000174 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000175 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000176 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000177 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000178 signalOnFlowDelete bool
179 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000180 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
181 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200182 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
183 // thus notification needs to be sent on chan.
184 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000185}
186
mpagenko01e726e2020-10-23 09:45:29 +0000187//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
188// of ONU UNI ports via OMCI
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000189func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler cmn.IdeviceHandler, apOnuDeviceEntry cmn.IonuDeviceEntry, apDevOmciCC *cmn.OmciCC, apUniPort *cmn.OnuUniPort,
190 apUniTechProf *OnuUniTechProf, apOnuDB *devdb.OnuDeviceDB, aTechProfileID uint8,
191 aRequestEvent cmn.OnuDeviceEvent, aName string, aCommChannel chan cmn.Message, aAcceptIncrementalEvto bool,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700192 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000193 instFsm := &UniVlanConfigFsm{
194 pDeviceHandler: apDeviceHandler,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000195 pOnuDeviceEntry: apOnuDeviceEntry,
196 deviceID: apDeviceHandler.GetDeviceID(),
mpagenkodff5dda2020-08-28 11:52:01 +0000197 pOmciCC: apDevOmciCC,
198 pOnuUniPort: apUniPort,
199 pUniTechProf: apUniTechProf,
200 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000201 requestEvent: aRequestEvent,
202 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000203 NumUniFlows: 0,
204 ConfiguredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000205 numRemoveFlows: 0,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200206 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000207 }
208
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000209 instFsm.PAdaptFsm = cmn.NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
210 if instFsm.PAdaptFsm == nil {
211 logger.Errorw(ctx, "UniVlanConfigFsm's cmn.AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000212 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700213 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000214 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000215 return nil
216 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000217 instFsm.PAdaptFsm.PFsm = fsm.NewFSM(
218 VlanStDisabled,
mpagenkodff5dda2020-08-28 11:52:01 +0000219 fsm.Events{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000220 {Name: VlanEvStart, Src: []string{VlanStDisabled}, Dst: VlanStPreparing},
221 {Name: VlanEvPrepareDone, Src: []string{VlanStPreparing}, Dst: VlanStStarting},
222 {Name: VlanEvWaitTechProf, Src: []string{VlanStStarting}, Dst: VlanStWaitingTechProf},
223 {Name: VlanEvCancelOutstandingConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigDone},
224 {Name: VlanEvContinueConfig, Src: []string{VlanStWaitingTechProf}, Dst: VlanStConfigVtfd},
225 {Name: VlanEvStartConfig, Src: []string{VlanStStarting}, Dst: VlanStConfigVtfd},
226 {Name: VlanEvRxConfigVtfd, Src: []string{VlanStConfigVtfd}, Dst: VlanStConfigEvtocd},
227 {Name: VlanEvRxConfigEvtocd, Src: []string{VlanStConfigEvtocd, VlanStConfigIncrFlow},
228 Dst: VlanStConfigDone},
229 {Name: VlanEvRenew, Src: []string{VlanStConfigDone}, Dst: VlanStStarting},
230 {Name: VlanEvWaitTPIncr, Src: []string{VlanStConfigDone}, Dst: VlanStIncrFlowWaitTP},
231 {Name: VlanEvIncrFlowConfig, Src: []string{VlanStConfigDone, VlanStIncrFlowWaitTP},
232 Dst: VlanStConfigIncrFlow},
233 {Name: VlanEvRemFlowConfig, Src: []string{VlanStConfigDone}, Dst: VlanStRemoveFlow},
234 {Name: VlanEvRemFlowDone, Src: []string{VlanStRemoveFlow}, Dst: VlanStCleanupDone},
235 {Name: VlanEvFlowDataRemoved, Src: []string{VlanStCleanupDone}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000236 /*
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000237 {Name: VlanEvTimeoutSimple, Src: []string{
238 VlanStCreatingDot1PMapper, VlanStCreatingMBPCD, VlanStSettingTconts, VlanStSettingDot1PMapper}, Dst: VlanStStarting},
239 {Name: VlanEvTimeoutMids, Src: []string{
240 VlanStCreatingGemNCTPs, VlanStCreatingGemIWs, VlanStSettingPQs}, Dst: VlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000241 */
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000242 // exceptional treatment for all states except VlanStResetting
243 {Name: VlanEvReset, Src: []string{VlanStStarting, VlanStWaitingTechProf,
244 VlanStConfigVtfd, VlanStConfigEvtocd, VlanStConfigDone, VlanStConfigIncrFlow,
245 VlanStRemoveFlow, VlanStCleanupDone},
246 Dst: VlanStResetting},
mpagenkodff5dda2020-08-28 11:52:01 +0000247 // the only way to get to resource-cleared disabled state again is via "resseting"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000248 {Name: VlanEvRestart, Src: []string{VlanStResetting}, Dst: VlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000249 // transitions for reconcile handling according to VOL-3834
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000250 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStPreparing}, Dst: VlanStConfigDone},
251 {Name: VlanEvSkipOmciConfig, Src: []string{VlanStConfigDone}, Dst: VlanStConfigIncrFlow},
252 {Name: VlanEvSkipIncFlowConfig, Src: []string{VlanStConfigIncrFlow}, Dst: VlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000253 },
mpagenkodff5dda2020-08-28 11:52:01 +0000254 fsm.Callbacks{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000255 "enter_state": func(e *fsm.Event) { instFsm.PAdaptFsm.LogFsmStateChange(ctx, e) },
256 "enter_" + VlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
257 "enter_" + VlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
258 "enter_" + VlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
259 "enter_" + VlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
260 "enter_" + VlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
261 "enter_" + VlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
262 "enter_" + VlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
263 "enter_" + VlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
264 "enter_" + VlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
265 "enter_" + VlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000266 },
267 )
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000268 if instFsm.PAdaptFsm.PFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000269 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000270 "device-id": instFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700271 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000272 instFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fmt.Errorf("adapter-base-fsm-could-not-be-instantiated"))
mpagenkodff5dda2020-08-28 11:52:01 +0000273 return nil
274 }
275
Girish Gowdrae95687a2021-09-08 16:30:58 -0700276 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter, respChan)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000277
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000279 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000280 return instFsm
281}
282
mpagenko01e726e2020-10-23 09:45:29 +0000283//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000284func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700285 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000286 loRuleParams := cmn.UniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000287 TpID: aTpID,
288 MatchVid: uint32(aMatchVlan),
289 SetVid: uint32(aSetVlan),
290 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000291 }
292 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000293 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
294 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000298 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
300 } else {
301 if !oFsm.acceptIncrementalEvtoOption {
302 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000303 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000304 }
305 }
306
mpagenko01e726e2020-10-23 09:45:29 +0000307 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000308 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.TagsToRemove = 0 //no tag pop action
310 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
311 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000312 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
313 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
314 // might collide with NoMatchVid/CopyPrio(/setVid) setting
315 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000316 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000317 }
318 }
mpagenko01e726e2020-10-23 09:45:29 +0000319
Girish Gowdrae95687a2021-09-08 16:30:58 -0700320 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000321 loFlowParams.CookieSlice = make([]uint64, 0)
322 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300323 if aMeter != nil {
324 loFlowParams.Meter = aMeter
325 }
mpagenko01e726e2020-10-23 09:45:29 +0000326
327 //no mutex protection is required for initial access and adding the first flow is always possible
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000328 oFsm.uniVlanFlowParamsSlice = make([]cmn.UniVlanFlowParams, 0)
mpagenko01e726e2020-10-23 09:45:29 +0000329 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000330 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000331 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
332 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
333 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
334 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000335 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000336
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000337 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000338 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
339 }
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000340 //cmp also usage in EVTOCDE create in omci_cc
341 oFsm.evtocdID = cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000342 oFsm.NumUniFlows = 1
mpagenko01e726e2020-10-23 09:45:29 +0000343 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
344
345 //permanently store flow config for reconcile case
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000346 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000347 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000349 return err
350 }
351
352 return nil
353}
354
mpagenko7d6bb022021-03-11 15:07:55 +0000355//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000356func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000357 if oFsm == nil {
358 logger.Error(ctx, "no valid UniVlanConfigFsm!")
359 return
360 }
mpagenko7d6bb022021-03-11 15:07:55 +0000361 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000362 oFsm.mutexIsAwaitingResponse.Lock()
363 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000364 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000365 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
366 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
367 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000368 //use channel to indicate that the response waiting shall be aborted
369 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000370 } else {
371 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000372 }
mpagenkocf48e452021-04-23 09:23:00 +0000373
mpagenko7d6bb022021-03-11 15:07:55 +0000374 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000375 PAdaptFsm := oFsm.PAdaptFsm
376 if PAdaptFsm != nil {
377 if fsmErr := PAdaptFsm.PFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000378 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000379 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000380 }
mpagenko7d6bb022021-03-11 15:07:55 +0000381 }
382}
383
mpagenko551a4d42020-12-08 18:09:20 +0000384//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000385func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
386 if oFsm == nil {
387 logger.Error(ctx, "no valid UniVlanConfigFsm!")
388 return 0
389 }
mpagenko551a4d42020-12-08 18:09:20 +0000390 //mutex protection is required for possible concurrent access to FSM members
391 oFsm.mutexFlowParams.RLock()
392 defer oFsm.mutexFlowParams.RUnlock()
393 return oFsm.TpIDWaitingFor
394}
395
mpagenko01e726e2020-10-23 09:45:29 +0000396//SetUniFlowParams verifies on existence of flow parameters to be configured,
397// optionally udates the cookie list or appends a new flow if there is space
398// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000399// ignore complexity by now
400// nolint: gocyclo
401func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700402 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000403 if oFsm == nil {
404 logger.Error(ctx, "no valid UniVlanConfigFsm!")
405 return fmt.Errorf("no-valid-UniVlanConfigFsm")
406 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000407 loRuleParams := cmn.UniVlanRuleParams{
mpagenko01e726e2020-10-23 09:45:29 +0000408 TpID: aTpID,
409 MatchVid: uint32(aMatchVlan),
410 SetVid: uint32(aSetVlan),
411 SetPcp: uint32(aSetPcp),
412 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700413 var err error
mpagenko01e726e2020-10-23 09:45:29 +0000414 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
415 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
416 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000417 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
418 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
419 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
420 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
421 } else {
422 if !oFsm.acceptIncrementalEvtoOption {
423 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
424 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
425 }
426 }
427
428 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
429 // no prio/vid filtering requested
430 loRuleParams.TagsToRemove = 0 //no tag pop action
431 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
432 if loRuleParams.SetPcp == cCopyPrioFromInner {
433 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
434 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
435 // might collide with NoMatchVid/CopyPrio(/setVid) setting
436 // this was some precondition setting taken over from py adapter ..
437 loRuleParams.SetPcp = 0
438 }
439 }
440
mpagenkof1d21d12021-06-11 13:14:45 +0000441 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
442 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
443 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
444 oFsm.mutexFlowParams.RLock()
445 if len(oFsm.uniRemoveFlowsSlice) > 0 {
446 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
447 if removeUniFlowParams.vlanRuleParams == loRuleParams {
448 // the flow to add is the same as the one already in progress of deleting
449 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000450 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
451 if flow >= len(oFsm.uniRemoveFlowsSlice) {
452 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
453 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
454 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700455 err = fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000456 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700457 return err
458
mpagenkof582d6a2021-06-18 15:58:10 +0000459 }
mpagenkof1d21d12021-06-11 13:14:45 +0000460 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
461 oFsm.mutexFlowParams.RUnlock()
462 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
463 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
464 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700465 err = fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000466 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700467 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000468 }
469 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000470 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000471 }
472 }
473 }
474 oFsm.mutexFlowParams.RUnlock()
475
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000476 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000477 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000478 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200479 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000480 //mutex protection is required for possible concurrent access to FSM members
481 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000482 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
483 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
484 // countable run time optimization (perhaps with including the hash in kvStore storage?)
485 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000486 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300488 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
489 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
490 "SetPcp": loRuleParams.SetPcp,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000491 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000492 var cookieMatch bool
493 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
494 cookieMatch = false
495 for _, cookie := range storedUniFlowParams.CookieSlice {
496 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000497 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000498 "device-id": oFsm.deviceID, "cookie": cookie})
499 cookieMatch = true
500 break //found new cookie - no further search for this requested cookie
501 }
502 }
503 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000504 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
505 if delayedCookie != 0 {
506 //a delay for adding the cookie to this rule is requested
507 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
508 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000509 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
510 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
511 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700512 err = fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000513 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700514 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000515 }
mpagenkobc4170a2021-08-17 16:42:10 +0000516 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000517 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000518 } else {
519 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
520 "device-id": oFsm.deviceID, "cookie": newCookie})
521 //as range works with copies of the slice we have to write to the original slice!!
522 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
523 newCookie)
524 flowCookieModify = true
525 }
mpagenko01e726e2020-10-23 09:45:29 +0000526 }
527 } //for all new cookies
528 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000529 }
530 }
mpagenkof1fc3862021-02-16 10:09:52 +0000531 oFsm.mutexFlowParams.Unlock()
532
533 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000534 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
535 if !deleteSuccess {
536 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
537 "device-id": oFsm.deviceID, "cookie": delayedCookie})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700538 err = fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000539 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700540 return err
mpagenkobc4170a2021-08-17 16:42:10 +0000541 }
mpagenkof1fc3862021-02-16 10:09:52 +0000542 requestAppendRule = true //default assumption here is that rule is to be appended
543 flowCookieModify = true //and that the the flow data base is to be updated
544 if delayedCookie != 0 { //it was suspended
545 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
546 }
547 }
548 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
549 if requestAppendRule {
550 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000551 if oFsm.NumUniFlows < cMaxAllowedFlows {
Girish Gowdrae95687a2021-09-08 16:30:58 -0700552 loFlowParams := cmn.UniVlanFlowParams{VlanRuleParams: loRuleParams, RespChan: respChan}
mpagenko01e726e2020-10-23 09:45:29 +0000553 loFlowParams.CookieSlice = make([]uint64, 0)
554 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300555 if aMeter != nil {
556 loFlowParams.Meter = aMeter
557 }
mpagenko01e726e2020-10-23 09:45:29 +0000558 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000559 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000560 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.NumUniFlows].CookieSlice,
mpagenko01e726e2020-10-23 09:45:29 +0000561 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
562 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000563 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.NumUniFlows + 1,
564 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID})
mpagenko01e726e2020-10-23 09:45:29 +0000565
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000566 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000567 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
568 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000569 oFsm.NumUniFlows++
570 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000571
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000572 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000573 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000574 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000575 //attention: take care to release the mutexFlowParams when calling the FSM directly -
576 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000577 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000578 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
579 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvSkipOmciConfig); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000580 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000581 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Girish Gowdrae95687a2021-09-08 16:30:58 -0700582 err = fsmErr
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000583 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700584 return err
mpagenkobb47bc22021-04-20 13:29:09 +0000585 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000586 }
587 return nil
588 }
mpagenko01e726e2020-10-23 09:45:29 +0000589 // note: theoretical it would be possible to clear the same rule from the remove slice
590 // (for entries that have not yet been started with removal)
591 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
592 // 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 +0000593
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000594 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000595 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000596 if oFsm.ConfiguredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000597 // this is a restart with a complete new flow, we can re-use the initial flow config control
598 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000599 //attention: take care to release the mutexFlowParams when calling the FSM directly -
600 // synchronous FSM 'event/state' functions may rely on this mutex
601 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000602 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRenew); fsmErr != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000603 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
604 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
605 }
mpagenko551a4d42020-12-08 18:09:20 +0000606 } else {
607 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000608 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000609 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +0000610 //check introduced after having observed some panic here
611 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000612 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +0000613 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
614 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700615 err = fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000616 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700617 return err
mpagenkof1d21d12021-06-11 13:14:45 +0000618 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700619
620 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +0000621 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -0700622 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000623 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -0700624 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000625 //attention: take care to release the mutexFlowParams when calling the FSM directly -
626 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000627 // but it must be released already before calling getTechProfileDone() as it may already be locked
628 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000629 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000630 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko45cc6a32021-07-23 10:06:57 +0000631 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000632 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +0000633 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
634
mpagenkobb47bc22021-04-20 13:29:09 +0000635 var fsmErr error
636 if loTechProfDone {
637 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000638 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenkobb47bc22021-04-20 13:29:09 +0000639 } else {
640 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000641 fsmErr = pConfigVlanStateBaseFsm.Event(VlanEvWaitTPIncr)
mpagenkobb47bc22021-04-20 13:29:09 +0000642 }
643 if fsmErr != nil {
644 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
645 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000646 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, fsmErr)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700647 return fsmErr
mpagenkobb47bc22021-04-20 13:29:09 +0000648 }
mpagenko551a4d42020-12-08 18:09:20 +0000649 }
mpagenkobb47bc22021-04-20 13:29:09 +0000650 } else {
651 // if not in the appropriate state a new entry will be automatically considered later
652 // when the configDone state is reached
653 oFsm.mutexFlowParams.Unlock()
654 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000655 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000656 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000657 "device-id": oFsm.deviceID, "flow-number": oFsm.NumUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000658 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -0700659 err = fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000660 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, err)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700661 return err
mpagenko01e726e2020-10-23 09:45:29 +0000662 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000663 } else {
664 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000665 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700666 // push response on response channel as there is nothing to be done for this flow
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000667 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700668
mpagenko15ff4a52021-03-02 10:09:20 +0000669 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000670 if oFsm.NumUniFlows == oFsm.ConfiguredUniFlow {
mpagenkofc4f56e2020-11-04 17:17:49 +0000671 //all requested rules really have been configured
672 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000673 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000674 if oFsm.pDeviceHandler != nil {
675 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000676 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000677 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000678 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
679 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000680 }
681 } else {
682 // avoid device reason update as the rule config connected to this flow may still be in progress
683 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000684 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000685 log.Fields{"device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000686 "NumberofRules": oFsm.NumUniFlows, "Configured rules": oFsm.ConfiguredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000687 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000688 }
689 }
mpagenko01e726e2020-10-23 09:45:29 +0000690
mpagenkof1fc3862021-02-16 10:09:52 +0000691 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000692 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000693 oFsm.mutexFlowParams.RLock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000694 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000695 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000696 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000697 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000698 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000699 }
mpagenko15ff4a52021-03-02 10:09:20 +0000700 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000701 }
702 return nil
703}
704
mpagenkof1d21d12021-06-11 13:14:45 +0000705func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
706 oFsm.mutexFlowParams.Lock()
707 deleteChannel := apRemoveFlowParams.removeChannel
708 apRemoveFlowParams.isSuspendedOnAdd = true
709 oFsm.mutexFlowParams.Unlock()
710
711 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
712 select {
713 case success := <-deleteChannel:
714 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
715 if success {
716 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
717 "device-id": oFsm.deviceID})
718 return nil
719 }
720 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
721 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
722 oFsm.mutexFlowParams.Lock()
723 if apRemoveFlowParams != nil {
724 apRemoveFlowParams.isSuspendedOnAdd = false
725 }
726 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000727 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000728 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000729 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000730 }
mpagenkof1d21d12021-06-11 13:14:45 +0000731}
732
mpagenkof1fc3862021-02-16 10:09:52 +0000733// VOL-3828 flow config sequence workaround ########### start ##########
734func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
735 //assumes mutexFlowParams.Lock() protection from caller!
736 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
737 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000738 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000739 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
740 newCookie := aCookieSlice[0]
741 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
742 for _, cookie := range storedUniFlowParams.CookieSlice {
743 if cookie == newCookie {
744 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
745 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
746 oFsm.delayNewRuleCookie = newCookie
747 return newCookie //found new cookie in some existing rule
748 }
749 } // for all stored cookies of the actual inspected rule
750 } //for all rules
751 }
752 return 0 //no delay requested
753}
mpagenkobc4170a2021-08-17 16:42:10 +0000754func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000755 oFsm.mutexFlowParams.RLock()
756 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
757 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
758 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000759 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000760 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000761 case cookieDeleted = <-oFsm.chCookieDeleted:
762 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
763 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000764 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000765 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
766 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
767 }
768 oFsm.mutexFlowParams.Lock()
769 oFsm.delayNewRuleCookie = 0
770 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000771 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000772}
mpagenkobc4170a2021-08-17 16:42:10 +0000773func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000774 oFsm.mutexFlowParams.Lock()
775 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
776 oFsm.mutexFlowParams.Unlock()
777
mpagenkobc4170a2021-08-17 16:42:10 +0000778 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000779 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000780 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000781 }
mpagenkobc4170a2021-08-17 16:42:10 +0000782 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000783}
784
785//returns flowModified, RuleAppendRequest
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000786func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams cmn.UniVlanRuleParams) (bool, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000787 flowEntryMatch := false
788 oFsm.mutexFlowParams.Lock()
789 defer oFsm.mutexFlowParams.Unlock()
790 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
791 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
792 flowEntryMatch = true
793 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
794 "device-id": oFsm.deviceID})
795 cookieMatch := false
796 for _, cookie := range storedUniFlowParams.CookieSlice {
797 if cookie == aCookie {
798 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
799 "device-id": oFsm.deviceID, "cookie": cookie})
800 cookieMatch = true
801 break //found new cookie - no further search for this requested cookie
802 }
803 }
804 if !cookieMatch {
805 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
806 "device-id": oFsm.deviceID, "cookie": aCookie})
807 //as range works with copies of the slice we have to write to the original slice!!
808 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
809 aCookie)
810 return true, false //flowModified, NoRuleAppend
811 }
812 break // found rule - no further rule search
813 }
814 }
815 if !flowEntryMatch { //it is a new rule
816 return true, true //flowModified, RuleAppend
817 }
818 return false, false //flowNotModified, NoRuleAppend
819}
820
821// VOL-3828 flow config sequence workaround ########### end ##########
822
mpagenko01e726e2020-10-23 09:45:29 +0000823//RemoveUniFlowParams verifies on existence of flow cookie,
824// if found removes cookie from flow cookie list and if this is empty
825// initiates removal of the flow related configuration from the ONU (via OMCI)
Girish Gowdrae95687a2021-09-08 16:30:58 -0700826func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64, respChan *chan error) error {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000827 if oFsm == nil {
828 logger.Error(ctx, "no valid UniVlanConfigFsm!")
829 return fmt.Errorf("no-valid-UniVlanConfigFsm")
830 }
mpagenkof1fc3862021-02-16 10:09:52 +0000831 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000832 flowCookieMatch := false
833 //mutex protection is required for possible concurrent access to FSM members
834 oFsm.mutexFlowParams.Lock()
835 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000836remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000837 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
838 for i, cookie := range storedUniFlowParams.CookieSlice {
839 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000840 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000841 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000842 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000843 //remove the cookie from the cookie slice and verify it is getting empty
844 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000845 // had to shift content to function due to sca complexity
Girish Gowdrae95687a2021-09-08 16:30:58 -0700846 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie, respChan)
mpagenkodee02a62021-07-21 10:56:10 +0000847 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000848 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000849 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000850 //cut off the requested cookie by slicing out this element
851 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
852 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
853 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000854 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
855 // state transition notification is checked in deviceHandler
856 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000857 // success indication without the need to write to kvStore (done already below with updated data from StorePersUniFlowConfig())
858 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000859 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000860 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000861 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000862 if deletedCookie == oFsm.delayNewRuleCookie {
863 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
864 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
865 //simply use the first one
866 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
867 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
868 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
869 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700870 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000871 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenkodee02a62021-07-21 10:56:10 +0000872 //permanently store the modified flow config for reconcile case and immediately write to KvStore
873 if oFsm.pDeviceHandler != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000874 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +0000875 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
876 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
877 return err
878 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000879 }
mpagenko01e726e2020-10-23 09:45:29 +0000880 }
mpagenkof1fc3862021-02-16 10:09:52 +0000881 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000882 }
883 }
mpagenko01e726e2020-10-23 09:45:29 +0000884 } //search all flows
885 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000886 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000887 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
888 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000889 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
890 // state transition notification is checked in deviceHandler
891 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000892 // success indication without the need to write to kvStore (no change)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000893 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000894 }
Girish Gowdrae95687a2021-09-08 16:30:58 -0700895 // Push response on the response channel
Holger Hildebrandtc192bc42021-10-28 14:38:31 +0000896 oFsm.pushReponseOnFlowResponseChannel(ctx, respChan, nil)
mpagenko01e726e2020-10-23 09:45:29 +0000897 return nil
898 } //unknown cookie
899
900 return nil
901}
902
mpagenkof582d6a2021-06-18 15:58:10 +0000903// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000904// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000905func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700906 aUniFlowParams cmn.UniVlanFlowParams, aCookie uint64, respChan *chan error) bool {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000907 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenkof582d6a2021-06-18 15:58:10 +0000908 var cancelPendingConfig bool = false
909 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
910 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
911 "device-id": oFsm.deviceID})
912 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
913 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
914 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
915 // 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 +0000916 if pConfigVlanStateBaseFsm.Is(VlanStWaitingTechProf) {
mpagenkof582d6a2021-06-18 15:58:10 +0000917 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
918 log.Fields{"device-id": oFsm.deviceID})
919 cancelPendingConfig = true
920 } else {
921 //create a new element for the removeVlanFlow slice
922 loRemoveParams = uniRemoveVlanFlowParams{
923 vlanRuleParams: aUniFlowParams.VlanRuleParams,
924 cookie: aCookie,
Girish Gowdrae95687a2021-09-08 16:30:58 -0700925 respChan: respChan,
mpagenkof582d6a2021-06-18 15:58:10 +0000926 }
927 loRemoveParams.removeChannel = make(chan bool)
928 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
929 }
930
931 usedTpID := aUniFlowParams.VlanRuleParams.TpID
932 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
933 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
934 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
935 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000936 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
937 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000938 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
939 "device-id": oFsm.deviceID})
940 if oFsm.pUniTechProf != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000941 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof582d6a2021-06-18 15:58:10 +0000942 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000943 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000944 }
945 } else {
946 if !cancelPendingConfig {
947 oFsm.updateTechProfileToDelete(ctx, usedTpID)
948 }
949 }
950 //trigger the FSM to remove the relevant rule
951 if cancelPendingConfig {
952 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000953 // the paramSlice has to be updated with rule-removal, which also then updates NumUniFlows
mpagenkof582d6a2021-06-18 15:58:10 +0000954 //call from 'non-configured' state of the rules
955 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
956 //something quite inconsistent detected, perhaps just try to recover with FSM reset
957 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000958 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvReset); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000959 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
960 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
961 }
962 return false //data base update could not be done, return like cookie not found
963 }
964
965 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
966 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
967 // synchronous FSM 'event/state' functions may rely on this mutex
968 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000969 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvCancelOutstandingConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000970 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
971 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
972 }
973 oFsm.mutexFlowParams.Lock()
974 return true
975 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000976 if pConfigVlanStateBaseFsm.Is(VlanStConfigDone) {
mpagenkof582d6a2021-06-18 15:58:10 +0000977 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000978 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenkof582d6a2021-06-18 15:58:10 +0000979 "tp-id": loRemoveParams.vlanRuleParams.TpID,
980 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
981 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
982 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
983 // synchronous FSM 'event/state' functions may rely on this mutex
984 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +0000985 if fsmErr := pConfigVlanStateBaseFsm.Event(VlanEvRemFlowConfig); fsmErr != nil {
mpagenkof582d6a2021-06-18 15:58:10 +0000986 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
987 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
988 }
989 oFsm.mutexFlowParams.Lock()
990 } // if not in the appropriate state a new entry will be automatically considered later
991 // when the configDone state is reached
992 return true
993}
994
mpagenkof1d21d12021-06-11 13:14:45 +0000995//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
996// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
997// from the start of the deletion request to avoid to much interference
998// so when called, there can only be one cookie active for this flow
999// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +00001000func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001001 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
1002 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +00001003 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +00001004removeFromSlice_loop:
1005 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +00001006 // if UniFlowParams exists, cookieSlice should always have at least one element
1007 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
1008 if cookieSliceLen == 1 {
1009 if storedUniFlowParams.CookieSlice[0] == aCookie {
1010 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001011 }
mpagenkof582d6a2021-06-18 15:58:10 +00001012 } else if cookieSliceLen == 0 {
1013 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1014 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1015 return errors.New(errStr)
1016 } else {
1017 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1018 logger.Errorw(ctx, errStr, log.Fields{
1019 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1020 for _, cookie := range storedUniFlowParams.CookieSlice {
1021 if cookie == aCookie {
1022 cookieFound = true
1023 break
1024 }
1025 }
1026 }
1027 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001028 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1029 "device-id": oFsm.deviceID, "cookie": aCookie})
1030 //remove the actual element from the addVlanFlow slice
1031 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1032 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001033 oFsm.NumUniFlows = 0 //no more flows
1034 oFsm.ConfiguredUniFlow = 0 //no more flows configured
mpagenkof1d21d12021-06-11 13:14:45 +00001035 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1036 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1037 //request that this profile gets deleted before a new flow add is allowed
1038 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1039 "device-id": oFsm.deviceID})
1040 } else {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001041 oFsm.NumUniFlows--
1042 if aWasConfigured && oFsm.ConfiguredUniFlow > 0 {
1043 oFsm.ConfiguredUniFlow--
mpagenkof1d21d12021-06-11 13:14:45 +00001044 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001045 if !aWasConfigured {
1046 // We did not actually process this flow but was removed before that.
1047 // Indicate success response for the flow to caller who is blocking on a response
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001048 oFsm.pushReponseOnFlowResponseChannel(ctx, storedUniFlowParams.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001049 }
1050
mpagenkof1d21d12021-06-11 13:14:45 +00001051 //cut off the requested flow by slicing out this element
1052 oFsm.uniVlanFlowParamsSlice = append(
1053 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1054 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1055 "device-id": oFsm.deviceID})
1056 }
1057 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1058 }
1059 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001060 if !cookieFound {
1061 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1062 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1063 return errors.New(errStr)
1064 }
mpagenkodee02a62021-07-21 10:56:10 +00001065 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1066 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001067 if err := oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID,
mpagenkodee02a62021-07-21 10:56:10 +00001068 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1069 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1070 return err
1071 }
mpagenkof582d6a2021-06-18 15:58:10 +00001072 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001073}
1074
1075// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001076func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1077 //here we have to check, if there are still other flows referencing to the actual ProfileId
1078 // before we can request that this profile gets deleted before a new flow add is allowed
1079 tpIDInOtherFlows := false
1080 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1081 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1082 tpIDInOtherFlows = true
1083 break // search loop can be left
1084 }
1085 }
1086 if tpIDInOtherFlows {
1087 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1088 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1089 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001090 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 +00001091 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001092 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1093 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001094 if oFsm.pUniTechProf != nil {
1095 //request that this profile gets deleted before a new flow add is allowed
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001096 oFsm.pUniTechProf.SetProfileToDelete(oFsm.pOnuUniPort.UniID, usedTpID, true)
mpagenkof1d21d12021-06-11 13:14:45 +00001097 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001098 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001099 }
1100}
1101
mpagenkof1d21d12021-06-11 13:14:45 +00001102func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1103 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001104
1105 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001106 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001107 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001108 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001109 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001111 //let the state machine run forward from here directly
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001112 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001113 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001114 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001115 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001116 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001117 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001118 go func(a_pAFsm *cmn.AdapterFsm) {
1119 _ = a_pAFsm.PFsm.Event(VlanEvSkipOmciConfig)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001120 }(pConfigVlanStateAFsm)
1121 return
1122 }
mpagenkof1d21d12021-06-11 13:14:45 +00001123 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001124 go func(a_pAFsm *cmn.AdapterFsm) {
1125 _ = a_pAFsm.PFsm.Event(VlanEvPrepareDone)
mpagenkof1d21d12021-06-11 13:14:45 +00001126 }(pConfigVlanStateAFsm)
1127 return
1128 }
1129 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1130 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1131 //should never happen, else: recovery would be needed from outside the FSM
1132}
1133
1134func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1135 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001136 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof1d21d12021-06-11 13:14:45 +00001137 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001138 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001139 //possibly the entry is not valid anymore based on intermediate delete requests
1140 //just a basic protection ...
1141 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1142 oFsm.mutexFlowParams.Unlock()
1143 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1144 "device-id": oFsm.deviceID})
1145 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001146 go func(a_pAFsm *cmn.AdapterFsm) {
1147 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenko9a304ea2020-12-16 15:54:01 +00001148 }(pConfigVlanStateAFsm)
1149 return
1150 }
mpagenko9a304ea2020-12-16 15:54:01 +00001151 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1152 //store the actual rule that shall be worked upon in the following transient states
Girish Gowdrae95687a2021-09-08 16:30:58 -07001153 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[0]
1154 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko9a304ea2020-12-16 15:54:01 +00001155 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001156 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001157 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1158 // synchronous FSM 'event/state' functions may rely on this mutex
1159 // but it must be released already before calling getTechProfileDone() as it may already be locked
1160 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001161 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001162 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001163 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001164 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001165 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001166
mpagenko9a304ea2020-12-16 15:54:01 +00001167 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001168 go func(aPAFsm *cmn.AdapterFsm, aTechProfDone bool) {
1169 if aPAFsm != nil && aPAFsm.PFsm != nil {
mpagenko551a4d42020-12-08 18:09:20 +00001170 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001171 // let the vlan processing begin
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001172 _ = aPAFsm.PFsm.Event(VlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001173 } else {
1174 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001175 _ = aPAFsm.PFsm.Event(VlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001176 }
1177 }
mpagenko551a4d42020-12-08 18:09:20 +00001178 }(pConfigVlanStateAFsm, loTechProfDone)
1179 } else {
1180 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1181 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1182 //should never happen, else: recovery would be needed from outside the FSM
1183 return
mpagenkodff5dda2020-08-28 11:52:01 +00001184 }
1185}
1186
dbainbri4d3a0dc2020-12-02 00:33:42 +00001187func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001188 //mutex protection is required for possible concurrent access to FSM members
1189 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001190 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Girish Gowdrae95687a2021-09-08 16:30:58 -07001191 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001192 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001193 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001194 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001195 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001196 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001197 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001198 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001199 go func(a_pAFsm *cmn.AdapterFsm) {
1200 _ = a_pAFsm.PFsm.Event(VlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001201 }(pConfigVlanStateAFsm)
1202 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001203 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1204 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001205 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001206 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001207 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001208 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001209 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001210 // setVid is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001211 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001212 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001213 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001214 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1215 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001216 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001217 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001218 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001219 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1220 "ForwardOperation": uint8(0x10), //VID investigation
1221 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001222 },
1223 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001224 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001225 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001226 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001227 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1228 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001229 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001230 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001231 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1232 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001233 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001234 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001235 go func(a_pAFsm *cmn.AdapterFsm) {
1236 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001237 }(pConfigVlanStateAFsm)
1238 }
1239 return
1240 }
mpagenkodff5dda2020-08-28 11:52:01 +00001241 //accept also nil as (error) return value for writing to LastTx
1242 // - this avoids misinterpretation of new received OMCI messages
1243 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1244 // send shall return (dual format) error code that can be used here for immediate error treatment
1245 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001246 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001247 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001248 }
1249}
1250
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1252 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001253 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001254 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001255 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001256 //using the first element in the slice because it's the first flow per definition here
1257 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001258 //This is correct passing scenario
1259 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001260 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001261 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1262 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001263 configuredUniFlows := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001264 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1265 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001266 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001268 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001269 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001270 vlanID)
1271 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001272 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001273 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001274 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001275 }
1276 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001277 //If this first flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001278 if oFsm.actualUniFlowParam.Meter != nil {
1279 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001280 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001281 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1282 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001283 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001284 if errCreateTrafficDescriptor != nil {
1285 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1286 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001287 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001288 }
1289 }
1290 }
1291
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001292 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001293 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001294 }
1295 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001296}
1297
dbainbri4d3a0dc2020-12-02 00:33:42 +00001298func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001299
mpagenkof1d21d12021-06-11 13:14:45 +00001300 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001301
mpagenkof1fc3862021-02-16 10:09:52 +00001302 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001303 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001304 "overall-uni-rules": oFsm.NumUniFlows, "configured-uni-rules": oFsm.ConfiguredUniFlow})
Girish Gowdrae95687a2021-09-08 16:30:58 -07001305 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001306 oFsm.pushReponseOnFlowResponseChannel(ctx, oFsm.actualUniFlowParam.RespChan, nil)
Girish Gowdrae95687a2021-09-08 16:30:58 -07001307 }
1308
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001309 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenko551a4d42020-12-08 18:09:20 +00001310 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001311 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001312 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1313 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1314 //should never happen, else: recovery would be needed from outside the FSM
1315 return
1316 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001317 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.PFsm
mpagenko01e726e2020-10-23 09:45:29 +00001318 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1319 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001320 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001321 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko9a304ea2020-12-16 15:54:01 +00001322 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1323 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001324 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001325 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001326 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001327 _ = a_pBaseFsm.Event(VlanEvRemFlowConfig)
mpagenko01e726e2020-10-23 09:45:29 +00001328 }(pConfigVlanStateBaseFsm)
1329 return
1330 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001331 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
1332 oFsm.ConfiguredUniFlow = oFsm.NumUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001333 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001334 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001335 oFsm.pOnuDeviceEntry.SetReconcilingFlows(false)
1336 oFsm.pOnuDeviceEntry.SetChReconcilingFlowsFinished(true)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001337 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001338 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001339 log.Fields{"NumUniFlows": oFsm.NumUniFlows, "ConfiguredUniFlow": oFsm.ConfiguredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001340 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001341 return
1342 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001343 if oFsm.NumUniFlows > oFsm.ConfiguredUniFlow {
1344 if oFsm.ConfiguredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001345 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001346 // this is a restart with a complete new flow, we can re-use the initial flow config control
1347 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001348 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001349 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001350 _ = a_pBaseFsm.Event(VlanEvRenew)
mpagenko551a4d42020-12-08 18:09:20 +00001351 }(pConfigVlanStateBaseFsm)
1352 return
1353 }
1354
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001355 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001356 //store the actual rule that shall be worked upon in the following transient states
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001357 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.ConfiguredUniFlow) {
mpagenkof1d21d12021-06-11 13:14:45 +00001358 //check introduced after having observed some panic in this processing
1359 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001360 log.Fields{"ConfiguredUniFlow": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001361 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1362 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001363 go func(a_pAFsm *cmn.AdapterFsm) {
1364 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof1d21d12021-06-11 13:14:45 +00001365 }(pConfigVlanStateAFsm)
1366 return
1367 }
Girish Gowdrae95687a2021-09-08 16:30:58 -07001368 oFsm.actualUniFlowParam = oFsm.uniVlanFlowParamsSlice[oFsm.ConfiguredUniFlow]
mpagenko551a4d42020-12-08 18:09:20 +00001369 //tpId of the next rule to be configured
Girish Gowdrae95687a2021-09-08 16:30:58 -07001370 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001371 oFsm.TpIDWaitingFor = tpID
Girish Gowdrae95687a2021-09-08 16:30:58 -07001372 loSetVlan := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenko45cc6a32021-07-23 10:06:57 +00001373 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1374 // synchronous FSM 'event/state' functions may rely on this mutex
1375 // but it must be released already before calling getTechProfileDone() as it may already be locked
1376 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1377 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001378 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.UniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001379 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001380 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.UniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001381 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1382
mpagenko9a304ea2020-12-16 15:54:01 +00001383 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001384 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1385 if aTechProfDone {
1386 // let the vlan processing continue with next rule
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001387 _ = aPBaseFsm.Event(VlanEvIncrFlowConfig)
mpagenko551a4d42020-12-08 18:09:20 +00001388 } else {
1389 // set to waiting for Techprofile
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001390 _ = aPBaseFsm.Event(VlanEvWaitTPIncr)
mpagenko551a4d42020-12-08 18:09:20 +00001391 }
1392 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001393 return
1394 }
mpagenkof1d21d12021-06-11 13:14:45 +00001395 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001396 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001397 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001398 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1399 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001400 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001401 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001402 //making use of the add->remove successor enum assumption/definition
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001403 go oFsm.pDeviceHandler.DeviceProcStatusUpdate(ctx, cmn.OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001404 }
1405}
1406
dbainbri4d3a0dc2020-12-02 00:33:42 +00001407func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001408
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001409 if oFsm.pDeviceHandler.IsSkipOnuConfigReconciling() {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001410 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001411 log.Fields{"fsmState": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001412 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001413 _ = a_pBaseFsm.Event(VlanEvSkipIncFlowConfig)
1414 }(oFsm.PAdaptFsm.PFsm)
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001415 return
1416 }
mpagenko15ff4a52021-03-02 10:09:20 +00001417 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001418 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001419 "recent flow-number": oFsm.ConfiguredUniFlow,
mpagenkof1d21d12021-06-11 13:14:45 +00001420 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001421 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001422
Girish Gowdrae95687a2021-09-08 16:30:58 -07001423 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001424 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001426 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001427 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001428 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1429 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1430 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1431 // 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 +00001432 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001433 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1434 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001435 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001436 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001438 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001439 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001440 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001441 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
Girish Gowdrae95687a2021-09-08 16:30:58 -07001442 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001443
mpagenko01e726e2020-10-23 09:45:29 +00001444 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001445 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1446 oFsm.numVlanFilterEntries = 1
1447 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001448 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001449 Attributes: me.AttributeValueMap{
1450 "VlanFilterList": vtfdFilterList,
1451 "ForwardOperation": uint8(0x10), //VID investigation
1452 "NumberOfEntries": oFsm.numVlanFilterEntries,
1453 },
1454 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001455 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001456 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1457 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001458 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001459 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001460 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001461 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1462 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001463 pConfigVlanStateAFsm := oFsm.PAdaptFsm
ozgecanetsiab36ed572021-04-01 10:38:48 +03001464 if pConfigVlanStateAFsm != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001465 go func(a_pAFsm *cmn.AdapterFsm) {
1466 _ = a_pAFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001467 }(pConfigVlanStateAFsm)
1468 }
1469 return
1470 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001471 //accept also nil as (error) return value for writing to LastTx
1472 // - this avoids misinterpretation of new received OMCI messages
1473 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1474 // send shall return (dual format) error code that can be used here for immediate error treatment
1475 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001476 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001477 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001478 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001479 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1480 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001481 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(oFsm.actualUniFlowParam.VlanRuleParams.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001482
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001484 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001485 "device-id": oFsm.deviceID,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001486 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": oFsm.actualUniFlowParam.VlanRuleParams.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001487 // setVid is assumed to be masked already by the caller to 12 bit
1488 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
Girish Gowdrae95687a2021-09-08 16:30:58 -07001489 uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001490 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001491
1492 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1493 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1494 // new vlan associated with a different TP.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001495 vtfdFilterList[0] = uint16(oFsm.actualUniFlowParam.VlanRuleParams.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001496
1497 oFsm.numVlanFilterEntries++
1498 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001499 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001500 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001501 "VlanFilterList": vtfdFilterList,
1502 "ForwardOperation": uint8(0x10), //VID investigation
1503 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001504 },
1505 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001506 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001507 meInstance, err := oFsm.pOmciCC.SendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1508 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001509 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001510 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001511 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001512 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1513 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001514 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001515 return
1516 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001517 //accept also nil as (error) return value for writing to LastTx
1518 // - this avoids misinterpretation of new received OMCI messages
1519 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1520 // send shall return (dual format) error code that can be used here for immediate error treatment
1521 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001522 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001523 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001524 }
1525 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001526 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001527 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001528 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001530 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001531 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001532 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001533 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001534 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001535 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001536 return
1537 }
1538 }
mpagenkof1d21d12021-06-11 13:14:45 +00001539
mpagenkof1fc3862021-02-16 10:09:52 +00001540 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001541 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001542 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001543 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001544 tpID := oFsm.actualUniFlowParam.VlanRuleParams.TpID
1545 configuredUniFlow := oFsm.ConfiguredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001546 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001547 oFsm.mutexFlowParams.RUnlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001548 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001549 //This is correct passing scenario
1550 if errEvto == nil {
1551 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001552 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.UniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001553 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001554 vlanID := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001555 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001556 "techProfile": tpID, "gemPort": gemPort,
Girish Gowdrae95687a2021-09-08 16:30:58 -07001557 "vlanID": vlanID, "ConfiguredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001558 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001560 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001562 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001563 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564 }
1565 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001566 //If this incremental flow contains a meter, then create TD for related gems.
Girish Gowdrae95687a2021-09-08 16:30:58 -07001567 if oFsm.actualUniFlowParam.Meter != nil {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001568 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.UniID, tpID) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07001569 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniFlowParam.Meter, "gem": gemPort})
1570 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniFlowParam.Meter, tpID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001571 oFsm.pOnuUniPort.UniID, gemPort)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001572 if errCreateTrafficDescriptor != nil {
1573 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1574 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001575 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsia82b91a62021-05-21 18:54:49 +03001576 }
1577 }
1578 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001579 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigEvtocd)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001580 }
1581 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001582}
1583
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001585 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001586 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001587 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1588 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001589
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001590 pConfigVlanStateBaseFsm := oFsm.PAdaptFsm.PFsm
1591 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.IsReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001592 loVlanEntryClear := uint8(0)
1593 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1594 //shallow copy is sufficient as no reference variables are used within struct
1595 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001596 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001597 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001598 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1599 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1600 "device-id": oFsm.deviceID})
1601
1602 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1603 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001604 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001605 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1606 } else {
1607 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1608 if oFsm.numVlanFilterEntries == 1 {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001609 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001610 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1611 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001612 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001613 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001614 "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001615 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001616 loVlanEntryClear = 1 //full VlanFilter clear request
1617 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001618 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001619 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1620 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001621 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001622 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001623 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1624 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001625 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001626 return
1627 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001628 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001629 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001630 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001632 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001633 }
mpagenko01e726e2020-10-23 09:45:29 +00001634 } else {
1635 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1636 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001637 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001638 log.Fields{"current vlan list": oFsm.vlanFilterList,
1639 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1640 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1641 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1642 loVlanEntryRmPos = i
1643 break //abort search
1644 }
1645 }
1646 if loVlanEntryRmPos < cVtfdTableSize {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001647 vtfdID, _ := cmn.GenerateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001648 //valid entry was found - to be eclipsed
1649 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1650 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1651 if i < loVlanEntryRmPos {
1652 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1653 } else if i < (cVtfdTableSize - 1) {
1654 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1655 } else {
1656 vtfdFilterList[i] = 0 //set last byte if needed
1657 }
1658 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001659 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001660 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001661 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001662 "macBpNo": oFsm.pOnuUniPort.MacBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001663
mpagenkofc4f56e2020-11-04 17:17:49 +00001664 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001665 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001666 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001667 meInstance, err := oFsm.pOmciCC.SendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(), true,
1668 oFsm.PAdaptFsm.CommChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001669 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001670 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001671 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1672 log.Fields{"device-id": oFsm.deviceID, "Error": err})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001673 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001674 return
1675 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001676 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001677 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001678 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001679 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001680 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.GetDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001681 }
mpagenko01e726e2020-10-23 09:45:29 +00001682 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001684 log.Fields{"device-id": oFsm.deviceID})
1685 }
1686 }
1687 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001688 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1689 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001690 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001691 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001692 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001693 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001694 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001695 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001696 _ = a_pBaseFsm.Event(VlanEvReset)
mpagenkofc4f56e2020-11-04 17:17:49 +00001697 }(pConfigVlanStateBaseFsm)
1698 return
1699 }
mpagenko01e726e2020-10-23 09:45:29 +00001700 }
1701
mpagenko15ff4a52021-03-02 10:09:20 +00001702 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001703 if loVlanEntryClear == 1 {
1704 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1705 oFsm.numVlanFilterEntries = 0
1706 } else if loVlanEntryClear == 2 {
1707 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1708 // this loop now includes the 0 element on previous last valid entry
1709 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1710 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1711 }
1712 oFsm.numVlanFilterEntries--
1713 }
mpagenko15ff4a52021-03-02 10:09:20 +00001714 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001715 }
1716 }
1717
mpagenkofc4f56e2020-11-04 17:17:49 +00001718 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001719 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001720 } else {
1721 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001722 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001723 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001724 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001725 go func(a_pBaseFsm *fsm.FSM) {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001726 _ = a_pBaseFsm.Event(VlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001727 }(pConfigVlanStateBaseFsm)
1728 }
mpagenkodff5dda2020-08-28 11:52:01 +00001729}
1730
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001732 var tpID uint8
1733 // Extract the tpID
1734 if len(e.Args) > 0 {
1735 tpID = e.Args[0].(uint8)
1736 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1737 } else {
1738 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1739 }
mpagenko01e726e2020-10-23 09:45:29 +00001740 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001741 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001742
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001743 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkof582d6a2021-06-18 15:58:10 +00001744 if pConfigVlanStateAFsm == nil {
1745 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1746 log.Fields{"device-id": oFsm.deviceID})
1747 //would have to be fixed from outside somehow
1748 return
1749 }
1750
mpagenkof1d21d12021-06-11 13:14:45 +00001751 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1752 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001753 //call from 'configured' state of the rule
1754 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1755 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1756 oFsm.mutexFlowParams.Unlock()
1757 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001758 go func(a_pAFsm *cmn.AdapterFsm) {
1759 _ = a_pAFsm.PFsm.Event(VlanEvReset)
mpagenkof582d6a2021-06-18 15:58:10 +00001760 }(pConfigVlanStateAFsm)
1761 return
1762 }
mpagenkof1d21d12021-06-11 13:14:45 +00001763 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1764 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1765 oFsm.mutexFlowParams.Unlock()
1766 removeChannel <- true
1767 oFsm.mutexFlowParams.Lock()
1768 }
1769
mpagenkof1fc3862021-02-16 10:09:52 +00001770 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1771 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1772 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1773
Girish Gowdrae95687a2021-09-08 16:30:58 -07001774 // Store the reference to the flow response channel before this entry in the slice is deleted
1775 flowRespChan := oFsm.uniRemoveFlowsSlice[0].respChan
1776
mpagenko01e726e2020-10-23 09:45:29 +00001777 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1778 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001779 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001780 "device-id": oFsm.deviceID})
1781 } else {
1782 //cut off the actual flow by slicing out the first element
1783 oFsm.uniRemoveFlowsSlice = append(
1784 oFsm.uniRemoveFlowsSlice[:0],
1785 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001787 "device-id": oFsm.deviceID})
1788 }
1789 oFsm.mutexFlowParams.Unlock()
1790
mpagenkof1fc3862021-02-16 10:09:52 +00001791 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001792 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001793 // Can't call FSM Event directly, decoupling it
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001794 go func(a_pAFsm *cmn.AdapterFsm) {
1795 _ = a_pAFsm.PFsm.Event(VlanEvFlowDataRemoved)
mpagenkof582d6a2021-06-18 15:58:10 +00001796 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001797
mpagenkobb47bc22021-04-20 13:29:09 +00001798 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001799 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001800 if deletedCookie == oFsm.delayNewRuleCookie {
1801 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1802 select {
1803 case <-oFsm.chCookieDeleted:
1804 logger.Debug(ctx, "flushed CookieDeleted")
1805 default:
1806 }
1807 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1808 }
mpagenkobb47bc22021-04-20 13:29:09 +00001809 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1810 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1811 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 -08001812 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001813 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1814 oFsm.flowDeleteChannel <- true
1815 oFsm.signalOnFlowDelete = false
1816 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001817 }
mpagenkobb47bc22021-04-20 13:29:09 +00001818 oFsm.mutexFlowParams.Unlock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07001819
1820 // send response on the response channel for the removed flow.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00001821 oFsm.pushReponseOnFlowResponseChannel(ctx, flowRespChan, nil)
mpagenkodff5dda2020-08-28 11:52:01 +00001822}
1823
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1825 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001826
mpagenko0f543222021-11-03 16:24:14 +00001827 oFsm.mutexPLastTxMeInstance.Lock()
1828 oFsm.pLastTxMeInstance = nil //to avoid misinterpretation in case of some lingering frame reception processing
1829 oFsm.mutexPLastTxMeInstance.Unlock()
1830
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001831 pConfigVlanStateAFsm := oFsm.PAdaptFsm
mpagenkodff5dda2020-08-28 11:52:01 +00001832 if pConfigVlanStateAFsm != nil {
1833 // abort running message processing
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001834 fsmAbortMsg := cmn.Message{
1835 Type: cmn.TestMsg,
1836 Data: cmn.TestMessage{
1837 TestMessageVal: cmn.AbortMessageProcessing,
mpagenkodff5dda2020-08-28 11:52:01 +00001838 },
1839 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001840 pConfigVlanStateAFsm.CommChan <- fsmAbortMsg
mpagenkodff5dda2020-08-28 11:52:01 +00001841
mpagenko0f543222021-11-03 16:24:14 +00001842 //internal data is not explicitly removed, this is left to garbage collection after complete FSM removal
1843 // but some channels have to be cleared to avoid unintended waiting for events, that have no meaning anymore now
1844
1845 oFsm.mutexFlowParams.RLock()
1846 if oFsm.delayNewRuleCookie != 0 {
1847 // looks like the waiting AddFlow is stuck
1848 oFsm.mutexFlowParams.RUnlock()
1849 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1850 select {
1851 case oFsm.chCookieDeleted <- false: // let the waiting AddFlow thread terminate
1852 default:
mpagenkodff5dda2020-08-28 11:52:01 +00001853 }
mpagenko0f543222021-11-03 16:24:14 +00001854 oFsm.mutexFlowParams.RLock()
1855 }
1856 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1857 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1858 if removeUniFlowParams.isSuspendedOnAdd {
1859 removeChannel := removeUniFlowParams.removeChannel
1860 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1861 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1862 oFsm.mutexFlowParams.RUnlock()
1863 //use asynchronous channel sending to avoid stucking on non-waiting receiver
1864 select {
1865 case removeChannel <- false:
1866 default:
1867 }
1868 oFsm.mutexFlowParams.RLock()
1869 }
1870 // Send response on response channel if the caller is waiting on it.
1871 var err error = nil
1872 if !oFsm.isCanceled {
1873 //only if the FSM is not canceled on external request use some error indication for the respChan
1874 // so only at real internal FSM abortion some error code is sent back
1875 // on the deleteFlow with the hope the system may handle such error situation (possibly retrying)
1876 err = fmt.Errorf("internal-error")
1877 }
1878 //if the FSM was cancelled on external request the assumption is, that all processing has to be stopped
1879 // assumed in connection with some ONU down/removal indication in which case all flows can be considered as removed
1880 oFsm.pushReponseOnFlowResponseChannel(ctx, removeUniFlowParams.respChan, err)
1881 }
1882 }
1883
1884 if oFsm.pDeviceHandler != nil {
1885 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1886 if !oFsm.isCanceled {
1887 //if the FSM is not canceled on external request use "internal-error" for the respChan
1888 for _, vlanRule := range oFsm.uniVlanFlowParamsSlice {
1889 // Send response on response channel if the caller is waiting on it with according error indication.
1890 oFsm.pushReponseOnFlowResponseChannel(ctx, vlanRule.RespChan, fmt.Errorf("internal-error"))
1891 }
1892 //permanently remove possibly stored persistent data
1893 var emptySlice = make([]cmn.UniVlanFlowParams, 0)
1894 _ = oFsm.pDeviceHandler.StorePersUniFlowConfig(ctx, oFsm.pOnuUniPort.UniID, &emptySlice, true) //ignore errors
1895 } else {
1896 // reset (cancel) of all Fsm is always accompanied by global persistency data removal
1897 // no need to remove specific data in this case here
1898 // TODO: cancelation may also abort a running flowAdd activity in which case it would be better
1899 // to also resopnd on the respChan with some error ("config canceled"), but that is a bit hard to decide here
1900 // so just left open by now
1901 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
1902 }
1903 }
1904 oFsm.mutexFlowParams.RUnlock()
1905
1906 //try to let the FSM proceed to 'disabled'
1907 // Can't call FSM Event directly, decoupling it
1908 go func(a_pAFsm *cmn.AdapterFsm) {
1909 if a_pAFsm != nil && a_pAFsm.PFsm != nil {
1910 _ = a_pAFsm.PFsm.Event(VlanEvRestart)
1911 }
1912 }(pConfigVlanStateAFsm)
1913 return
1914 }
1915 oFsm.mutexFlowParams.RUnlock()
1916 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1917 log.Fields{"device-id": oFsm.deviceID})
1918 return
mpagenkodff5dda2020-08-28 11:52:01 +00001919 }
mpagenko0f543222021-11-03 16:24:14 +00001920 logger.Warnw(ctx, "UniVlanConfigFsm - FSM pointer already vanished",
1921 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001922}
1923
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1925 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001926
mpagenkodff5dda2020-08-28 11:52:01 +00001927 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001928 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001930 return
mpagenkodff5dda2020-08-28 11:52:01 +00001931 }
mpagenko0f543222021-11-03 16:24:14 +00001932 logger.Warnw(ctx, "UniVlanConfigFsm - device handler already vanished",
1933 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001934}
1935
dbainbri4d3a0dc2020-12-02 00:33:42 +00001936func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1937 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001938loop:
1939 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001940 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001942 // break loop
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001943 message, ok := <-oFsm.PAdaptFsm.CommChan
Himani Chawla4d908332020-08-31 12:30:20 +05301944 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001945 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301946 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001947 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Himani Chawla4d908332020-08-31 12:30:20 +05301948 break loop
1949 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301951
1952 switch message.Type {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001953 case cmn.TestMsg:
1954 msg, _ := message.Data.(cmn.TestMessage)
1955 if msg.TestMessageVal == cmn.AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001957 break loop
1958 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001959 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001960 case cmn.OMCI:
1961 msg, _ := message.Data.(cmn.OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001962 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301963 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001964 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301965 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001966 }
1967 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001969}
1970
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00001971func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg cmn.OmciMessage) {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001973 "msgType": msg.OmciMsg.MessageType})
1974
1975 switch msg.OmciMsg.MessageType {
1976 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001977 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001978 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1979 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001980 return
1981 }
mpagenkodff5dda2020-08-28 11:52:01 +00001982 } //CreateResponseType
1983 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001984 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001985 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1986 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001987 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001988 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001989 return
1990 }
1991 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1992 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001994 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001995 return
1996 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001998 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002000 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00002001 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2002 return
2003 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002004 oFsm.mutexPLastTxMeInstance.RLock()
2005 if oFsm.pLastTxMeInstance != nil {
2006 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2007 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2008 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002009 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002010 { // let the MultiEntity config proceed by stopping the wait function
2011 oFsm.mutexPLastTxMeInstance.RUnlock()
2012 oFsm.omciMIdsResponseReceived <- true
2013 return
2014 }
2015 default:
2016 {
2017 logger.Warnw(ctx, "Unsupported ME name received!",
2018 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2019 }
mpagenkodff5dda2020-08-28 11:52:01 +00002020 }
2021 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002022 } else {
2023 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002024 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002025 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002026 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00002027 case omci.DeleteResponseType:
2028 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00002029 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
2030 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00002031 return
2032 }
2033 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00002034 default:
2035 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002036 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00002037 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002038 return
2039 }
2040 }
2041}
2042
dbainbri4d3a0dc2020-12-02 00:33:42 +00002043func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002044 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
2045 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002046 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002047 log.Fields{"device-id": oFsm.deviceID})
2048 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
2049 oFsm.deviceID)
2050 }
2051 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
2052 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002054 log.Fields{"device-id": oFsm.deviceID})
2055 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
2056 oFsm.deviceID)
2057 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002058 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002059 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002061 "Error": msgObj.Result})
2062 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2063 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2064 oFsm.deviceID)
2065 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002066 oFsm.mutexPLastTxMeInstance.RLock()
2067 if oFsm.pLastTxMeInstance != nil {
2068 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2069 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2070 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2071 switch oFsm.pLastTxMeInstance.GetName() {
2072 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2073 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002074 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002075 {
2076 oFsm.mutexPLastTxMeInstance.RUnlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002077 if oFsm.PAdaptFsm.PFsm.Current() == VlanStConfigVtfd {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002078 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002079 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRxConfigVtfd)
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002080 } else { // let the MultiEntity config proceed by stopping the wait function
2081 oFsm.omciMIdsResponseReceived <- true
2082 }
2083 return nil
2084 }
2085 default:
2086 {
2087 logger.Warnw(ctx, "Unsupported ME name received!",
2088 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002089 }
2090 }
2091 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002092 } else {
2093 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002094 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002095 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002096 return nil
2097}
2098
dbainbri4d3a0dc2020-12-02 00:33:42 +00002099func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002100 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2101 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002102 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002103 log.Fields{"device-id": oFsm.deviceID})
2104 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2105 oFsm.deviceID)
2106 }
2107 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2108 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002110 log.Fields{"device-id": oFsm.deviceID})
2111 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2112 oFsm.deviceID)
2113 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002114 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002115 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002116 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002117 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2118 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2119 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2120 oFsm.deviceID)
2121 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002122 oFsm.mutexPLastTxMeInstance.RLock()
2123 if oFsm.pLastTxMeInstance != nil {
2124 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2125 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2126 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002127 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002128 { // let the MultiEntity config proceed by stopping the wait function
2129 oFsm.mutexPLastTxMeInstance.RUnlock()
2130 oFsm.omciMIdsResponseReceived <- true
2131 return nil
2132 }
2133 default:
2134 {
2135 logger.Warnw(ctx, "Unsupported ME name received!",
2136 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2137 }
mpagenko01e726e2020-10-23 09:45:29 +00002138 }
2139 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002140 } else {
2141 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002142 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002143 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002144 return nil
2145}
2146
dbainbri4d3a0dc2020-12-02 00:33:42 +00002147func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002148 oFsm.mutexFlowParams.RLock()
2149 evtocdID := oFsm.evtocdID
2150 oFsm.mutexFlowParams.RUnlock()
2151
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002152 if aFlowEntryNo == 0 {
2153 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002154 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2155 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002157 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002158 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002159 "device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002160 associationType := 2 // default to UniPPTP
2161 if oFsm.pOnuUniPort.PortType == cmn.UniVEIP {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002162 associationType = 10
2163 }
2164 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002165 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002166 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002167 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002168 "AssociationType": uint8(associationType),
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002169 "AssociatedMePointer": oFsm.pOnuUniPort.EntityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002170 },
2171 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002172 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002173 meInstance, err := oFsm.pOmciCC.SendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.GetOmciTimeout(),
2174 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002175 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002177 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2178 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002179 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002180 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2181 }
mpagenkodff5dda2020-08-28 11:52:01 +00002182 //accept also nil as (error) return value for writing to LastTx
2183 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002184 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002185 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002186
2187 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002188 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002189 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002191 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002192 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002193 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2194 }
2195
2196 // Set the EVTOCD ME default params
2197 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002198 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002199 Attributes: me.AttributeValueMap{
2200 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2201 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2202 "DownstreamMode": uint8(cDefaultDownstreamMode),
2203 },
2204 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002205 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002206 meInstance, err = oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2207 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2208 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002209 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002210 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002211 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2212 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002213 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002214 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2215 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002216 //accept also nil as (error) return value for writing to LastTx
2217 // - this avoids misinterpretation of new received OMCI messages
2218 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002219 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002220
2221 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002222 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002223 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002224 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002225 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002226 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002227 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002228 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002229 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002230
mpagenko551a4d42020-12-08 18:09:20 +00002231 oFsm.mutexFlowParams.RLock()
Girish Gowdrae95687a2021-09-08 16:30:58 -07002232 if oFsm.actualUniFlowParam.VlanRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002233 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002234 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002235 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002236 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002237 sliceEvtocdRule := make([]uint8, 16)
2238 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2239 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2240 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2241 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2242 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2243
2244 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2245 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2246 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2247 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2248 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2249
2250 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2251 0<<cTreatTTROffset| // Do not pop any tags
2252 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2253 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2254 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2255
2256 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2257 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2258 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2259 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2260
2261 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002262 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002263 Attributes: me.AttributeValueMap{
2264 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2265 },
2266 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002267 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002268 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2269 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2270 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002271 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002272 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002273 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2274 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002275 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002276 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2277 }
mpagenkodff5dda2020-08-28 11:52:01 +00002278 //accept also nil as (error) return value for writing to LastTx
2279 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002280 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002281 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002282
2283 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002284 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002285 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002286 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002287 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002288 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002289 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2290
mpagenkodff5dda2020-08-28 11:52:01 +00002291 }
2292 } else {
2293 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2294 if oFsm.acceptIncrementalEvtoOption {
Girish Gowdrae95687a2021-09-08 16:30:58 -07002295 matchPcp := oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp
2296 matchVid := oFsm.actualUniFlowParam.VlanRuleParams.MatchVid
2297 setPcp := oFsm.actualUniFlowParam.VlanRuleParams.SetPcp
2298 setVid := oFsm.actualUniFlowParam.VlanRuleParams.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002299 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002300 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002301 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002302 sliceEvtocdRule := make([]uint8, 16)
2303 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2304 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2305 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2306 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2307 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2308
2309 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002310 oFsm.actualUniFlowParam.VlanRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2311 oFsm.actualUniFlowParam.VlanRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002312 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2313 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2314
2315 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002316 oFsm.actualUniFlowParam.VlanRuleParams.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002317 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2318 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2319 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2320
2321 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
Girish Gowdrae95687a2021-09-08 16:30:58 -07002322 oFsm.actualUniFlowParam.VlanRuleParams.SetPcp<<cTreatPrioOffset| // as configured in flow
2323 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002324 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002325 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002326
2327 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002328 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002329 Attributes: me.AttributeValueMap{
2330 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2331 },
2332 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002333 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002334 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2335 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2336 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002337 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002338 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002339 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2340 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002341 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002342 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2343 }
mpagenkodff5dda2020-08-28 11:52:01 +00002344 //accept also nil as (error) return value for writing to LastTx
2345 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002346 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002347 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002348
2349 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002350 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002351 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002352 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002353 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002354 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002355 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002356 }
2357 } else {
2358 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2359 { // just for local var's
2360 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002361 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002362 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002363 sliceEvtocdRule := make([]uint8, 16)
2364 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2365 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2366 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2367 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2368 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2369
2370 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2371 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2372 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2373 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2374 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2375
2376 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2377 0<<cTreatTTROffset| // Do not pop any tags
2378 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2379 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2380 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2381
2382 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2383 0<<cTreatPrioOffset| // vlan prio set to 0
2384 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002385 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002386 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2387
mpagenko551a4d42020-12-08 18:09:20 +00002388 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002389 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002390 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002391 Attributes: me.AttributeValueMap{
2392 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2393 },
2394 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002395 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002396 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2397 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2398 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002399 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002400 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002401 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2402 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002403 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002404 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2405 }
mpagenkodff5dda2020-08-28 11:52:01 +00002406 //accept also nil as (error) return value for writing to LastTx
2407 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002408 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002409 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002410
2411 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002412 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002413 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002414 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002415 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002416 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002417 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2418
mpagenkodff5dda2020-08-28 11:52:01 +00002419 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002420 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002421 { // just for local var's
2422 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002423 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002424 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002425 sliceEvtocdRule := make([]uint8, 16)
2426 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2427 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2428 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2429 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2430 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2431
2432 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2433 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2434 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2435 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2436 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2437
2438 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2439 1<<cTreatTTROffset| // pop the prio-tag
2440 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2441 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2442 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2443
mpagenko551a4d42020-12-08 18:09:20 +00002444 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002445 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2446 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2447 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
Girish Gowdrae95687a2021-09-08 16:30:58 -07002448 oFsm.actualUniFlowParam.VlanRuleParams.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002449 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002450 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002451
2452 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002453 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002454 Attributes: me.AttributeValueMap{
2455 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2456 },
2457 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002458 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002459 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2460 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2461 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002462 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002463 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002464 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2465 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002466 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002467 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2468 }
mpagenkodff5dda2020-08-28 11:52:01 +00002469 //accept also nil as (error) return value for writing to LastTx
2470 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002471 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002472 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002473
2474 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002475 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002476 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002478 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002479 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002480 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2481
mpagenkodff5dda2020-08-28 11:52:01 +00002482 }
2483 } //just for local var's
2484 }
2485 }
2486
mpagenkofc4f56e2020-11-04 17:17:49 +00002487 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002488 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002489 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002490 oFsm.ConfiguredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002491 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002492 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002493}
2494
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002495func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams cmn.UniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002496 oFsm.mutexFlowParams.RLock()
2497 evtocdID := oFsm.evtocdID
2498 oFsm.mutexFlowParams.RUnlock()
2499
mpagenko01e726e2020-10-23 09:45:29 +00002500 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2501 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2502 //transparent transmission was set
2503 //perhaps the config is not needed for removal,
2504 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002505 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002506 "device-id": oFsm.deviceID})
2507 sliceEvtocdRule := make([]uint8, 16)
2508 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2509 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2510 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2511 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2512 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2513
2514 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2515 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2516 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2517 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2518 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2519
2520 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2521 0<<cTreatTTROffset| // Do not pop any tags
2522 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2523 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2524 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2525
2526 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2527 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2528 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2529 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2530
2531 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002532 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002533 Attributes: me.AttributeValueMap{
2534 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2535 },
2536 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002537 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002538 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2539 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2540 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002541 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002542 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002543 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2544 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002545 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002546 return
2547 }
mpagenko01e726e2020-10-23 09:45:29 +00002548 //accept also nil as (error) return value for writing to LastTx
2549 // - this avoids misinterpretation of new received OMCI messages
2550 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002551 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002552
2553 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002554 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002555 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002556 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002557 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002558 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002559 return
2560 }
2561 } else {
2562 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002563 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002564 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002565 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002566 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002567 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002568 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2569 sliceEvtocdRule := make([]uint8, 16)
2570 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2571 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2572 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2573 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2574 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2575
2576 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2577 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2578 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2579 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2580 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2581
2582 // delete indication for the indicated Filter
2583 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2584 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2585
2586 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002587 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002588 Attributes: me.AttributeValueMap{
2589 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2590 },
2591 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002592 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002593 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2594 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2595 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002596 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002597 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002598 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2599 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002600 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002601 return
2602 }
mpagenko01e726e2020-10-23 09:45:29 +00002603 //accept also nil as (error) return value for writing to LastTx
2604 // - this avoids misinterpretation of new received OMCI messages
2605 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002606 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002607
2608 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002609 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002610 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002612 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002613 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002614 return
2615 }
2616 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617 // VOL-3685
2618 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2619 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2620 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2621 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2622 // later when the flow is being re-installed.
2623 // Of course this is applicable to case only where single service (or single tcont) is in use and
2624 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2625 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2626 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002627 if oFsm.ConfiguredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002628 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002629 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002630 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2631 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002632 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002633 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002634 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002635 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002636 meInstance, err := oFsm.pOmciCC.SendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2637 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2638 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002639 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002640 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002641 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2642 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002643 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002644 return
2645 }
mpagenko01e726e2020-10-23 09:45:29 +00002646 //accept also nil as (error) return value for writing to LastTx
2647 // - this avoids misinterpretation of new received OMCI messages
2648 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002649 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002650
2651 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002652 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002653 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002654 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002655 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002656 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
mpagenko01e726e2020-10-23 09:45:29 +00002657 return
2658 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002659 } else {
2660 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2661 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002662 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002663 log.Fields{"configured-flow": oFsm.ConfiguredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002664 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002665 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2666 { // just for local var's
2667 // this defines stacking scenario: untagged->singletagged
2668 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2669 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2670 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2671 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002672 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002673 "device-id": oFsm.deviceID})
2674 sliceEvtocdRule := make([]uint8, 16)
2675 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2676 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2677 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2678 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2679 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002680
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002681 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2682 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2683 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2684 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2685 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002686
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002687 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2688 0<<cTreatTTROffset| // Do not pop any tags
2689 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2690 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2691 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002692
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002693 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2694 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2695 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2696 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002697
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002698 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002699 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002700 Attributes: me.AttributeValueMap{
2701 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2702 },
2703 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002704 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002705 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(context.TODO(),
2706 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2707 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002708 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002709 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002710 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2711 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002712 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002713 return
2714 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002715 //accept also nil as (error) return value for writing to LastTx
2716 // - this avoids misinterpretation of new received OMCI messages
2717 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002718 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002719
2720 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002721 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002722 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002723 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002724 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002725 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002726 return
2727 }
2728 } // just for local var's
2729 { // just for local var's
2730 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002731 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002732 "device-id": oFsm.deviceID})
2733 sliceEvtocdRule := make([]uint8, 16)
2734 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2735 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2736 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2737 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2738 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2739
2740 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2741 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2742 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2743 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2744 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2745
2746 // delete indication for the indicated Filter
2747 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2748 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2749
2750 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002751 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002752 Attributes: me.AttributeValueMap{
2753 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2754 },
2755 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002756 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002757 meInstance, err := oFsm.pOmciCC.SendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2758 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2759 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002760 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002761 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002762 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2763 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002764 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002765 return
2766 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002767 //accept also nil as (error) return value for writing to LastTx
2768 // - this avoids misinterpretation of new received OMCI messages
2769 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002770 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002771
2772 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002773 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002774 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002775 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002776 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002777 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002778 return
2779 }
mpagenko01e726e2020-10-23 09:45:29 +00002780 }
2781 } //just for local var's
2782 }
2783 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002784 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002785 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002786 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002787}
2788
dbainbri4d3a0dc2020-12-02 00:33:42 +00002789func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002790 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002791 if oFsm.isCanceled {
2792 // FSM already canceled before entering wait
2793 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2794 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002795 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkocf48e452021-04-23 09:23:00 +00002796 }
mpagenko7d6bb022021-03-11 15:07:55 +00002797 oFsm.isAwaitingResponse = true
2798 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002799 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302800 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002801 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002802 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002803 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002804 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002805 oFsm.mutexIsAwaitingResponse.Lock()
2806 oFsm.isAwaitingResponse = false
2807 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002808 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002809 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302810 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002811 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002812 oFsm.mutexIsAwaitingResponse.Lock()
2813 oFsm.isAwaitingResponse = false
2814 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002815 return nil
2816 }
mpagenko7d6bb022021-03-11 15:07:55 +00002817 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002818 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002819 oFsm.mutexIsAwaitingResponse.Lock()
2820 oFsm.isAwaitingResponse = false
2821 oFsm.mutexIsAwaitingResponse.Unlock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002822 return fmt.Errorf(cmn.CErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002823 }
2824}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002825
mpagenko551a4d42020-12-08 18:09:20 +00002826func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002827 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002828 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002829 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002830 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002831 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002832 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002833 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002834 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2835 }
2836
dbainbri4d3a0dc2020-12-02 00:33:42 +00002837 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002838 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002840 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002841 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002842 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2843 }
2844
dbainbri4d3a0dc2020-12-02 00:33:42 +00002845 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002846 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002849 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002850 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2851 }
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002852 macBpCdEID, errMacBpCdEID := cmn.GenerateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
Mahir Gunyel6781f962021-05-16 23:30:08 -07002853 if errMacBpCdEID != nil {
2854 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2855 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002856 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
Mahir Gunyel6781f962021-05-16 23:30:08 -07002857 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002858
Mahir Gunyel6781f962021-05-16 23:30:08 -07002859 }
2860 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002861 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.MacBpNo,
2862 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002863 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002864 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002865 Attributes: me.AttributeValueMap{
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002866 "BridgeIdPointer": cmn.MacBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.MacBpNo),
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867 "PortNum": 0xf0, //fixed unique ANI side indication
2868 "TpType": 6, //MCGemIWTP
2869 "TpPointer": multicastGemPortID,
2870 },
2871 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002872 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002873 meInstance, err := oFsm.pOmciCC.SendCreateMBPConfigDataVar(context.TODO(),
2874 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002875 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002876 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002877 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2878 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002879 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002880 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2881 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002882 //accept also nil as (error) return value for writing to LastTx
2883 // - this avoids misinterpretation of new received OMCI messages
2884 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002885 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002886 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002887 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002889 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": cmn.MacBridgeServiceProfileEID})
2890 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002891 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2892 }
2893
2894 // ==> Start creating VTFD for mcast vlan
2895
2896 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2897 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002898 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002899
dbainbri4d3a0dc2020-12-02 00:33:42 +00002900 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002901 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002902 "in state": oFsm.PAdaptFsm.PFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002903 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2904
2905 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2906 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2907 // new vlan associated with a different TP.
2908 vtfdFilterList[0] = uint16(vlanID)
2909
2910 meParams = me.ParamData{
2911 EntityID: mcastVtfdID,
2912 Attributes: me.AttributeValueMap{
2913 "VlanFilterList": vtfdFilterList,
2914 "ForwardOperation": uint8(0x10), //VID investigation
2915 "NumberOfEntries": oFsm.numVlanFilterEntries,
2916 },
2917 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002918 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002919 meInstance, err = oFsm.pOmciCC.SendCreateVtfdVar(context.TODO(),
2920 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002921 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002922 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002923 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2924 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002925 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002926 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2927 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002928 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002929 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002930 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002931 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002932 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002933 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002934 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002935 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2936 }
2937
2938 return nil
2939}
2940
dbainbri4d3a0dc2020-12-02 00:33:42 +00002941func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002942 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002943 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002944 logger.Errorw(ctx, "error generrating me instance id",
2945 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 return err
2947 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002948 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2949 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002950 meParams := me.ParamData{
2951 EntityID: instID,
2952 Attributes: me.AttributeValueMap{
2953 "MeType": 0,
2954 //Direct reference to the Operation profile
2955 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002956 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002957 },
2958 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002959 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002960 meInstance, err := oFsm.pOmciCC.SendCreateMulticastSubConfigInfoVar(context.TODO(),
2961 oFsm.pDeviceHandler.GetOmciTimeout(), true,
2962 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002963 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002964 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002965 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2966 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002967 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002968 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2969 oFsm.deviceID, err)
2970 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002971 //accept also nil as (error) return value for writing to LastTx
2972 // - this avoids misinterpretation of new received OMCI messages
2973 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002974 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002975 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002976 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002977 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002978 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002979 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2980 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2981 }
2982 return nil
2983}
2984
dbainbri4d3a0dc2020-12-02 00:33:42 +00002985func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00002986 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002987 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002988 logger.Errorw(ctx, "error generating me instance id",
2989 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002990 return err
2991 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002992 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2993 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002994 meParams := me.ParamData{
2995 EntityID: instID,
2996 Attributes: me.AttributeValueMap{
2997 "IgmpVersion": 2,
2998 "IgmpFunction": 0,
2999 //0 means false
Girish Gowdraa7beb872021-11-03 11:55:42 -07003000 "ImmediateLeave": 0,
3001 "Robustness": 2,
3002 "QuerierIpAddress": 0,
3003 "QueryInterval": 125,
3004 "QueryMaxResponseTime": 100,
3005 "LastMemberQueryInterval": 10,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003006 //0 means false
Girish Gowdraa7beb872021-11-03 11:55:42 -07003007 "UnauthorizedJoinRequestBehaviour": 0,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003008 },
3009 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003010 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003011 meInstance, err := oFsm.pOmciCC.SendCreateMulticastOperationProfileVar(context.TODO(),
3012 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3013 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003014 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003015 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003016 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
3017 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003018 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003019 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
3020 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003021 //accept also nil as (error) return value for writing to LastTx
3022 // - this avoids misinterpretation of new received OMCI messages
3023 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003024 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003025 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003026 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003027 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003028 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003029 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003030 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003031 }
3032 return nil
3033}
3034
dbainbri4d3a0dc2020-12-02 00:33:42 +00003035func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003036 instID, err := cmn.GenerateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.MacBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03003037 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03003038 logger.Errorw(ctx, "error generating me instance id",
3039 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03003040 return err
3041 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07003042 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
3043 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003044 //TODO check that this is correct
3045 // Table control
3046 //setCtrl = 1
3047 //rowPartId = 0
3048 //test = 0
3049 //rowKey = 0
3050 tableCtrlStr := "0100000000000000"
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003051 tableCtrl := cmn.AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003052 dynamicAccessCL := make([]uint8, 24)
3053 copy(dynamicAccessCL, tableCtrl)
3054 //Multicast GemPortId
3055 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
3056 // python version waits for installation of flows, see line 723 onward of
3057 // brcm_openomci_onu_handler.py
3058 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
3059 //Source IP all to 0
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003060 binary.BigEndian.PutUint32(dynamicAccessCL[6:], cmn.IPToInt32(net.IPv4(0, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003061 //TODO start and end are hardcoded, get from TP
3062 // Destination IP address start of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003063 binary.BigEndian.PutUint32(dynamicAccessCL[10:], cmn.IPToInt32(net.IPv4(225, 0, 0, 0)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003064 // Destination IP address end of range
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003065 binary.BigEndian.PutUint32(dynamicAccessCL[14:], cmn.IPToInt32(net.IPv4(239, 255, 255, 255)))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003066 //imputed group bandwidth
3067 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3068
3069 meParams := me.ParamData{
3070 EntityID: instID,
3071 Attributes: me.AttributeValueMap{
3072 "DynamicAccessControlListTable": dynamicAccessCL,
3073 },
3074 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003075 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003076 meInstance, err := oFsm.pOmciCC.SendSetMulticastOperationProfileVar(context.TODO(),
3077 oFsm.pDeviceHandler.GetOmciTimeout(), true,
3078 oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003079 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003080 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003081 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3082 log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003083 _ = oFsm.PAdaptFsm.PFsm.Event(VlanEvReset)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003084 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3085 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003086 //accept also nil as (error) return value for writing to LastTx
3087 // - this avoids misinterpretation of new received OMCI messages
3088 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003089 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003090 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003091 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003092 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003093 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003094 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003095 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003096 }
3097 return nil
3098}
Girish Gowdra26a40922021-01-29 17:14:34 -08003099
ozgecanetsia82b91a62021-05-21 18:54:49 +03003100func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3101 tpID uint8, uniID uint8, gemPortID uint16) error {
3102 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3103 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3104 // I created unique TD ID by flow direction.
3105 // TODO! Traffic descriptor ME ID will check
3106 trafficDescriptorID := gemPortID
3107 if aMeter == nil {
3108 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3109 }
3110 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3111 if err != nil {
3112 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3113 return err
3114 }
3115 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3116 cbs := trafficShapingInfo.Cbs
3117 pir := trafficShapingInfo.Pir
3118 pbs := trafficShapingInfo.Pbs
3119
3120 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3121 meParams := me.ParamData{
3122 EntityID: trafficDescriptorID,
3123 Attributes: me.AttributeValueMap{
3124 "Cir": cir,
3125 "Pir": pir,
3126 "Cbs": cbs,
3127 "Pbs": pbs,
3128 "ColourMode": 1,
3129 "IngressColourMarking": 3,
3130 "EgressColourMarking": 3,
3131 "MeterType": 1,
3132 },
3133 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003134 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003135 meInstance, errCreateTD := oFsm.pOmciCC.SendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.GetOmciTimeout(),
3136 true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003137 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003138 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003139 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3140 return err
3141 }
3142 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003143 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003144 err = oFsm.waitforOmciResponse(ctx)
3145 if err != nil {
3146 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3147 return err
3148 }
3149
Girish Gowdra09e5f212021-09-30 16:28:36 -07003150 // 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
3151 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID, gemPortID)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003152 if err != nil {
3153 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3154 return err
3155 }
3156 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3157
3158 return nil
3159}
3160
Girish Gowdra09e5f212021-09-30 16:28:36 -07003161func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortEntityID uint16, trafficDescriptorEntityID uint16) error {
3162 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP",
3163 log.Fields{"device-id": oFsm.deviceID, "gem-port-entity-id": gemPortEntityID, "traffic-descriptor-entity-id": trafficDescriptorEntityID})
ozgecanetsia82b91a62021-05-21 18:54:49 +03003164 meParams := me.ParamData{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003165 EntityID: gemPortEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003166 Attributes: me.AttributeValueMap{
Girish Gowdra09e5f212021-09-30 16:28:36 -07003167 "TrafficDescriptorProfilePointerForUpstream": trafficDescriptorEntityID,
ozgecanetsia82b91a62021-05-21 18:54:49 +03003168 },
3169 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003170 oFsm.mutexPLastTxMeInstance.Lock()
Holger Hildebrandt4b5e73f2021-08-19 06:51:21 +00003171 meInstance, err := oFsm.pOmciCC.SendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3172 oFsm.pDeviceHandler.GetOmciTimeout(), true, oFsm.PAdaptFsm.CommChan, meParams)
ozgecanetsia82b91a62021-05-21 18:54:49 +03003173 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003174 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003175 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3176 return err
3177 }
3178 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003179 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003180 err = oFsm.waitforOmciResponse(ctx)
3181 if err != nil {
3182 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3183 return err
3184 }
3185 return nil
3186}
3187
Girish Gowdra26a40922021-01-29 17:14:34 -08003188// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003189func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3190 if oFsm == nil {
3191 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3192 return false
3193 }
mpagenkobb47bc22021-04-20 13:29:09 +00003194 oFsm.mutexFlowParams.Lock()
3195 defer oFsm.mutexFlowParams.Unlock()
3196 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3197 //flow removal is still ongoing/pending
3198 oFsm.signalOnFlowDelete = true
3199 oFsm.flowDeleteChannel = aFlowDeleteChannel
3200 return true
3201 }
3202 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003203}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003204
3205func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3206 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3207 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3208 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3209 log.Fields{"device-id": oFsm.deviceID})
3210 } else {
3211 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3212 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3213 "index": oFsm.numVlanFilterEntries,
3214 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3215 "device-id": oFsm.deviceID})
3216 oFsm.numVlanFilterEntries++
3217 }
3218}
Girish Gowdrae95687a2021-09-08 16:30:58 -07003219
Holger Hildebrandtc192bc42021-10-28 14:38:31 +00003220// pushReponseOnFlowResponseChannel pushes response on the response channel if available
3221func (oFsm *UniVlanConfigFsm) pushReponseOnFlowResponseChannel(ctx context.Context, respChan *chan error, err error) {
Girish Gowdrae95687a2021-09-08 16:30:58 -07003222 if respChan != nil {
3223 // 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
3224 select {
3225 case *respChan <- err:
3226 logger.Debugw(ctx, "submitted-response-for-flow", log.Fields{"device-id": oFsm.deviceID, "err": err})
3227 default:
3228 }
3229 }
3230}