blob: 3201150c44b210c80a1def4a05138c488cb3242c [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
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
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
ozgecanetsia82b91a62021-05-21 18:54:49 +030030 meters "github.com/opencord/voltha-lib-go/v5/pkg/meters"
31 "github.com/opencord/voltha-protos/v4/go/voltha"
32
mpagenko01e726e2020-10-23 09:45:29 +000033 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000034 "github.com/looplab/fsm"
35 "github.com/opencord/omci-lib-go"
36 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070037 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000038 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000039)
40
41const (
42 // internal predefined values
43 cDefaultDownstreamMode = 0
44 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000045 cVtfdTableSize = 12 //as per G.988
46 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000047)
48
49const (
mpagenkof1fc3862021-02-16 10:09:52 +000050 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
51 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
52 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
53 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
54 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
55)
56
57const (
mpagenkodff5dda2020-08-28 11:52:01 +000058 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
59 cFilterPrioOffset = 28
60 cFilterVidOffset = 15
61 cFilterTpidOffset = 12
62 cFilterEtherTypeOffset = 0
63 cTreatTTROffset = 30
64 cTreatPrioOffset = 16
65 cTreatVidOffset = 3
66 cTreatTpidOffset = 0
67)
68const (
69 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
70 cFilterOuterOffset = 0
71 cFilterInnerOffset = 4
72 cTreatOuterOffset = 8
73 cTreatInnerOffset = 12
74)
75const (
76 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
77 cPrioIgnoreTag uint32 = 15
78 cPrioDefaultFilter uint32 = 14
79 cPrioDoNotFilter uint32 = 8
80 cDoNotFilterVid uint32 = 4096
81 cDoNotFilterTPID uint32 = 0
82 cDoNotFilterEtherType uint32 = 0
83 cDoNotAddPrio uint32 = 15
84 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053085 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000086 cDontCareVid uint32 = 0
87 cDontCareTpid uint32 = 0
88 cSetOutputTpidCopyDei uint32 = 4
89)
90
91const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000092 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000093 vlanEvStart = "vlanEvStart"
mpagenkof1d21d12021-06-11 13:14:45 +000094 vlanEvPrepareDone = "vlanEvPrepareDone"
mpagenko535d6ef2021-02-26 13:15:34 +000095 vlanEvWaitTechProf = "vlanEvWaitTechProf"
96 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
97 vlanEvContinueConfig = "vlanEvContinueConfig"
98 vlanEvStartConfig = "vlanEvStartConfig"
99 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
100 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
101 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
102 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
103 vlanEvRenew = "vlanEvRenew"
104 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
105 vlanEvRemFlowDone = "vlanEvRemFlowDone"
106 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000107 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
108 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000109 vlanEvReset = "vlanEvReset"
110 vlanEvRestart = "vlanEvRestart"
111 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
112 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000113)
mpagenko01e726e2020-10-23 09:45:29 +0000114
mpagenkodff5dda2020-08-28 11:52:01 +0000115const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000116 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000117 vlanStDisabled = "vlanStDisabled"
mpagenkof1d21d12021-06-11 13:14:45 +0000118 vlanStPreparing = "vlanStPreparing"
mpagenkodff5dda2020-08-28 11:52:01 +0000119 vlanStStarting = "vlanStStarting"
120 vlanStWaitingTechProf = "vlanStWaitingTechProf"
121 vlanStConfigVtfd = "vlanStConfigVtfd"
122 vlanStConfigEvtocd = "vlanStConfigEvtocd"
123 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000124 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000125 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000126 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000127 vlanStCleanupDone = "vlanStCleanupDone"
128 vlanStResetting = "vlanStResetting"
129)
mpagenkof1fc3862021-02-16 10:09:52 +0000130const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
131const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000132
mpagenko01e726e2020-10-23 09:45:29 +0000133type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000134 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000135 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
136 MatchPcp uint32 `json:"match_pcp"`
137 TagsToRemove uint32 `json:"tags_to_remove"`
138 SetVid uint32 `json:"set_vid"`
139 SetPcp uint32 `json:"set_pcp"`
140}
141
142type uniVlanFlowParams struct {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300143 CookieSlice []uint64 `json:"cookie_slice"`
144 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
145 Meter *voltha.OfpMeterConfig `json:"flow_meter"`
mpagenko01e726e2020-10-23 09:45:29 +0000146}
147
148type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000149 isSuspendedOnAdd bool
150 removeChannel chan bool
151 cookie uint64 //just the last cookie valid for removal
152 vlanRuleParams uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000153}
154
mpagenkobb47bc22021-04-20 13:29:09 +0000155//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
156// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000157type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000159 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530160 pOmciCC *omciCC
161 pOnuUniPort *onuUniPort
162 pUniTechProf *onuUniTechProf
163 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000164 requestEvent OnuDeviceEvent
165 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
166 pAdaptFsm *AdapterFsm
167 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000168 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000169 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000170 isAwaitingResponse bool
171 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000172 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000173 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000174 actualUniVlanConfigRule uniVlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300175 actualUniVlanConfigMeter *voltha.OfpMeterConfig
mpagenko01e726e2020-10-23 09:45:29 +0000176 uniVlanFlowParamsSlice []uniVlanFlowParams
177 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000178 numUniFlows uint8 // expected number of flows should be less than 12
179 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000180 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000181 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000182 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000183 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000184 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000185 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000186 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000187 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000188 signalOnFlowDelete bool
189 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000190 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
191 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200192 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
193 // thus notification needs to be sent on chan.
194 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000195}
196
mpagenko01e726e2020-10-23 09:45:29 +0000197//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
198// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000199func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000200 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000201 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300202 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000203 instFsm := &UniVlanConfigFsm{
204 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000205 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000206 pOmciCC: apDevOmciCC,
207 pOnuUniPort: apUniPort,
208 pUniTechProf: apUniTechProf,
209 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000210 requestEvent: aRequestEvent,
211 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000212 numUniFlows: 0,
213 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000214 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000215 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200216 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000217 }
218
mpagenko01e726e2020-10-23 09:45:29 +0000219 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000220 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000222 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000223 return nil
224 }
mpagenkodff5dda2020-08-28 11:52:01 +0000225 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
226 vlanStDisabled,
227 fsm.Events{
mpagenkof1d21d12021-06-11 13:14:45 +0000228 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStPreparing},
229 {Name: vlanEvPrepareDone, Src: []string{vlanStPreparing}, Dst: vlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000230 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000231 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000232 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
233 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
234 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000235 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
236 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000237 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
238 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
239 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
240 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000241 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
242 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
243 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000244 /*
245 {Name: vlanEvTimeoutSimple, Src: []string{
246 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
247 {Name: vlanEvTimeoutMids, Src: []string{
248 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
249 */
250 // exceptional treatment for all states except vlanStResetting
251 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000252 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000253 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000254 Dst: vlanStResetting},
255 // the only way to get to resource-cleared disabled state again is via "resseting"
256 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000257 // transitions for reconcile handling according to VOL-3834
mpagenkof1d21d12021-06-11 13:14:45 +0000258 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStPreparing}, Dst: vlanStConfigDone},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000259 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
260 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000261 },
mpagenkodff5dda2020-08-28 11:52:01 +0000262 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000263 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
mpagenkof1d21d12021-06-11 13:14:45 +0000264 "enter_" + vlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
266 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
267 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
268 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
269 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
270 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
271 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
272 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
273 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000274 },
275 )
276 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000278 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return nil
280 }
281
ozgecanetsia82b91a62021-05-21 18:54:49 +0300282 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000283
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000286 return instFsm
287}
288
mpagenko01e726e2020-10-23 09:45:29 +0000289//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000290func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300291 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000293 TpID: aTpID,
294 MatchVid: uint32(aMatchVlan),
295 SetVid: uint32(aSetVlan),
296 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 }
298 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000299 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
300 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301
mpagenko01e726e2020-10-23 09:45:29 +0000302 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 //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 +0000304 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000305 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
306 } else {
307 if !oFsm.acceptIncrementalEvtoOption {
308 //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 +0000309 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 }
311 }
312
mpagenko01e726e2020-10-23 09:45:29 +0000313 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000314 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000315 loRuleParams.TagsToRemove = 0 //no tag pop action
316 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
317 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000318 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
319 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
320 // might collide with NoMatchVid/CopyPrio(/setVid) setting
321 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000322 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000323 }
324 }
mpagenko01e726e2020-10-23 09:45:29 +0000325
326 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
327 loFlowParams.CookieSlice = make([]uint64, 0)
328 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300329 if aMeter != nil {
330 loFlowParams.Meter = aMeter
331 }
mpagenko01e726e2020-10-23 09:45:29 +0000332
333 //no mutex protection is required for initial access and adding the first flow is always possible
334 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
335 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000337 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
338 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
339 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
340 "SetPcp": loRuleParams.SetPcp,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300341 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000342 oFsm.numUniFlows = 1
343 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
344
345 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +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) {
mpagenko7d6bb022021-03-11 15:07:55 +0000357 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000358 oFsm.mutexIsAwaitingResponse.Lock()
359 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000360 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000361 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
362 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
363 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000364 //use channel to indicate that the response waiting shall be aborted
365 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000366 } else {
367 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000368 }
mpagenkocf48e452021-04-23 09:23:00 +0000369
mpagenko7d6bb022021-03-11 15:07:55 +0000370 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
371 pAdaptFsm := oFsm.pAdaptFsm
372 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000373 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000374 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000375 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000376 }
mpagenko7d6bb022021-03-11 15:07:55 +0000377 }
378}
379
mpagenko551a4d42020-12-08 18:09:20 +0000380//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
381func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
382 //mutex protection is required for possible concurrent access to FSM members
383 oFsm.mutexFlowParams.RLock()
384 defer oFsm.mutexFlowParams.RUnlock()
385 return oFsm.TpIDWaitingFor
386}
387
mpagenko2418ab02020-11-12 12:58:06 +0000388//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
389func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
390 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000391 oFsm.mutexFlowParams.Lock()
392 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000393 oFsm.clearPersistency = aClear
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,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300402 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000403 loRuleParams := uniVlanRuleParams{
404 TpID: aTpID,
405 MatchVid: uint32(aMatchVlan),
406 SetVid: uint32(aSetVlan),
407 SetPcp: uint32(aSetPcp),
408 }
409 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
410 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
411 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000412 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
413 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
414 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
415 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
416 } else {
417 if !oFsm.acceptIncrementalEvtoOption {
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 }
421 }
422
423 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
424 // no prio/vid filtering requested
425 loRuleParams.TagsToRemove = 0 //no tag pop action
426 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
427 if loRuleParams.SetPcp == cCopyPrioFromInner {
428 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
429 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
430 // might collide with NoMatchVid/CopyPrio(/setVid) setting
431 // this was some precondition setting taken over from py adapter ..
432 loRuleParams.SetPcp = 0
433 }
434 }
435
mpagenkof1d21d12021-06-11 13:14:45 +0000436 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
437 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
438 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
439 oFsm.mutexFlowParams.RLock()
440 if len(oFsm.uniRemoveFlowsSlice) > 0 {
441 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
442 if removeUniFlowParams.vlanRuleParams == loRuleParams {
443 // the flow to add is the same as the one already in progress of deleting
444 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000445 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
446 if flow >= len(oFsm.uniRemoveFlowsSlice) {
447 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
448 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
449 oFsm.mutexFlowParams.RUnlock()
450 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
451 }
mpagenkof1d21d12021-06-11 13:14:45 +0000452 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
453 oFsm.mutexFlowParams.RUnlock()
454 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
455 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
456 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
457 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
458 }
459 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000460 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000461 }
462 }
463 }
464 oFsm.mutexFlowParams.RUnlock()
465
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000466 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000467 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000468 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200469 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000470 //mutex protection is required for possible concurrent access to FSM members
471 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000472 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
473 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
474 // countable run time optimization (perhaps with including the hash in kvStore storage?)
475 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000476 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300478 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
479 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
480 "SetPcp": loRuleParams.SetPcp,
481 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000482 var cookieMatch bool
483 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
484 cookieMatch = false
485 for _, cookie := range storedUniFlowParams.CookieSlice {
486 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000488 "device-id": oFsm.deviceID, "cookie": cookie})
489 cookieMatch = true
490 break //found new cookie - no further search for this requested cookie
491 }
492 }
493 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000494 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
495 if delayedCookie != 0 {
496 //a delay for adding the cookie to this rule is requested
497 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
498 oFsm.mutexFlowParams.Unlock()
mpagenko2f487262021-08-23 15:59:06 +0000499 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
500 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
501 "device-id": oFsm.deviceID, "cookie": delayedCookie})
502 return fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
503 }
mpagenkof1fc3862021-02-16 10:09:52 +0000504 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
505 oFsm.mutexFlowParams.Lock()
506 } else {
507 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
508 "device-id": oFsm.deviceID, "cookie": newCookie})
509 //as range works with copies of the slice we have to write to the original slice!!
510 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
511 newCookie)
512 flowCookieModify = true
513 }
mpagenko01e726e2020-10-23 09:45:29 +0000514 }
515 } //for all new cookies
516 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000517 }
518 }
mpagenkof1fc3862021-02-16 10:09:52 +0000519 oFsm.mutexFlowParams.Unlock()
520
521 if !flowEntryMatch { //it is (was) a new rule
mpagenko2f487262021-08-23 15:59:06 +0000522 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
523 if !deleteSuccess {
524 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
525 "device-id": oFsm.deviceID, "cookie": delayedCookie})
526 return fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
527 }
mpagenkof1fc3862021-02-16 10:09:52 +0000528 requestAppendRule = true //default assumption here is that rule is to be appended
529 flowCookieModify = true //and that the the flow data base is to be updated
530 if delayedCookie != 0 { //it was suspended
531 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
532 }
533 }
534 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
535 if requestAppendRule {
536 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000537 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000538 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
539 loFlowParams.CookieSlice = make([]uint64, 0)
540 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300541 if aMeter != nil {
542 loFlowParams.Meter = aMeter
543 }
mpagenko01e726e2020-10-23 09:45:29 +0000544 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000545 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000546 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
547 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
548 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800549 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300550 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000551
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000552 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000553 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
554
555 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
556 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
557 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000558 //attention: take care to release the mutexFlowParams when calling the FSM directly -
559 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000560 oFsm.mutexFlowParams.Unlock()
561 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000562 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
563 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
564 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
565 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000566 }
567 return nil
568 }
mpagenko01e726e2020-10-23 09:45:29 +0000569 // note: theoretical it would be possible to clear the same rule from the remove slice
570 // (for entries that have not yet been started with removal)
571 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
572 // 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 +0000573
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000574 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
575 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000576 if oFsm.configuredUniFlow == 0 {
577 // this is a restart with a complete new flow, we can re-use the initial flow config control
578 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000579 //attention: take care to release the mutexFlowParams when calling the FSM directly -
580 // synchronous FSM 'event/state' functions may rely on this mutex
581 oFsm.mutexFlowParams.Unlock()
582 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
583 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
584 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
585 }
mpagenko551a4d42020-12-08 18:09:20 +0000586 } else {
587 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000588 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000589 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
590 //check introduced after having observed some panic here
591 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
592 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
593 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
594 oFsm.mutexFlowParams.Unlock()
595 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
596 }
mpagenko9a304ea2020-12-16 15:54:01 +0000597 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300598 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +0000599 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000600 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000601 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +0000602 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000603 //attention: take care to release the mutexFlowParams when calling the FSM directly -
604 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko18eca9c2021-07-26 11:03:45 +0000605 // but it must be released already before calling getTechProfileDone() as it may already be locked
606 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000607 oFsm.mutexFlowParams.Unlock()
mpagenko18eca9c2021-07-26 11:03:45 +0000608 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
609 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
610 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
611 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
612
mpagenkobb47bc22021-04-20 13:29:09 +0000613 var fsmErr error
614 if loTechProfDone {
615 // let the vlan processing continue with next rule
616 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
617 } else {
618 // set to waiting for Techprofile
619 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
620 }
621 if fsmErr != nil {
622 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
623 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
624 }
mpagenko551a4d42020-12-08 18:09:20 +0000625 }
mpagenkobb47bc22021-04-20 13:29:09 +0000626 } else {
627 // if not in the appropriate state a new entry will be automatically considered later
628 // when the configDone state is reached
629 oFsm.mutexFlowParams.Unlock()
630 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000631 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000632 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000633 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000634 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000635 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
636 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000637 } else {
638 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000639 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000640 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000641 if oFsm.numUniFlows == oFsm.configuredUniFlow {
642 //all requested rules really have been configured
643 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000644 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000645 if oFsm.pDeviceHandler != nil {
646 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000647 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000648 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000649 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
650 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000651 }
652 } else {
653 // avoid device reason update as the rule config connected to this flow may still be in progress
654 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000656 log.Fields{"device-id": oFsm.deviceID,
657 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000658 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000659 }
660 }
mpagenko01e726e2020-10-23 09:45:29 +0000661
mpagenkof1fc3862021-02-16 10:09:52 +0000662 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000663 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000664 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000665 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
666 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000667 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000668 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000669 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000670 }
mpagenko15ff4a52021-03-02 10:09:20 +0000671 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000672 }
673 return nil
674}
675
mpagenkof1d21d12021-06-11 13:14:45 +0000676func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
677 oFsm.mutexFlowParams.Lock()
678 deleteChannel := apRemoveFlowParams.removeChannel
679 apRemoveFlowParams.isSuspendedOnAdd = true
680 oFsm.mutexFlowParams.Unlock()
681
682 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
683 select {
684 case success := <-deleteChannel:
685 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
686 if success {
687 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
688 "device-id": oFsm.deviceID})
689 return nil
690 }
691 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
692 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
693 oFsm.mutexFlowParams.Lock()
694 if apRemoveFlowParams != nil {
695 apRemoveFlowParams.isSuspendedOnAdd = false
696 }
697 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000698 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000699 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000700 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000701 }
mpagenkof1d21d12021-06-11 13:14:45 +0000702}
703
mpagenkof1fc3862021-02-16 10:09:52 +0000704// VOL-3828 flow config sequence workaround ########### start ##########
705func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
706 //assumes mutexFlowParams.Lock() protection from caller!
707 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
708 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000709 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000710 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
711 newCookie := aCookieSlice[0]
712 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
713 for _, cookie := range storedUniFlowParams.CookieSlice {
714 if cookie == newCookie {
715 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
716 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
717 oFsm.delayNewRuleCookie = newCookie
718 return newCookie //found new cookie in some existing rule
719 }
720 } // for all stored cookies of the actual inspected rule
721 } //for all rules
722 }
723 return 0 //no delay requested
724}
mpagenko2f487262021-08-23 15:59:06 +0000725func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000726 oFsm.mutexFlowParams.RLock()
727 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
728 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
729 oFsm.mutexFlowParams.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +0000730 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000731 select {
mpagenko2f487262021-08-23 15:59:06 +0000732 case cookieDeleted = <-oFsm.chCookieDeleted:
733 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
734 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000735 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000736 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
737 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
738 }
739 oFsm.mutexFlowParams.Lock()
740 oFsm.delayNewRuleCookie = 0
741 oFsm.mutexFlowParams.Unlock()
mpagenko2f487262021-08-23 15:59:06 +0000742 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000743}
mpagenko2f487262021-08-23 15:59:06 +0000744func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000745 oFsm.mutexFlowParams.Lock()
746 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
747 oFsm.mutexFlowParams.Unlock()
748
mpagenko2f487262021-08-23 15:59:06 +0000749 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000750 if delayedCookie != 0 {
mpagenko2f487262021-08-23 15:59:06 +0000751 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000752 }
mpagenko2f487262021-08-23 15:59:06 +0000753 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000754}
755
756//returns flowModified, RuleAppendRequest
757func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
758 flowEntryMatch := false
759 oFsm.mutexFlowParams.Lock()
760 defer oFsm.mutexFlowParams.Unlock()
761 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
762 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
763 flowEntryMatch = true
764 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
765 "device-id": oFsm.deviceID})
766 cookieMatch := false
767 for _, cookie := range storedUniFlowParams.CookieSlice {
768 if cookie == aCookie {
769 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
770 "device-id": oFsm.deviceID, "cookie": cookie})
771 cookieMatch = true
772 break //found new cookie - no further search for this requested cookie
773 }
774 }
775 if !cookieMatch {
776 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
777 "device-id": oFsm.deviceID, "cookie": aCookie})
778 //as range works with copies of the slice we have to write to the original slice!!
779 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
780 aCookie)
781 return true, false //flowModified, NoRuleAppend
782 }
783 break // found rule - no further rule search
784 }
785 }
786 if !flowEntryMatch { //it is a new rule
787 return true, true //flowModified, RuleAppend
788 }
789 return false, false //flowNotModified, NoRuleAppend
790}
791
792// VOL-3828 flow config sequence workaround ########### end ##########
793
mpagenko01e726e2020-10-23 09:45:29 +0000794//RemoveUniFlowParams verifies on existence of flow cookie,
795// if found removes cookie from flow cookie list and if this is empty
796// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000797func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000798 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000799 flowCookieMatch := false
800 //mutex protection is required for possible concurrent access to FSM members
801 oFsm.mutexFlowParams.Lock()
802 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000803remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000804 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
805 for i, cookie := range storedUniFlowParams.CookieSlice {
806 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000807 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000808 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000809 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000810 //remove the cookie from the cookie slice and verify it is getting empty
811 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000812 // had to shift content to function due to sca complexity
813 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenko333846a2021-07-21 12:38:07 +0000814 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000815 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000816 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000817 //cut off the requested cookie by slicing out this element
818 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
819 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
820 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000821 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
822 // state transition notification is checked in deviceHandler
823 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000824 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
825 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000826 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000827 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000828 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000829 if deletedCookie == oFsm.delayNewRuleCookie {
830 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
831 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
832 //simply use the first one
833 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
834 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
835 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
836 }
mpagenko333846a2021-07-21 12:38:07 +0000837 //permanently store the modified flow config for reconcile case and immediately write to KvStore
838 if oFsm.pDeviceHandler != nil {
839 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
840 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
841 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
842 return err
843 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000844 }
mpagenko01e726e2020-10-23 09:45:29 +0000845 }
mpagenkof1fc3862021-02-16 10:09:52 +0000846 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000847 }
848 }
mpagenko01e726e2020-10-23 09:45:29 +0000849 } //search all flows
850 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000851 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000852 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
853 // but accept the request with success as no such cookie (flow) does exist
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 {
mpagenkof1fc3862021-02-16 10:09:52 +0000857 // success indication without the need to write to kvStore (no change)
858 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000859 }
mpagenko01e726e2020-10-23 09:45:29 +0000860 return nil
861 } //unknown cookie
862
863 return nil
864}
865
mpagenkof582d6a2021-06-18 15:58:10 +0000866// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenko333846a2021-07-21 12:38:07 +0000867// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000868func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
869 aUniFlowParams uniVlanFlowParams, aCookie uint64) bool {
870 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
871 var cancelPendingConfig bool = false
872 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
873 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
874 "device-id": oFsm.deviceID})
875 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
876 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
877 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
878 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
879 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
880 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
881 log.Fields{"device-id": oFsm.deviceID})
882 cancelPendingConfig = true
883 } else {
884 //create a new element for the removeVlanFlow slice
885 loRemoveParams = uniRemoveVlanFlowParams{
886 vlanRuleParams: aUniFlowParams.VlanRuleParams,
887 cookie: aCookie,
888 }
889 loRemoveParams.removeChannel = make(chan bool)
890 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
891 }
892
893 usedTpID := aUniFlowParams.VlanRuleParams.TpID
894 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
895 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
896 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
897 if !cancelPendingConfig {
mpagenko7a592192021-07-28 13:32:00 +0000898 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
899 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000900 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
901 "device-id": oFsm.deviceID})
902 if oFsm.pUniTechProf != nil {
903 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
904 }
mpagenko7a592192021-07-28 13:32:00 +0000905 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000906 }
907 } else {
908 if !cancelPendingConfig {
909 oFsm.updateTechProfileToDelete(ctx, usedTpID)
910 }
911 }
912 //trigger the FSM to remove the relevant rule
913 if cancelPendingConfig {
914 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
915 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
916 //call from 'non-configured' state of the rules
917 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
918 //something quite inconsistent detected, perhaps just try to recover with FSM reset
919 oFsm.mutexFlowParams.Unlock()
920 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvReset); fsmErr != nil {
921 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
922 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
923 }
924 return false //data base update could not be done, return like cookie not found
925 }
926
927 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
928 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
929 // synchronous FSM 'event/state' functions may rely on this mutex
930 oFsm.mutexFlowParams.Unlock()
931 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
932 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
933 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
934 }
935 oFsm.mutexFlowParams.Lock()
936 return true
937 }
938 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
939 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
940 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
941 "tp-id": loRemoveParams.vlanRuleParams.TpID,
942 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
943 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
944 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
945 // synchronous FSM 'event/state' functions may rely on this mutex
946 oFsm.mutexFlowParams.Unlock()
947 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
948 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
949 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
950 }
951 oFsm.mutexFlowParams.Lock()
952 } // if not in the appropriate state a new entry will be automatically considered later
953 // when the configDone state is reached
954 return true
955}
956
mpagenkof1d21d12021-06-11 13:14:45 +0000957//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
958// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
959// from the start of the deletion request to avoid to much interference
960// so when called, there can only be one cookie active for this flow
961// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000962func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000963 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
964 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000965 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000966removeFromSlice_loop:
967 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000968 // if UniFlowParams exists, cookieSlice should always have at least one element
969 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
970 if cookieSliceLen == 1 {
971 if storedUniFlowParams.CookieSlice[0] == aCookie {
972 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +0000973 }
mpagenkof582d6a2021-06-18 15:58:10 +0000974 } else if cookieSliceLen == 0 {
975 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
976 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
977 return errors.New(errStr)
978 } else {
979 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
980 logger.Errorw(ctx, errStr, log.Fields{
981 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
982 for _, cookie := range storedUniFlowParams.CookieSlice {
983 if cookie == aCookie {
984 cookieFound = true
985 break
986 }
987 }
988 }
989 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +0000990 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
991 "device-id": oFsm.deviceID, "cookie": aCookie})
992 //remove the actual element from the addVlanFlow slice
993 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
994 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
995 oFsm.numUniFlows = 0 //no more flows
996 oFsm.configuredUniFlow = 0 //no more flows configured
997 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
998 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
999 //request that this profile gets deleted before a new flow add is allowed
1000 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1001 "device-id": oFsm.deviceID})
1002 } else {
1003 oFsm.numUniFlows--
1004 if aWasConfigured && oFsm.configuredUniFlow > 0 {
1005 oFsm.configuredUniFlow--
1006 }
1007 //cut off the requested flow by slicing out this element
1008 oFsm.uniVlanFlowParamsSlice = append(
1009 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1010 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1011 "device-id": oFsm.deviceID})
1012 }
1013 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1014 }
1015 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001016 if !cookieFound {
1017 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1018 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1019 return errors.New(errStr)
1020 }
mpagenko333846a2021-07-21 12:38:07 +00001021 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1022 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
1023 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
1024 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1025 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1026 return err
1027 }
mpagenkof582d6a2021-06-18 15:58:10 +00001028 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001029}
1030
1031// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001032func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1033 //here we have to check, if there are still other flows referencing to the actual ProfileId
1034 // before we can request that this profile gets deleted before a new flow add is allowed
1035 tpIDInOtherFlows := false
1036 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1037 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1038 tpIDInOtherFlows = true
1039 break // search loop can be left
1040 }
1041 }
1042 if tpIDInOtherFlows {
1043 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1044 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1045 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001046 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 +00001047 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko7a592192021-07-28 13:32:00 +00001048 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1049 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001050 if oFsm.pUniTechProf != nil {
1051 //request that this profile gets deleted before a new flow add is allowed
1052 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
1053 }
mpagenko7a592192021-07-28 13:32:00 +00001054 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001055 }
1056}
1057
mpagenkof1d21d12021-06-11 13:14:45 +00001058func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1059 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001060
1061 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001062 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001063 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001064 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001065 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001066 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001067 //let the state machine run forward from here directly
1068 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1069 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001070 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1071 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
1072 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001073 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001074 go func(a_pAFsm *AdapterFsm) {
1075 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
1076 }(pConfigVlanStateAFsm)
1077 return
1078 }
mpagenkof1d21d12021-06-11 13:14:45 +00001079 // Can't call FSM Event directly, decoupling it
1080 go func(a_pAFsm *AdapterFsm) {
1081 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
1082 }(pConfigVlanStateAFsm)
1083 return
1084 }
1085 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1086 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1087 //should never happen, else: recovery would be needed from outside the FSM
1088}
1089
1090func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1091 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1092 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1093 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001094 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001095 //possibly the entry is not valid anymore based on intermediate delete requests
1096 //just a basic protection ...
1097 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1098 oFsm.mutexFlowParams.Unlock()
1099 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1100 "device-id": oFsm.deviceID})
1101 // Can't call FSM Event directly, decoupling it
1102 go func(a_pAFsm *AdapterFsm) {
1103 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1104 }(pConfigVlanStateAFsm)
1105 return
1106 }
mpagenko9a304ea2020-12-16 15:54:01 +00001107 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1108 //store the actual rule that shall be worked upon in the following transient states
1109 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001110 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
mpagenko9a304ea2020-12-16 15:54:01 +00001111 tpID := oFsm.actualUniVlanConfigRule.TpID
1112 oFsm.TpIDWaitingFor = tpID
Girish Gowdra24dd1132021-07-06 15:25:40 -07001113 //cmp also usage in EVTOCDE create in omci_cc
1114 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko18eca9c2021-07-26 11:03:45 +00001115 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1116 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1117 // synchronous FSM 'event/state' functions may rely on this mutex
1118 // but it must be released already before calling getTechProfileDone() as it may already be locked
1119 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001120 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001121 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001122 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1123 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001124 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001125
mpagenko9a304ea2020-12-16 15:54:01 +00001126 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001127 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1128 if aPAFsm != nil && aPAFsm.pFsm != nil {
1129 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001130 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001131 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001132 } else {
1133 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001134 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001135 }
1136 }
mpagenko551a4d42020-12-08 18:09:20 +00001137 }(pConfigVlanStateAFsm, loTechProfDone)
1138 } else {
1139 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1140 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1141 //should never happen, else: recovery would be needed from outside the FSM
1142 return
mpagenkodff5dda2020-08-28 11:52:01 +00001143 }
1144}
1145
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001147 //mutex protection is required for possible concurrent access to FSM members
1148 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001149 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001150 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001151 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001152 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001154 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001155 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001156 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001157 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001158 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301159 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001160 }(pConfigVlanStateAFsm)
1161 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001162 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1163 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001164 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001166 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001167 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1168 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001169 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001170 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001171 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001172 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001173 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1174 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001175 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001176 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001177 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001178 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1179 "ForwardOperation": uint8(0x10), //VID investigation
1180 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001181 },
1182 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001183 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001184 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001185 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001186 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001187 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001188 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001189 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001190 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1191 log.Fields{"device-id": oFsm.deviceID})
1192 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1193 if pConfigVlanStateAFsm != nil {
1194 go func(a_pAFsm *AdapterFsm) {
1195 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1196 }(pConfigVlanStateAFsm)
1197 }
1198 return
1199 }
mpagenkodff5dda2020-08-28 11:52:01 +00001200 //accept also nil as (error) return value for writing to LastTx
1201 // - this avoids misinterpretation of new received OMCI messages
1202 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1203 // send shall return (dual format) error code that can be used here for immediate error treatment
1204 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001205 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001206 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001207 }
1208}
1209
dbainbri4d3a0dc2020-12-02 00:33:42 +00001210func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1211 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001212 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001213 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001214 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001215 //using the first element in the slice because it's the first flow per definition here
1216 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001217 //This is correct passing scenario
1218 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001219 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001220 tpID := oFsm.actualUniVlanConfigRule.TpID
1221 vlanID := oFsm.actualUniVlanConfigRule.SetVid
mpagenko7a592192021-07-28 13:32:00 +00001222 configuredUniFlows := oFsm.configuredUniFlow
1223 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1224 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001225 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1226 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
mpagenko7a592192021-07-28 13:32:00 +00001227 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001228 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001229 vlanID)
1230 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001231 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001232 log.Fields{"device-id": oFsm.deviceID})
1233 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1234 }
1235 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001236 //If this first flow contains a meter, then create TD for related gems.
1237 if oFsm.actualUniVlanConfigMeter != nil {
1238 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter})
1239 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1240 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1241 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1242 oFsm.pOnuUniPort.uniID, gemPort)
1243 if errCreateTrafficDescriptor != nil {
1244 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1245 log.Fields{"device-id": oFsm.deviceID})
1246 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1247 }
1248 }
1249 }
1250
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001251 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1252 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1253 }
1254 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001255}
1256
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001258
mpagenkof1d21d12021-06-11 13:14:45 +00001259 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001260
mpagenkof1fc3862021-02-16 10:09:52 +00001261 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001262 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001263 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1264 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1265 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001266 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001267 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1268 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1269 //should never happen, else: recovery would be needed from outside the FSM
1270 return
1271 }
1272 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001273 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1274 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001275 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1276 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1277 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1278 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001279 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001280 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001281 go func(a_pBaseFsm *fsm.FSM) {
1282 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1283 }(pConfigVlanStateBaseFsm)
1284 return
1285 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001286 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1287 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001288 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001289 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001290 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001291 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1292 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001293 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1294 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001295 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001296 return
1297 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001298 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001299 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001300 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001301 // this is a restart with a complete new flow, we can re-use the initial flow config control
1302 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001303 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001304 go func(a_pBaseFsm *fsm.FSM) {
1305 _ = a_pBaseFsm.Event(vlanEvRenew)
1306 }(pConfigVlanStateBaseFsm)
1307 return
1308 }
1309
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001310 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001311 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001312 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1313 //check introduced after having observed some panic in this processing
1314 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1315 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1316 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1317 oFsm.mutexFlowParams.Unlock()
1318 go func(a_pAFsm *AdapterFsm) {
1319 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1320 }(pConfigVlanStateAFsm)
1321 return
1322 }
mpagenko9a304ea2020-12-16 15:54:01 +00001323 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001324 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +00001325 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001326 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001327 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +00001328 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1329 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1330 // synchronous FSM 'event/state' functions may rely on this mutex
1331 // but it must be released already before calling getTechProfileDone() as it may already be locked
1332 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1333 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001334 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001335 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1336 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001337 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1338
mpagenko9a304ea2020-12-16 15:54:01 +00001339 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001340 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1341 if aTechProfDone {
1342 // let the vlan processing continue with next rule
1343 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1344 } else {
1345 // set to waiting for Techprofile
1346 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1347 }
1348 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001349 return
1350 }
mpagenkof1d21d12021-06-11 13:14:45 +00001351 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001352 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001353 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001354 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1355 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001356 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001357 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001358 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001360 }
1361}
1362
dbainbri4d3a0dc2020-12-02 00:33:42 +00001363func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001364
1365 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1366 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1367 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1368 go func(a_pBaseFsm *fsm.FSM) {
1369 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1370 }(oFsm.pAdaptFsm.pFsm)
1371 return
1372 }
mpagenko15ff4a52021-03-02 10:09:20 +00001373 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001374 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001375 "recent flow-number": oFsm.configuredUniFlow,
1376 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001377 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001378
mpagenko9a304ea2020-12-16 15:54:01 +00001379 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001380 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001382 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001383 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001384 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1385 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1386 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1387 // 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 +00001388 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001389 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1390 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001391 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001392 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001394 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001395 "device-id": oFsm.deviceID,
1396 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001397 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001398 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001399
mpagenko01e726e2020-10-23 09:45:29 +00001400 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001401 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1402 oFsm.numVlanFilterEntries = 1
1403 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001404 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001405 Attributes: me.AttributeValueMap{
1406 "VlanFilterList": vtfdFilterList,
1407 "ForwardOperation": uint8(0x10), //VID investigation
1408 "NumberOfEntries": oFsm.numVlanFilterEntries,
1409 },
1410 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001411 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001412 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001413 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001414 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001415 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001416 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001417 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1418 log.Fields{"device-id": oFsm.deviceID})
1419 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1420 if pConfigVlanStateAFsm != nil {
1421 go func(a_pAFsm *AdapterFsm) {
1422 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1423 }(pConfigVlanStateAFsm)
1424 }
1425 return
1426 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001427 //accept also nil as (error) return value for writing to LastTx
1428 // - this avoids misinterpretation of new received OMCI messages
1429 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1430 // send shall return (dual format) error code that can be used here for immediate error treatment
1431 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001432 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001433 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001434 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001435 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1436 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001437 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001438
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001440 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001441 "device-id": oFsm.deviceID,
1442 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001443 // setVid is assumed to be masked already by the caller to 12 bit
1444 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001445 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001446 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001447
1448 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1449 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1450 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001451 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001452
1453 oFsm.numVlanFilterEntries++
1454 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001455 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001456 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001457 "VlanFilterList": vtfdFilterList,
1458 "ForwardOperation": uint8(0x10), //VID investigation
1459 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001460 },
1461 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001462 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001463 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001464 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001465 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001466 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001467 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001468 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1469 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1470 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1471 return
1472 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001473 //accept also nil as (error) return value for writing to LastTx
1474 // - this avoids misinterpretation of new received OMCI messages
1475 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1476 // send shall return (dual format) error code that can be used here for immediate error treatment
1477 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001478 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001479 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001480 }
1481 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001482 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001483 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001484 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001486 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001487 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001488 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001489 go func(a_pBaseFsm *fsm.FSM) {
1490 _ = a_pBaseFsm.Event(vlanEvReset)
1491 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001492 return
1493 }
1494 }
mpagenkof1d21d12021-06-11 13:14:45 +00001495
mpagenkof1fc3862021-02-16 10:09:52 +00001496 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001497 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001498 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001499 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001500 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001501 configuredUniFlow := oFsm.configuredUniFlow
mpagenko7a592192021-07-28 13:32:00 +00001502 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001503 oFsm.mutexFlowParams.RUnlock()
1504 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001505 //This is correct passing scenario
1506 if errEvto == nil {
1507 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001509 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001510 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001511 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001512 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001513 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001514 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001516 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001518 log.Fields{"device-id": oFsm.deviceID})
1519 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1520 }
1521 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001522 //If this incremental flow contains a meter, then create TD for related gems.
1523 if oFsm.actualUniVlanConfigMeter != nil {
1524 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1525 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1526 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1527 oFsm.pOnuUniPort.uniID, gemPort)
1528 if errCreateTrafficDescriptor != nil {
1529 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1530 log.Fields{"device-id": oFsm.deviceID})
1531 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1532 }
1533 }
1534 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001535 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1536 }
1537 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001538}
1539
dbainbri4d3a0dc2020-12-02 00:33:42 +00001540func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001541 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001543 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1544 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001545
mpagenkofc4f56e2020-11-04 17:17:49 +00001546 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001547 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001548 loVlanEntryClear := uint8(0)
1549 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1550 //shallow copy is sufficient as no reference variables are used within struct
1551 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001552 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001553 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001554 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1555 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1556 "device-id": oFsm.deviceID})
1557
1558 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1559 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001561 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1562 } else {
1563 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1564 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001565 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001566 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1567 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001568 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001569 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001570 "device-id": oFsm.deviceID,
1571 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001572 loVlanEntryClear = 1 //full VlanFilter clear request
1573 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001574 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001575 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001576 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001577 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001578 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001579 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1580 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1581 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1582 return
1583 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001584 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001585 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001586 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001587 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001588 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001589 }
mpagenko01e726e2020-10-23 09:45:29 +00001590 } else {
1591 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1592 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001594 log.Fields{"current vlan list": oFsm.vlanFilterList,
1595 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1596 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1597 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1598 loVlanEntryRmPos = i
1599 break //abort search
1600 }
1601 }
1602 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001603 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001604 //valid entry was found - to be eclipsed
1605 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1606 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1607 if i < loVlanEntryRmPos {
1608 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1609 } else if i < (cVtfdTableSize - 1) {
1610 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1611 } else {
1612 vtfdFilterList[i] = 0 //set last byte if needed
1613 }
1614 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001615 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001616 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001617 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1618 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001619
mpagenkofc4f56e2020-11-04 17:17:49 +00001620 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001621 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001622 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001623 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001624 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001625 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001626 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001627 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1628 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1629 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1630 return
1631 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001632 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001633 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001634 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001635 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001636 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001637 }
mpagenko01e726e2020-10-23 09:45:29 +00001638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001639 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001640 log.Fields{"device-id": oFsm.deviceID})
1641 }
1642 }
1643 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001644 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1645 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001647 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001648 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001649 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001650 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001651 go func(a_pBaseFsm *fsm.FSM) {
1652 _ = a_pBaseFsm.Event(vlanEvReset)
1653 }(pConfigVlanStateBaseFsm)
1654 return
1655 }
mpagenko01e726e2020-10-23 09:45:29 +00001656 }
1657
mpagenko15ff4a52021-03-02 10:09:20 +00001658 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001659 if loVlanEntryClear == 1 {
1660 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1661 oFsm.numVlanFilterEntries = 0
1662 } else if loVlanEntryClear == 2 {
1663 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1664 // this loop now includes the 0 element on previous last valid entry
1665 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1666 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1667 }
1668 oFsm.numVlanFilterEntries--
1669 }
mpagenko15ff4a52021-03-02 10:09:20 +00001670 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001671 }
1672 }
1673
mpagenkofc4f56e2020-11-04 17:17:49 +00001674 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001676 } else {
1677 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001679 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001680 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001682 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001683 }(pConfigVlanStateBaseFsm)
1684 }
mpagenkodff5dda2020-08-28 11:52:01 +00001685}
1686
dbainbri4d3a0dc2020-12-02 00:33:42 +00001687func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001688 var tpID uint8
1689 // Extract the tpID
1690 if len(e.Args) > 0 {
1691 tpID = e.Args[0].(uint8)
1692 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1693 } else {
1694 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1695 }
mpagenko01e726e2020-10-23 09:45:29 +00001696 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001697 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001698
mpagenkof582d6a2021-06-18 15:58:10 +00001699 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1700 if pConfigVlanStateAFsm == nil {
1701 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1702 log.Fields{"device-id": oFsm.deviceID})
1703 //would have to be fixed from outside somehow
1704 return
1705 }
1706
mpagenkof1d21d12021-06-11 13:14:45 +00001707 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1708 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001709 //call from 'configured' state of the rule
1710 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1711 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1712 oFsm.mutexFlowParams.Unlock()
1713 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
1714 go func(a_pAFsm *AdapterFsm) {
1715 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1716 }(pConfigVlanStateAFsm)
1717 return
1718 }
mpagenkof1d21d12021-06-11 13:14:45 +00001719 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1720 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1721 oFsm.mutexFlowParams.Unlock()
1722 removeChannel <- true
1723 oFsm.mutexFlowParams.Lock()
1724 }
1725
mpagenkof1fc3862021-02-16 10:09:52 +00001726 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1727 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1728 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1729
mpagenko01e726e2020-10-23 09:45:29 +00001730 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1731 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001732 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001733 "device-id": oFsm.deviceID})
1734 } else {
1735 //cut off the actual flow by slicing out the first element
1736 oFsm.uniRemoveFlowsSlice = append(
1737 oFsm.uniRemoveFlowsSlice[:0],
1738 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001740 "device-id": oFsm.deviceID})
1741 }
1742 oFsm.mutexFlowParams.Unlock()
1743
mpagenkof1fc3862021-02-16 10:09:52 +00001744 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001745 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001746 // Can't call FSM Event directly, decoupling it
1747 go func(a_pAFsm *AdapterFsm) {
1748 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
1749 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001750
mpagenkobb47bc22021-04-20 13:29:09 +00001751 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001752 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001753 if deletedCookie == oFsm.delayNewRuleCookie {
1754 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1755 select {
1756 case <-oFsm.chCookieDeleted:
1757 logger.Debug(ctx, "flushed CookieDeleted")
1758 default:
1759 }
1760 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1761 }
mpagenkobb47bc22021-04-20 13:29:09 +00001762 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1763 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1764 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 -08001765 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001766 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1767 oFsm.flowDeleteChannel <- true
1768 oFsm.signalOnFlowDelete = false
1769 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001770 }
mpagenkobb47bc22021-04-20 13:29:09 +00001771 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001772}
1773
dbainbri4d3a0dc2020-12-02 00:33:42 +00001774func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1775 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001776
1777 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1778 if pConfigVlanStateAFsm != nil {
1779 // abort running message processing
1780 fsmAbortMsg := Message{
1781 Type: TestMsg,
1782 Data: TestMessage{
1783 TestMessageVal: AbortMessageProcessing,
1784 },
1785 }
1786 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1787
mpagenko9a304ea2020-12-16 15:54:01 +00001788 //try to restart the FSM to 'disabled'
1789 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001790 go func(a_pAFsm *AdapterFsm) {
1791 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301792 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001793 }
1794 }(pConfigVlanStateAFsm)
1795 }
1796}
1797
dbainbri4d3a0dc2020-12-02 00:33:42 +00001798func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1799 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001800 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001801 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001802 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001803
1804 oFsm.mutexFlowParams.RLock()
1805 if oFsm.delayNewRuleCookie != 0 {
1806 // looks like the waiting AddFlow is stuck
1807 oFsm.mutexFlowParams.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00001808 oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
mpagenkof1d21d12021-06-11 13:14:45 +00001809 oFsm.mutexFlowParams.RLock()
1810 }
1811 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1812 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1813 if removeUniFlowParams.isSuspendedOnAdd {
1814 removeChannel := removeUniFlowParams.removeChannel
1815 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1816 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1817 oFsm.mutexFlowParams.RUnlock()
1818 removeChannel <- false
1819 oFsm.mutexFlowParams.RLock()
1820 }
1821 }
1822 }
1823
mpagenkodff5dda2020-08-28 11:52:01 +00001824 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001825 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1826 // current code removes the complete FSM including all flow/rule configuration done so far
1827 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1828 // maybe a more sophisticated approach is possible without clearing the data
1829 if oFsm.clearPersistency {
1830 //permanently remove possibly stored persistent data
1831 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1832 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001833 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001834 }
1835 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001836 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001837 }
mpagenko9a304ea2020-12-16 15:54:01 +00001838 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001839 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001840 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001841 return
mpagenkodff5dda2020-08-28 11:52:01 +00001842 }
mpagenkof1d21d12021-06-11 13:14:45 +00001843 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001844}
1845
dbainbri4d3a0dc2020-12-02 00:33:42 +00001846func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1847 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001848loop:
1849 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001850 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001851 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001852 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301853 message, ok := <-oFsm.pAdaptFsm.commChan
1854 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301856 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1857 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1858 break loop
1859 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301861
1862 switch message.Type {
1863 case TestMsg:
1864 msg, _ := message.Data.(TestMessage)
1865 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001867 break loop
1868 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301870 case OMCI:
1871 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001872 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301873 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001874 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301875 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001876 }
1877 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001879}
1880
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1882 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001883 "msgType": msg.OmciMsg.MessageType})
1884
1885 switch msg.OmciMsg.MessageType {
1886 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001887 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1889 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001890 return
1891 }
mpagenkodff5dda2020-08-28 11:52:01 +00001892 } //CreateResponseType
1893 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001894 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001895 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1896 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001898 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001899 return
1900 }
1901 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1902 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001903 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001904 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001905 return
1906 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001908 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001909 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001910 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001911 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1912 return
1913 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001914 oFsm.mutexPLastTxMeInstance.RLock()
1915 if oFsm.pLastTxMeInstance != nil {
1916 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1917 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1918 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001919 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001920 { // let the MultiEntity config proceed by stopping the wait function
1921 oFsm.mutexPLastTxMeInstance.RUnlock()
1922 oFsm.omciMIdsResponseReceived <- true
1923 return
1924 }
1925 default:
1926 {
1927 logger.Warnw(ctx, "Unsupported ME name received!",
1928 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1929 }
mpagenkodff5dda2020-08-28 11:52:01 +00001930 }
1931 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001932 } else {
1933 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001934 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001935 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001936 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001937 case omci.DeleteResponseType:
1938 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1940 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001941 return
1942 }
1943 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001944 default:
1945 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001947 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001948 return
1949 }
1950 }
1951}
1952
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001954 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1955 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001957 log.Fields{"device-id": oFsm.deviceID})
1958 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1959 oFsm.deviceID)
1960 }
1961 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1962 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001964 log.Fields{"device-id": oFsm.deviceID})
1965 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1966 oFsm.deviceID)
1967 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001968 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001969 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001971 "Error": msgObj.Result})
1972 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1973 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1974 oFsm.deviceID)
1975 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001976 oFsm.mutexPLastTxMeInstance.RLock()
1977 if oFsm.pLastTxMeInstance != nil {
1978 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1979 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1980 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1981 switch oFsm.pLastTxMeInstance.GetName() {
1982 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1983 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03001984 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001985 {
1986 oFsm.mutexPLastTxMeInstance.RUnlock()
1987 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1988 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1989 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1990 } else { // let the MultiEntity config proceed by stopping the wait function
1991 oFsm.omciMIdsResponseReceived <- true
1992 }
1993 return nil
1994 }
1995 default:
1996 {
1997 logger.Warnw(ctx, "Unsupported ME name received!",
1998 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001999 }
2000 }
2001 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002002 } else {
2003 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002004 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002005 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002006 return nil
2007}
2008
dbainbri4d3a0dc2020-12-02 00:33:42 +00002009func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002010 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2011 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002013 log.Fields{"device-id": oFsm.deviceID})
2014 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2015 oFsm.deviceID)
2016 }
2017 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2018 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002020 log.Fields{"device-id": oFsm.deviceID})
2021 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2022 oFsm.deviceID)
2023 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002024 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002025 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002027 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2028 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2029 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2030 oFsm.deviceID)
2031 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002032 oFsm.mutexPLastTxMeInstance.RLock()
2033 if oFsm.pLastTxMeInstance != nil {
2034 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2035 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2036 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002037 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002038 { // let the MultiEntity config proceed by stopping the wait function
2039 oFsm.mutexPLastTxMeInstance.RUnlock()
2040 oFsm.omciMIdsResponseReceived <- true
2041 return nil
2042 }
2043 default:
2044 {
2045 logger.Warnw(ctx, "Unsupported ME name received!",
2046 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2047 }
mpagenko01e726e2020-10-23 09:45:29 +00002048 }
2049 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002050 } else {
2051 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002052 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002053 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002054 return nil
2055}
2056
dbainbri4d3a0dc2020-12-02 00:33:42 +00002057func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002058 oFsm.mutexFlowParams.RLock()
2059 evtocdID := oFsm.evtocdID
2060 oFsm.mutexFlowParams.RUnlock()
2061
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002062 if aFlowEntryNo == 0 {
2063 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002064 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2065 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002066 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002067 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002068 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002069 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002070 associationType := 2 // default to uniPPTP
2071 if oFsm.pOnuUniPort.portType == uniVEIP {
2072 associationType = 10
2073 }
2074 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002075 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002076 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002077 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002078 "AssociationType": uint8(associationType),
2079 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002080 },
2081 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002082 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002083 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
2084 true, oFsm.pAdaptFsm.commChan, meParams)
2085 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002086 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002087 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2088 log.Fields{"device-id": oFsm.deviceID})
2089 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2090 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2091 }
mpagenkodff5dda2020-08-28 11:52:01 +00002092 //accept also nil as (error) return value for writing to LastTx
2093 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002094 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002095 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002096
2097 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002098 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002099 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002100 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002101 log.Fields{"device-id": oFsm.deviceID})
2102 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2103 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2104 }
2105
2106 // Set the EVTOCD ME default params
2107 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002108 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002109 Attributes: me.AttributeValueMap{
2110 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2111 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2112 "DownstreamMode": uint8(cDefaultDownstreamMode),
2113 },
2114 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002115 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002116 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2117 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002118 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002119 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002120 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002121 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2122 log.Fields{"device-id": oFsm.deviceID})
2123 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2124 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2125 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002126 //accept also nil as (error) return value for writing to LastTx
2127 // - this avoids misinterpretation of new received OMCI messages
2128 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002129 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002130
2131 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002132 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002133 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002134 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002135 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302136 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002137 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002138 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002139 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002140
mpagenko551a4d42020-12-08 18:09:20 +00002141 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002142 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002143 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002144 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002145 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002146 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002147 sliceEvtocdRule := make([]uint8, 16)
2148 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2149 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2150 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2151 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2152 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2153
2154 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2155 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2156 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2157 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2158 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2159
2160 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2161 0<<cTreatTTROffset| // Do not pop any tags
2162 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2163 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2164 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2165
2166 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2167 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2168 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2169 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2170
2171 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002172 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002173 Attributes: me.AttributeValueMap{
2174 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2175 },
2176 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002177 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002178 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2179 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002180 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002181 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002182 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002183 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2184 log.Fields{"device-id": oFsm.deviceID})
2185 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2186 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2187 }
mpagenkodff5dda2020-08-28 11:52:01 +00002188 //accept also nil as (error) return value for writing to LastTx
2189 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002190 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002191 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002192
2193 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002194 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002195 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002196 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002197 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302198 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002199 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2200
mpagenkodff5dda2020-08-28 11:52:01 +00002201 }
2202 } else {
2203 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2204 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002205 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2206 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2207 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2208 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002209 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002210 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002211 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002212 sliceEvtocdRule := make([]uint8, 16)
2213 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2214 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2215 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2216 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2217 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2218
2219 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002220 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2221 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002222 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2223 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2224
2225 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002226 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002227 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2228 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2229 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2230
2231 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002232 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2233 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002234 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002235 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002236
2237 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002238 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002239 Attributes: me.AttributeValueMap{
2240 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2241 },
2242 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002243 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002244 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2245 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002246 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002247 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002248 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002249 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2250 log.Fields{"device-id": oFsm.deviceID})
2251 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2252 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2253 }
mpagenkodff5dda2020-08-28 11:52:01 +00002254 //accept also nil as (error) return value for writing to LastTx
2255 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002256 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002257 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002258
2259 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002260 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002261 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002263 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302264 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002265 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002266 }
2267 } else {
2268 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2269 { // just for local var's
2270 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002271 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002272 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002273 sliceEvtocdRule := make([]uint8, 16)
2274 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2275 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2276 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2277 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2278 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2279
2280 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2281 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2282 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2283 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2284 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2285
2286 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2287 0<<cTreatTTROffset| // Do not pop any tags
2288 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2289 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2290 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2291
2292 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2293 0<<cTreatPrioOffset| // vlan prio set to 0
2294 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002295 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002296 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2297
mpagenko551a4d42020-12-08 18:09:20 +00002298 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002299 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002300 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002301 Attributes: me.AttributeValueMap{
2302 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2303 },
2304 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002305 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002306 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2307 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002308 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002309 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002310 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002311 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2312 log.Fields{"device-id": oFsm.deviceID})
2313 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2314 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2315 }
mpagenkodff5dda2020-08-28 11:52:01 +00002316 //accept also nil as (error) return value for writing to LastTx
2317 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002318 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002319 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002320
2321 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002322 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002323 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002324 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002325 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302326 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002327 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2328
mpagenkodff5dda2020-08-28 11:52:01 +00002329 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002330 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002331 { // just for local var's
2332 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002334 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002335 sliceEvtocdRule := make([]uint8, 16)
2336 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2337 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2338 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2339 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2340 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2341
2342 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2343 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2344 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2345 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2346 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2347
2348 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2349 1<<cTreatTTROffset| // pop the prio-tag
2350 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2351 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2352 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2353
mpagenko551a4d42020-12-08 18:09:20 +00002354 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002355 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2356 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2357 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002358 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002359 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002360 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002361
2362 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002363 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002364 Attributes: me.AttributeValueMap{
2365 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2366 },
2367 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002368 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002369 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2370 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002371 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002372 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002373 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002374 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2375 log.Fields{"device-id": oFsm.deviceID})
2376 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2377 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2378 }
mpagenkodff5dda2020-08-28 11:52:01 +00002379 //accept also nil as (error) return value for writing to LastTx
2380 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002381 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002382 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002383
2384 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002385 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002386 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002387 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002388 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302389 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002390 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2391
mpagenkodff5dda2020-08-28 11:52:01 +00002392 }
2393 } //just for local var's
2394 }
2395 }
2396
mpagenkofc4f56e2020-11-04 17:17:49 +00002397 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002398 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002399 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002400 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002401 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002402 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002403}
2404
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002406 oFsm.mutexFlowParams.RLock()
2407 evtocdID := oFsm.evtocdID
2408 oFsm.mutexFlowParams.RUnlock()
2409
mpagenko01e726e2020-10-23 09:45:29 +00002410 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2411 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2412 //transparent transmission was set
2413 //perhaps the config is not needed for removal,
2414 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002415 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002416 "device-id": oFsm.deviceID})
2417 sliceEvtocdRule := make([]uint8, 16)
2418 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2419 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2420 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2421 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2422 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2423
2424 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2425 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2426 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2427 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2428 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2429
2430 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2431 0<<cTreatTTROffset| // Do not pop any tags
2432 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2433 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2434 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2435
2436 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2437 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2438 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2439 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2440
2441 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002442 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002443 Attributes: me.AttributeValueMap{
2444 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2445 },
2446 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002447 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002448 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2449 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002450 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002451 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002452 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002453 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2454 log.Fields{"device-id": oFsm.deviceID})
2455 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2456 return
2457 }
mpagenko01e726e2020-10-23 09:45:29 +00002458 //accept also nil as (error) return value for writing to LastTx
2459 // - this avoids misinterpretation of new received OMCI messages
2460 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002461 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002462
2463 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002464 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002465 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002466 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002467 log.Fields{"device-id": oFsm.deviceID})
2468 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2469 return
2470 }
2471 } else {
2472 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002473 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002474 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002475 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002476 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002477 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002478 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2479 sliceEvtocdRule := make([]uint8, 16)
2480 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2481 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2482 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2483 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2484 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2485
2486 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2487 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2488 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2489 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2490 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2491
2492 // delete indication for the indicated Filter
2493 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2494 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2495
2496 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002497 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002498 Attributes: me.AttributeValueMap{
2499 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2500 },
2501 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002502 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002503 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2504 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002505 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002506 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002507 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002508 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2509 log.Fields{"device-id": oFsm.deviceID})
2510 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2511 return
2512 }
mpagenko01e726e2020-10-23 09:45:29 +00002513 //accept also nil as (error) return value for writing to LastTx
2514 // - this avoids misinterpretation of new received OMCI messages
2515 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002516 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002517
2518 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002519 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002520 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002521 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002522 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2523 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2524 return
2525 }
2526 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002527 // VOL-3685
2528 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2529 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2530 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2531 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2532 // later when the flow is being re-installed.
2533 // Of course this is applicable to case only where single service (or single tcont) is in use and
2534 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2535 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2536 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002537 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2538 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002540 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2541 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002542 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002543 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002544 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002545 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002546 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2547 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002548 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002549 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002550 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002551 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2552 log.Fields{"device-id": oFsm.deviceID})
2553 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2554 return
2555 }
mpagenko01e726e2020-10-23 09:45:29 +00002556 //accept also nil as (error) return value for writing to LastTx
2557 // - this avoids misinterpretation of new received OMCI messages
2558 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002559 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002560
2561 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002562 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002563 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002564 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002565 log.Fields{"device-id": oFsm.deviceID})
2566 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2567 return
2568 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002569 } else {
2570 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2571 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002572 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002573 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002574 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002575 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2576 { // just for local var's
2577 // this defines stacking scenario: untagged->singletagged
2578 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2579 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2580 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2581 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002582 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002583 "device-id": oFsm.deviceID})
2584 sliceEvtocdRule := make([]uint8, 16)
2585 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2586 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2587 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2588 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2589 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002590
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002591 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2592 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2593 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2594 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2595 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002596
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002597 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2598 0<<cTreatTTROffset| // Do not pop any tags
2599 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2600 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2601 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002602
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002603 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2604 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2605 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2606 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002607
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002608 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002609 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002610 Attributes: me.AttributeValueMap{
2611 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2612 },
2613 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002614 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002615 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2616 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002618 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002619 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002620 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2621 log.Fields{"device-id": oFsm.deviceID})
2622 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2623 return
2624 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002625 //accept also nil as (error) return value for writing to LastTx
2626 // - this avoids misinterpretation of new received OMCI messages
2627 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002628 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002629
2630 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002631 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002632 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002633 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002634 log.Fields{"device-id": oFsm.deviceID})
2635 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2636 return
2637 }
2638 } // just for local var's
2639 { // just for local var's
2640 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002641 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002642 "device-id": oFsm.deviceID})
2643 sliceEvtocdRule := make([]uint8, 16)
2644 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2645 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2646 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2647 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2648 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2649
2650 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2651 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2652 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2653 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2654 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2655
2656 // delete indication for the indicated Filter
2657 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2658 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2659
2660 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002661 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002662 Attributes: me.AttributeValueMap{
2663 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2664 },
2665 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002666 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002667 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2668 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002669 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002670 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002671 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002672 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2673 log.Fields{"device-id": oFsm.deviceID})
2674 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2675 return
2676 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002677 //accept also nil as (error) return value for writing to LastTx
2678 // - this avoids misinterpretation of new received OMCI messages
2679 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002680 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002681
2682 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002683 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002684 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002685 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002686 log.Fields{"device-id": oFsm.deviceID})
2687 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2688 return
2689 }
mpagenko01e726e2020-10-23 09:45:29 +00002690 }
2691 } //just for local var's
2692 }
2693 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002694 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002695 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002696 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002697}
2698
dbainbri4d3a0dc2020-12-02 00:33:42 +00002699func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002700 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002701 if oFsm.isCanceled {
2702 // FSM already canceled before entering wait
2703 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2704 oFsm.mutexIsAwaitingResponse.Unlock()
2705 return fmt.Errorf(cErrWaitAborted)
2706 }
mpagenko7d6bb022021-03-11 15:07:55 +00002707 oFsm.isAwaitingResponse = true
2708 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002709 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302710 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002711 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002712 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002713 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002714 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002715 oFsm.mutexIsAwaitingResponse.Lock()
2716 oFsm.isAwaitingResponse = false
2717 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002718 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002719 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302720 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002721 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002722 oFsm.mutexIsAwaitingResponse.Lock()
2723 oFsm.isAwaitingResponse = false
2724 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002725 return nil
2726 }
mpagenko7d6bb022021-03-11 15:07:55 +00002727 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002728 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002729 oFsm.mutexIsAwaitingResponse.Lock()
2730 oFsm.isAwaitingResponse = false
2731 oFsm.mutexIsAwaitingResponse.Unlock()
2732 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002733 }
2734}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002735
mpagenko551a4d42020-12-08 18:09:20 +00002736func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002737 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002738 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002739 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002740 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002741 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002742 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002743 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002744 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2745 }
2746
dbainbri4d3a0dc2020-12-02 00:33:42 +00002747 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002748 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002749 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002750 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002751 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002752 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2753 }
2754
dbainbri4d3a0dc2020-12-02 00:33:42 +00002755 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002756 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002757 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002758 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002759 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002760 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2761 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002762 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2763 if errMacBpCdEID != nil {
2764 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2765 log.Fields{"device-id": oFsm.deviceID})
2766 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2767 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002768
Mahir Gunyel6781f962021-05-16 23:30:08 -07002769 }
2770 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2771 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2772 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002773 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002774 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002775 Attributes: me.AttributeValueMap{
2776 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2777 "PortNum": 0xf0, //fixed unique ANI side indication
2778 "TpType": 6, //MCGemIWTP
2779 "TpPointer": multicastGemPortID,
2780 },
2781 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002782 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002783 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2784 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2785 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002786 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002787 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2788 log.Fields{"device-id": oFsm.deviceID})
2789 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2790 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2791 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002792 //accept also nil as (error) return value for writing to LastTx
2793 // - this avoids misinterpretation of new received OMCI messages
2794 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002795 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002796 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002797 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002799 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002800 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002801 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2802 }
2803
2804 // ==> Start creating VTFD for mcast vlan
2805
2806 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2807 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002808 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002809
dbainbri4d3a0dc2020-12-02 00:33:42 +00002810 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002811 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2812 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2813 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2814
2815 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2816 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2817 // new vlan associated with a different TP.
2818 vtfdFilterList[0] = uint16(vlanID)
2819
2820 meParams = me.ParamData{
2821 EntityID: mcastVtfdID,
2822 Attributes: me.AttributeValueMap{
2823 "VlanFilterList": vtfdFilterList,
2824 "ForwardOperation": uint8(0x10), //VID investigation
2825 "NumberOfEntries": oFsm.numVlanFilterEntries,
2826 },
2827 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002828 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002829 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2830 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2831 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002832 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002833 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2834 log.Fields{"device-id": oFsm.deviceID})
2835 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2836 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2837 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002838 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002839 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002840 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002841 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002842 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002844 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2846 }
2847
2848 return nil
2849}
2850
dbainbri4d3a0dc2020-12-02 00:33:42 +00002851func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002852 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002853 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002854 logger.Errorw(ctx, "error generrating me instance id",
2855 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002856 return err
2857 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002858 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2859 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860 meParams := me.ParamData{
2861 EntityID: instID,
2862 Attributes: me.AttributeValueMap{
2863 "MeType": 0,
2864 //Direct reference to the Operation profile
2865 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002866 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867 },
2868 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002869 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002870 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2871 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002872 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002873 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002874 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002875 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2876 log.Fields{"device-id": oFsm.deviceID})
2877 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2878 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2879 oFsm.deviceID, err)
2880 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002881 //accept also nil as (error) return value for writing to LastTx
2882 // - this avoids misinterpretation of new received OMCI messages
2883 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002884 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002885 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002886 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002887 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002888 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002889 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2890 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2891 }
2892 return nil
2893}
2894
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002896 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002897 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002898 logger.Errorw(ctx, "error generating me instance id",
2899 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002900 return err
2901 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002902 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2903 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002904 meParams := me.ParamData{
2905 EntityID: instID,
2906 Attributes: me.AttributeValueMap{
2907 "IgmpVersion": 2,
2908 "IgmpFunction": 0,
2909 //0 means false
2910 "ImmediateLeave": 0,
2911 "Robustness": 2,
2912 "QuerierIp": 0,
2913 "QueryInterval": 125,
2914 "QuerierMaxResponseTime": 100,
2915 "LastMemberResponseTime": 10,
2916 //0 means false
2917 "UnauthorizedJoinBehaviour": 0,
2918 },
2919 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002920 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002921 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2922 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002923 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002924 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002925 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002926 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2927 log.Fields{"device-id": oFsm.deviceID})
2928 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2929 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2930 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002931 //accept also nil as (error) return value for writing to LastTx
2932 // - this avoids misinterpretation of new received OMCI messages
2933 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002934 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002935 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002936 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002937 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002938 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002939 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002940 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002941 }
2942 return nil
2943}
2944
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002946 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002947 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002948 logger.Errorw(ctx, "error generating me instance id",
2949 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002950 return err
2951 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002952 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2953 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002954 //TODO check that this is correct
2955 // Table control
2956 //setCtrl = 1
2957 //rowPartId = 0
2958 //test = 0
2959 //rowKey = 0
2960 tableCtrlStr := "0100000000000000"
2961 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002962 dynamicAccessCL := make([]uint8, 24)
2963 copy(dynamicAccessCL, tableCtrl)
2964 //Multicast GemPortId
2965 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2966 // python version waits for installation of flows, see line 723 onward of
2967 // brcm_openomci_onu_handler.py
2968 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2969 //Source IP all to 0
2970 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2971 //TODO start and end are hardcoded, get from TP
2972 // Destination IP address start of range
2973 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2974 // Destination IP address end of range
2975 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2976 //imputed group bandwidth
2977 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2978
2979 meParams := me.ParamData{
2980 EntityID: instID,
2981 Attributes: me.AttributeValueMap{
2982 "DynamicAccessControlListTable": dynamicAccessCL,
2983 },
2984 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002985 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002986 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2987 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002988 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002989 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002990 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002991 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2992 log.Fields{"device-id": oFsm.deviceID})
2993 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2994 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2995 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002996 //accept also nil as (error) return value for writing to LastTx
2997 // - this avoids misinterpretation of new received OMCI messages
2998 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002999 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003000 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003001 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003002 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003003 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003004 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003005 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003006 }
3007 return nil
3008}
Girish Gowdra26a40922021-01-29 17:14:34 -08003009
ozgecanetsia82b91a62021-05-21 18:54:49 +03003010func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3011 tpID uint8, uniID uint8, gemPortID uint16) error {
3012 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3013 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3014 // I created unique TD ID by flow direction.
3015 // TODO! Traffic descriptor ME ID will check
3016 trafficDescriptorID := gemPortID
3017 if aMeter == nil {
3018 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3019 }
3020 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3021 if err != nil {
3022 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3023 return err
3024 }
3025 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3026 cbs := trafficShapingInfo.Cbs
3027 pir := trafficShapingInfo.Pir
3028 pbs := trafficShapingInfo.Pbs
3029
3030 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3031 meParams := me.ParamData{
3032 EntityID: trafficDescriptorID,
3033 Attributes: me.AttributeValueMap{
3034 "Cir": cir,
3035 "Pir": pir,
3036 "Cbs": cbs,
3037 "Pbs": pbs,
3038 "ColourMode": 1,
3039 "IngressColourMarking": 3,
3040 "EgressColourMarking": 3,
3041 "MeterType": 1,
3042 },
3043 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003044 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003045 meInstance, errCreateTD := oFsm.pOmciCC.sendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
3046 true, oFsm.pAdaptFsm.commChan, meParams)
3047 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003048 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003049 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3050 return err
3051 }
3052 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003053 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003054 err = oFsm.waitforOmciResponse(ctx)
3055 if err != nil {
3056 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3057 return err
3058 }
3059
3060 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID)
3061 if err != nil {
3062 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3063 return err
3064 }
3065 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3066
3067 return nil
3068}
3069
3070func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortID uint16) error {
3071 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID})
3072 meParams := me.ParamData{
3073 EntityID: gemPortID,
3074 Attributes: me.AttributeValueMap{
3075 "TrafficManagementPointerForUpstream": gemPortID,
3076 },
3077 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003078 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003079 meInstance, err := oFsm.pOmciCC.sendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3080 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
3081 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003082 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003083 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3084 return err
3085 }
3086 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003087 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003088 err = oFsm.waitforOmciResponse(ctx)
3089 if err != nil {
3090 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3091 return err
3092 }
3093 return nil
3094}
3095
Girish Gowdra26a40922021-01-29 17:14:34 -08003096// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00003097func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
3098 oFsm.mutexFlowParams.Lock()
3099 defer oFsm.mutexFlowParams.Unlock()
3100 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3101 //flow removal is still ongoing/pending
3102 oFsm.signalOnFlowDelete = true
3103 oFsm.flowDeleteChannel = aFlowDeleteChannel
3104 return true
3105 }
3106 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003107}