blob: d541ffd8460691259bec25aa55fa583e9f144c6f [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"
Andrea Campanella6515c582020-10-05 11:25:00 +020023 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030024 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000025 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000026 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000027 "time"
28
mpagenko01e726e2020-10-23 09:45:29 +000029 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000030 "github.com/looplab/fsm"
31 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/log"
34 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000035)
36
37const (
38 // internal predefined values
mpagenkof1fc3862021-02-16 10:09:52 +000039 cWaitForCookieDeletion = 3 //seconds
mpagenkodff5dda2020-08-28 11:52:01 +000040 cDefaultDownstreamMode = 0
41 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000042 cVtfdTableSize = 12 //as per G.988
43 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000044)
45
46const (
mpagenkof1fc3862021-02-16 10:09:52 +000047 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
48 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
49 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
50 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
51 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
52)
53
54const (
mpagenkodff5dda2020-08-28 11:52:01 +000055 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
56 cFilterPrioOffset = 28
57 cFilterVidOffset = 15
58 cFilterTpidOffset = 12
59 cFilterEtherTypeOffset = 0
60 cTreatTTROffset = 30
61 cTreatPrioOffset = 16
62 cTreatVidOffset = 3
63 cTreatTpidOffset = 0
64)
65const (
66 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
67 cFilterOuterOffset = 0
68 cFilterInnerOffset = 4
69 cTreatOuterOffset = 8
70 cTreatInnerOffset = 12
71)
72const (
73 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
74 cPrioIgnoreTag uint32 = 15
75 cPrioDefaultFilter uint32 = 14
76 cPrioDoNotFilter uint32 = 8
77 cDoNotFilterVid uint32 = 4096
78 cDoNotFilterTPID uint32 = 0
79 cDoNotFilterEtherType uint32 = 0
80 cDoNotAddPrio uint32 = 15
81 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053082 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000083 cDontCareVid uint32 = 0
84 cDontCareTpid uint32 = 0
85 cSetOutputTpidCopyDei uint32 = 4
86)
87
88const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000089 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000090 vlanEvStart = "vlanEvStart"
91 vlanEvWaitTechProf = "vlanEvWaitTechProf"
92 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
93 vlanEvContinueConfig = "vlanEvContinueConfig"
94 vlanEvStartConfig = "vlanEvStartConfig"
95 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
96 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
97 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
98 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
99 vlanEvRenew = "vlanEvRenew"
100 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
101 vlanEvRemFlowDone = "vlanEvRemFlowDone"
102 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000103 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
104 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000105 vlanEvReset = "vlanEvReset"
106 vlanEvRestart = "vlanEvRestart"
107 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
108 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000109)
mpagenko01e726e2020-10-23 09:45:29 +0000110
mpagenkodff5dda2020-08-28 11:52:01 +0000111const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000112 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000113 vlanStDisabled = "vlanStDisabled"
114 vlanStStarting = "vlanStStarting"
115 vlanStWaitingTechProf = "vlanStWaitingTechProf"
116 vlanStConfigVtfd = "vlanStConfigVtfd"
117 vlanStConfigEvtocd = "vlanStConfigEvtocd"
118 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000119 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000120 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000121 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000122 vlanStCleanupDone = "vlanStCleanupDone"
123 vlanStResetting = "vlanStResetting"
124)
mpagenkof1fc3862021-02-16 10:09:52 +0000125const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
126const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000127
mpagenko01e726e2020-10-23 09:45:29 +0000128type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000129 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000130 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
131 MatchPcp uint32 `json:"match_pcp"`
132 TagsToRemove uint32 `json:"tags_to_remove"`
133 SetVid uint32 `json:"set_vid"`
134 SetPcp uint32 `json:"set_pcp"`
135}
136
137type uniVlanFlowParams struct {
138 CookieSlice []uint64 `json:"cookie_slice"`
139 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
140}
141
142type uniRemoveVlanFlowParams struct {
143 cookie uint64 //just the last cookie valid for removal
144 vlanRuleParams uniVlanRuleParams
145}
146
mpagenkodff5dda2020-08-28 11:52:01 +0000147//UniVlanConfigFsm defines the structure for the state machine to config the PON ANI ports of ONU UNI ports via OMCI
148type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000150 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530151 pOmciCC *omciCC
152 pOnuUniPort *onuUniPort
153 pUniTechProf *onuUniTechProf
154 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000155 requestEvent OnuDeviceEvent
156 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
157 pAdaptFsm *AdapterFsm
158 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000159 clearPersistency bool
mpagenko551a4d42020-12-08 18:09:20 +0000160 mutexFlowParams sync.RWMutex
mpagenkof1fc3862021-02-16 10:09:52 +0000161 chCookieDeleted chan bool //channel to indicate that a specificly indicated cookie was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000162 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000163 uniVlanFlowParamsSlice []uniVlanFlowParams
164 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000165 numUniFlows uint8 // expected number of flows should be less than 12
166 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000167 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000168 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000169 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000170 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000171 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000172 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000173 TpIDWaitingFor uint8
mpagenkof1fc3862021-02-16 10:09:52 +0000174 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
175 delayNewRuleCookie uint64
mpagenkodff5dda2020-08-28 11:52:01 +0000176}
177
mpagenko01e726e2020-10-23 09:45:29 +0000178//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
179// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000180func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000181 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000182 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
183 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000184 instFsm := &UniVlanConfigFsm{
185 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000186 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000187 pOmciCC: apDevOmciCC,
188 pOnuUniPort: apUniPort,
189 pUniTechProf: apUniTechProf,
190 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000191 requestEvent: aRequestEvent,
192 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000193 numUniFlows: 0,
194 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000195 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000196 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000197 }
198
mpagenko01e726e2020-10-23 09:45:29 +0000199 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000200 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000201 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000202 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000203 return nil
204 }
mpagenkodff5dda2020-08-28 11:52:01 +0000205 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
206 vlanStDisabled,
207 fsm.Events{
208 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
209 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000210 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000211 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
212 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
213 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000214 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
215 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000216 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
217 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
218 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
219 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000220 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
221 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
222 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000223 /*
224 {Name: vlanEvTimeoutSimple, Src: []string{
225 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
226 {Name: vlanEvTimeoutMids, Src: []string{
227 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
228 */
229 // exceptional treatment for all states except vlanStResetting
230 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000231 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000232 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000233 Dst: vlanStResetting},
234 // the only way to get to resource-cleared disabled state again is via "resseting"
235 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000236 // transitions for reconcile handling according to VOL-3834
237 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
238 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
239 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000240 },
mpagenkodff5dda2020-08-28 11:52:01 +0000241 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000242 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
243 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
244 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
245 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
246 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
247 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
248 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
249 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
250 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
251 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000252 },
253 )
254 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000255 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000256 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000257 return nil
258 }
259
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000261
dbainbri4d3a0dc2020-12-02 00:33:42 +0000262 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000263 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000264 return instFsm
265}
266
mpagenko01e726e2020-10-23 09:45:29 +0000267//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000268func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000269 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
270 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000271 TpID: aTpID,
272 MatchVid: uint32(aMatchVlan),
273 SetVid: uint32(aSetVlan),
274 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000275 }
276 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000277 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
278 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000279
mpagenko01e726e2020-10-23 09:45:29 +0000280 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000281 //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 +0000282 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000283 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
284 } else {
285 if !oFsm.acceptIncrementalEvtoOption {
286 //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 +0000287 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000288 }
289 }
290
mpagenko01e726e2020-10-23 09:45:29 +0000291 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000292 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000293 loRuleParams.TagsToRemove = 0 //no tag pop action
294 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
295 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000296 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
297 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
298 // might collide with NoMatchVid/CopyPrio(/setVid) setting
299 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000300 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301 }
302 }
mpagenko01e726e2020-10-23 09:45:29 +0000303
304 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
305 loFlowParams.CookieSlice = make([]uint64, 0)
306 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
307
308 //no mutex protection is required for initial access and adding the first flow is always possible
309 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
310 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000311 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000312 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
313 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
314 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
315 "SetPcp": loRuleParams.SetPcp,
316 "device-id": oFsm.deviceID})
317 oFsm.numUniFlows = 1
318 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
319
320 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000321 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000322 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000323 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000324 return err
325 }
326
327 return nil
328}
329
mpagenko551a4d42020-12-08 18:09:20 +0000330//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
331func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
332 //mutex protection is required for possible concurrent access to FSM members
333 oFsm.mutexFlowParams.RLock()
334 defer oFsm.mutexFlowParams.RUnlock()
335 return oFsm.TpIDWaitingFor
336}
337
mpagenko2418ab02020-11-12 12:58:06 +0000338//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
339func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
340 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000341 oFsm.mutexFlowParams.Lock()
342 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000343 oFsm.clearPersistency = aClear
344}
345
mpagenko01e726e2020-10-23 09:45:29 +0000346//SetUniFlowParams verifies on existence of flow parameters to be configured,
347// optionally udates the cookie list or appends a new flow if there is space
348// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000349// ignore complexity by now
350// nolint: gocyclo
351func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000352 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
353 loRuleParams := uniVlanRuleParams{
354 TpID: aTpID,
355 MatchVid: uint32(aMatchVlan),
356 SetVid: uint32(aSetVlan),
357 SetPcp: uint32(aSetPcp),
358 }
359 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
360 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
361 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
362
363 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
364 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
365 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
366 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
367 } else {
368 if !oFsm.acceptIncrementalEvtoOption {
369 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
370 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
371 }
372 }
373
374 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
375 // no prio/vid filtering requested
376 loRuleParams.TagsToRemove = 0 //no tag pop action
377 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
378 if loRuleParams.SetPcp == cCopyPrioFromInner {
379 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
380 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
381 // might collide with NoMatchVid/CopyPrio(/setVid) setting
382 // this was some precondition setting taken over from py adapter ..
383 loRuleParams.SetPcp = 0
384 }
385 }
386
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000387 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000388 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000389 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000390 //mutex protection is required for possible concurrent access to FSM members
391 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000392 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
393 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
394 // countable run time optimization (perhaps with including the hash in kvStore storage?)
395 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000396 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000397 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000398 "device-id": oFsm.deviceID})
399 var cookieMatch bool
400 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
401 cookieMatch = false
402 for _, cookie := range storedUniFlowParams.CookieSlice {
403 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000404 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000405 "device-id": oFsm.deviceID, "cookie": cookie})
406 cookieMatch = true
407 break //found new cookie - no further search for this requested cookie
408 }
409 }
410 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000411 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
412 if delayedCookie != 0 {
413 //a delay for adding the cookie to this rule is requested
414 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
415 oFsm.mutexFlowParams.Unlock()
416 oFsm.suspendNewRule(ctx)
417 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
418 oFsm.mutexFlowParams.Lock()
419 } else {
420 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
421 "device-id": oFsm.deviceID, "cookie": newCookie})
422 //as range works with copies of the slice we have to write to the original slice!!
423 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
424 newCookie)
425 flowCookieModify = true
426 }
mpagenko01e726e2020-10-23 09:45:29 +0000427 }
428 } //for all new cookies
429 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000430 }
431 }
mpagenkof1fc3862021-02-16 10:09:52 +0000432 oFsm.mutexFlowParams.Unlock()
433
434 if !flowEntryMatch { //it is (was) a new rule
435 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
436 requestAppendRule = true //default assumption here is that rule is to be appended
437 flowCookieModify = true //and that the the flow data base is to be updated
438 if delayedCookie != 0 { //it was suspended
439 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
440 }
441 }
442 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
443 if requestAppendRule {
444 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000445 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000446 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
447 loFlowParams.CookieSlice = make([]uint64, 0)
448 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
449 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000450 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000451 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
452 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
453 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800454 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000455 "device-id": oFsm.deviceID})
456
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000457 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000458 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
459
460 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
461 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
462 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
463 oFsm.mutexFlowParams.Unlock()
464 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
465 go func(a_pBaseFsm *fsm.FSM) {
466 _ = a_pBaseFsm.Event(vlanEvSkipOmciConfig)
467 }(pConfigVlanStateBaseFsm)
468 }
469 return nil
470 }
mpagenko01e726e2020-10-23 09:45:29 +0000471 // note: theoretical it would be possible to clear the same rule from the remove slice
472 // (for entries that have not yet been started with removal)
473 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
474 // 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 +0000475
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000476 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
477 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000478 if oFsm.configuredUniFlow == 0 {
479 // this is a restart with a complete new flow, we can re-use the initial flow config control
480 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000481 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000482 go func(a_pBaseFsm *fsm.FSM) {
483 _ = a_pBaseFsm.Event(vlanEvRenew)
484 }(pConfigVlanStateBaseFsm)
485 } else {
486 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000487 //store the actual rule that shall be worked upon in the following transient states
488 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000489 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000490 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000491 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
492 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000493 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
494 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
495 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
496
mpagenko551a4d42020-12-08 18:09:20 +0000497 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
498 if aTechProfDone {
499 // let the vlan processing continue with next rule
500 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
501 } else {
502 // set to waiting for Techprofile
503 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
504 }
505 }(pConfigVlanStateBaseFsm, loTechProfDone)
506 }
mpagenko01e726e2020-10-23 09:45:29 +0000507 } // if not in the appropriate state a new entry will be automatically considered later
508 // when the configDone state is reached
mpagenko15ff4a52021-03-02 10:09:20 +0000509 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000510 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000511 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000512 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000513 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000514 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
515 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000516 } else {
517 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000518 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000519 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000520 if oFsm.numUniFlows == oFsm.configuredUniFlow {
521 //all requested rules really have been configured
522 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000523 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000524 if oFsm.pDeviceHandler != nil {
525 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000526 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000527 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000528 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
529 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000530 }
531 } else {
532 // avoid device reason update as the rule config connected to this flow may still be in progress
533 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000534 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000535 log.Fields{"device-id": oFsm.deviceID,
536 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000537 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000538 }
539 }
mpagenko01e726e2020-10-23 09:45:29 +0000540
mpagenkof1fc3862021-02-16 10:09:52 +0000541 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000542 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000543 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000544 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
545 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000546 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000547 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000548 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000549 }
mpagenko15ff4a52021-03-02 10:09:20 +0000550 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000551 }
552 return nil
553}
554
mpagenkof1fc3862021-02-16 10:09:52 +0000555// VOL-3828 flow config sequence workaround ########### start ##########
556func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
557 //assumes mutexFlowParams.Lock() protection from caller!
558 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
559 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
560 // suspend check is done only of there is only one cookie in the request
561 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
562 newCookie := aCookieSlice[0]
563 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
564 for _, cookie := range storedUniFlowParams.CookieSlice {
565 if cookie == newCookie {
566 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
567 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
568 oFsm.delayNewRuleCookie = newCookie
569 return newCookie //found new cookie in some existing rule
570 }
571 } // for all stored cookies of the actual inspected rule
572 } //for all rules
573 }
574 return 0 //no delay requested
575}
576func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
577 oFsm.mutexFlowParams.RLock()
578 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
579 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
580 oFsm.mutexFlowParams.RUnlock()
581 select {
582 case <-oFsm.chCookieDeleted:
583 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
584 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
585 case <-time.After(time.Duration(cWaitForCookieDeletion) * time.Second):
586 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
587 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
588 }
589 oFsm.mutexFlowParams.Lock()
590 oFsm.delayNewRuleCookie = 0
591 oFsm.mutexFlowParams.Unlock()
592}
593func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
594 oFsm.mutexFlowParams.Lock()
595 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
596 oFsm.mutexFlowParams.Unlock()
597
598 if delayedCookie != 0 {
599 oFsm.suspendNewRule(ctx)
600 }
601 return delayedCookie
602}
603
604//returns flowModified, RuleAppendRequest
605func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
606 flowEntryMatch := false
607 oFsm.mutexFlowParams.Lock()
608 defer oFsm.mutexFlowParams.Unlock()
609 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
610 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
611 flowEntryMatch = true
612 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
613 "device-id": oFsm.deviceID})
614 cookieMatch := false
615 for _, cookie := range storedUniFlowParams.CookieSlice {
616 if cookie == aCookie {
617 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
618 "device-id": oFsm.deviceID, "cookie": cookie})
619 cookieMatch = true
620 break //found new cookie - no further search for this requested cookie
621 }
622 }
623 if !cookieMatch {
624 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
625 "device-id": oFsm.deviceID, "cookie": aCookie})
626 //as range works with copies of the slice we have to write to the original slice!!
627 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
628 aCookie)
629 return true, false //flowModified, NoRuleAppend
630 }
631 break // found rule - no further rule search
632 }
633 }
634 if !flowEntryMatch { //it is a new rule
635 return true, true //flowModified, RuleAppend
636 }
637 return false, false //flowNotModified, NoRuleAppend
638}
639
640// VOL-3828 flow config sequence workaround ########### end ##########
641
mpagenko01e726e2020-10-23 09:45:29 +0000642//RemoveUniFlowParams verifies on existence of flow cookie,
643// if found removes cookie from flow cookie list and if this is empty
644// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000645func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000646 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000647 flowCookieMatch := false
648 //mutex protection is required for possible concurrent access to FSM members
649 oFsm.mutexFlowParams.Lock()
650 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000651remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000652 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
653 for i, cookie := range storedUniFlowParams.CookieSlice {
654 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000655 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000656 "device-id": oFsm.deviceID, "cookie": cookie})
657 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000658 deletedCookie = aCookie
659 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000660 //remove the cookie from the cookie slice and verify it is getting empty
661 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000662 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
663 var cancelPendingConfig bool = false
664 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000665 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000666 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000667 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
mpagenko535d6ef2021-02-26 13:15:34 +0000668 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000669 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
mpagenko535d6ef2021-02-26 13:15:34 +0000670 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
671 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
672 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
673 log.Fields{"device-id": oFsm.deviceID})
674 cancelPendingConfig = true
675 } else {
676 //create a new element for the removeVlanFlow slice
677 loRemoveParams = uniRemoveVlanFlowParams{
678 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
679 cookie: aCookie,
680 }
681 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000682 }
mpagenko01e726e2020-10-23 09:45:29 +0000683
684 //and remove the actual element from the addVlanFlow slice
685 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
686 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
687 oFsm.numUniFlows = 0 //no more flows
688 oFsm.configuredUniFlow = 0 //no more flows configured
689 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000690 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000691 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
692 if !cancelPendingConfig {
693 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
694 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000695 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000696 "device-id": oFsm.deviceID})
697 } else {
698 oFsm.numUniFlows--
699 if oFsm.configuredUniFlow > 0 {
700 oFsm.configuredUniFlow--
701 //TODO!! might be needed to consider still outstanding configure requests ..
702 // so a flow at removal might still not be configured !?!
703 }
mpagenko2418ab02020-11-12 12:58:06 +0000704 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000705 //cut off the requested flow by slicing out this element
706 oFsm.uniVlanFlowParamsSlice = append(
707 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000708 //here we have to check, if there are still other flows referencing to the actual ProfileId
709 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000710 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000711 if !cancelPendingConfig {
712 oFsm.updateTechProfileToDelete(ctx, usedTpID)
713 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000714 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000715 "device-id": oFsm.deviceID})
716 }
717 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000718 if cancelPendingConfig {
719 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +0000720 go func(a_pBaseFsm *fsm.FSM) {
mpagenko535d6ef2021-02-26 13:15:34 +0000721 _ = a_pBaseFsm.Event(vlanEvCancelOutstandingConfig)
mpagenko01e726e2020-10-23 09:45:29 +0000722 }(pConfigVlanStateBaseFsm)
mpagenko535d6ef2021-02-26 13:15:34 +0000723 } else {
724 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
725 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
726 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
727 "tp-id": loRemoveParams.vlanRuleParams.TpID,
728 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
729 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
730 // Can't call FSM Event directly, decoupling it
731 go func(a_pBaseFsm *fsm.FSM) {
732 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
733 }(pConfigVlanStateBaseFsm)
734 } // if not in the appropriate state a new entry will be automatically considered later
735 // when the configDone state is reached
736 }
mpagenko01e726e2020-10-23 09:45:29 +0000737 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000738 //cut off the requested cookie by slicing out this element
739 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
740 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
741 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000742 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000743 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000744 // state transition notification is checked in deviceHandler
745 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000746 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
747 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000748 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000749 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000750 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000751 if deletedCookie == oFsm.delayNewRuleCookie {
752 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
753 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
754 //simply use the first one
755 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
756 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
757 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
758 }
mpagenko01e726e2020-10-23 09:45:29 +0000759 }
mpagenko01e726e2020-10-23 09:45:29 +0000760 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000761 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000762 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
763 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000764 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000765 return err
766 }
mpagenko01e726e2020-10-23 09:45:29 +0000767 }
mpagenkof1fc3862021-02-16 10:09:52 +0000768 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000769 }
770 }
mpagenko01e726e2020-10-23 09:45:29 +0000771 } //search all flows
772 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000773 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000774 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
775 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000776 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
777 // state transition notification is checked in deviceHandler
778 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000779 // success indication without the need to write to kvStore (no change)
780 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000781 }
mpagenko01e726e2020-10-23 09:45:29 +0000782 return nil
783 } //unknown cookie
784
785 return nil
786}
787
mpagenkof1fc3862021-02-16 10:09:52 +0000788func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
789 //here we have to check, if there are still other flows referencing to the actual ProfileId
790 // before we can request that this profile gets deleted before a new flow add is allowed
791 tpIDInOtherFlows := false
792 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
793 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
794 tpIDInOtherFlows = true
795 break // search loop can be left
796 }
797 }
798 if tpIDInOtherFlows {
799 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
800 "device-id": oFsm.deviceID, "tp-id": usedTpID})
801 } else {
802 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
803 "device-id": oFsm.deviceID, "tp-id": usedTpID})
804 //request that this profile gets deleted before a new flow add is allowed
805 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
806 }
807}
808
dbainbri4d3a0dc2020-12-02 00:33:42 +0000809func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
810 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000811 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000812
813 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000814 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000815 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000816 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000817 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000818 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000819 //let the state machine run forward from here directly
820 pConfigVlanStateAFsm := oFsm.pAdaptFsm
821 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000822
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000823 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
824 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
825 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
826 go func(a_pAFsm *AdapterFsm) {
827 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
828 }(pConfigVlanStateAFsm)
829 return
830 }
831 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000832 //possibly the entry is not valid anymore based on intermediate delete requests
833 //just a basic protection ...
834 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
835 oFsm.mutexFlowParams.Unlock()
836 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
837 "device-id": oFsm.deviceID})
838 // Can't call FSM Event directly, decoupling it
839 go func(a_pAFsm *AdapterFsm) {
840 _ = a_pAFsm.pFsm.Event(vlanEvReset)
841 }(pConfigVlanStateAFsm)
842 return
843 }
mpagenko9a304ea2020-12-16 15:54:01 +0000844 //access to uniVlanFlowParamsSlice is done on first element only here per definition
845 //store the actual rule that shall be worked upon in the following transient states
846 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000847 tpID := oFsm.actualUniVlanConfigRule.TpID
848 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000849 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000850 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
851 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
852 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000853 //cmp also usage in EVTOCDE create in omci_cc
854 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000855 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000856 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000857 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
858 if aPAFsm != nil && aPAFsm.pFsm != nil {
859 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000860 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000861 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000862 } else {
863 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000864 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000865 }
866 }
mpagenko551a4d42020-12-08 18:09:20 +0000867 }(pConfigVlanStateAFsm, loTechProfDone)
868 } else {
869 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
870 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
871 //should never happen, else: recovery would be needed from outside the FSM
872 return
mpagenkodff5dda2020-08-28 11:52:01 +0000873 }
874}
875
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000877 //mutex protection is required for possible concurrent access to FSM members
878 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000879 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000880 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000881 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000882 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000883 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000884 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000885 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000886 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000887 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000888 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530889 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000890 }(pConfigVlanStateAFsm)
891 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300892 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
893 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000894 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000895 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300896 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000897 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
898 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000899 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000900 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000901 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000902 vtfdFilterList[0] = oFsm.vlanFilterList[0]
903 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000904 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300905 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000906 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000907 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
908 "ForwardOperation": uint8(0x10), //VID investigation
909 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000910 },
911 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000912 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000913 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000914 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000915 oFsm.pAdaptFsm.commChan, meParams)
916 //accept also nil as (error) return value for writing to LastTx
917 // - this avoids misinterpretation of new received OMCI messages
918 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
919 // send shall return (dual format) error code that can be used here for immediate error treatment
920 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000921 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000922 }
923}
924
dbainbri4d3a0dc2020-12-02 00:33:42 +0000925func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
926 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000927 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000928 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300929 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000930 //using the first element in the slice because it's the first flow per definition here
931 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300932 //This is correct passing scenario
933 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000934 tpID := oFsm.actualUniVlanConfigRule.TpID
935 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
937 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300938 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +0000939 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300940 vlanID)
941 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000942 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300943 log.Fields{"device-id": oFsm.deviceID})
944 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
945 }
946 }
947 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
948 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
949 }
950 }()
mpagenkodff5dda2020-08-28 11:52:01 +0000951}
952
dbainbri4d3a0dc2020-12-02 00:33:42 +0000953func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000954
mpagenko9a304ea2020-12-16 15:54:01 +0000955 oFsm.mutexFlowParams.RLock()
956 defer oFsm.mutexFlowParams.RUnlock()
957
mpagenkof1fc3862021-02-16 10:09:52 +0000958 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +0000959 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
960 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
961 pConfigVlanStateAFsm := oFsm.pAdaptFsm
962 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +0000963 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
964 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
965 //should never happen, else: recovery would be needed from outside the FSM
966 return
967 }
968 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +0000969 if len(oFsm.uniRemoveFlowsSlice) > 0 {
970 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +0000971 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
972 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
973 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
974 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
975 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +0000976 go func(a_pBaseFsm *fsm.FSM) {
977 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
978 }(pConfigVlanStateBaseFsm)
979 return
980 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000981 if oFsm.numUniFlows > oFsm.configuredUniFlow {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
983 oFsm.configuredUniFlow = oFsm.numUniFlows
984 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
985 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
986 return
987 }
mpagenko551a4d42020-12-08 18:09:20 +0000988 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +0000989 // this is a restart with a complete new flow, we can re-use the initial flow config control
990 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +0000991 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000992 go func(a_pBaseFsm *fsm.FSM) {
993 _ = a_pBaseFsm.Event(vlanEvRenew)
994 }(pConfigVlanStateBaseFsm)
995 return
996 }
997
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000998 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000999 //store the actual rule that shall be worked upon in the following transient states
1000 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001001 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001002 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001003 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001004 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001005 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1006 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1007 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1008 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001009 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1010 if aTechProfDone {
1011 // let the vlan processing continue with next rule
1012 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1013 } else {
1014 // set to waiting for Techprofile
1015 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1016 }
1017 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001018 return
1019 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001020 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001021 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001022 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1023 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001024 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001025 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001026 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001027 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001028 }
1029}
1030
dbainbri4d3a0dc2020-12-02 00:33:42 +00001031func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001032
1033 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1034 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1035 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1036 go func(a_pBaseFsm *fsm.FSM) {
1037 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1038 }(oFsm.pAdaptFsm.pFsm)
1039 return
1040 }
mpagenko15ff4a52021-03-02 10:09:20 +00001041 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001042 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001043 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001044 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001045 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001046
mpagenko9a304ea2020-12-16 15:54:01 +00001047 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001048 // meaning transparent setup - no specific VTFD setting required
1049 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001050 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001051 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001052 } else {
1053 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001054 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1055 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +00001056 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001057 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001059 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001060 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001061 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001062 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001063
mpagenko01e726e2020-10-23 09:45:29 +00001064 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001065 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1066 oFsm.numVlanFilterEntries = 1
1067 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001068 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001069 Attributes: me.AttributeValueMap{
1070 "VlanFilterList": vtfdFilterList,
1071 "ForwardOperation": uint8(0x10), //VID investigation
1072 "NumberOfEntries": oFsm.numVlanFilterEntries,
1073 },
1074 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001075 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001076 oFsm.pAdaptFsm.commChan, meParams)
1077 //accept also nil as (error) return value for writing to LastTx
1078 // - this avoids misinterpretation of new received OMCI messages
1079 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1080 // send shall return (dual format) error code that can be used here for immediate error treatment
1081 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001082 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001083 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001084 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1085 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +00001086 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +00001087 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001088
dbainbri4d3a0dc2020-12-02 00:33:42 +00001089 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001090 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001091 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001092 // setVid is assumed to be masked already by the caller to 12 bit
1093 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001094 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001095 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001096
1097 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1098 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1099 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001100 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001101
1102 oFsm.numVlanFilterEntries++
1103 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001104 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001105 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001106 "VlanFilterList": vtfdFilterList,
1107 "ForwardOperation": uint8(0x10), //VID investigation
1108 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001109 },
1110 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001111 meInstance := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001112 oFsm.pAdaptFsm.commChan, meParams)
1113 //accept also nil as (error) return value for writing to LastTx
1114 // - this avoids misinterpretation of new received OMCI messages
1115 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1116 // send shall return (dual format) error code that can be used here for immediate error treatment
1117 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001118 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001119 }
mpagenko15ff4a52021-03-02 10:09:20 +00001120 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001121 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001122 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001123 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001124 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001125 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001126 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001127 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001128 go func(a_pBaseFsm *fsm.FSM) {
1129 _ = a_pBaseFsm.Event(vlanEvReset)
1130 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001131 return
1132 }
1133 }
mpagenko15ff4a52021-03-02 10:09:20 +00001134 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001135 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001136 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001137 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001138 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001139 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001140 configuredUniFlow := oFsm.configuredUniFlow
1141 oFsm.mutexFlowParams.RUnlock()
1142 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001143 //This is correct passing scenario
1144 if errEvto == nil {
1145 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001146 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001147 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001148 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001149 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001150 "techProfile": tpID, "gemPort": gemPort,
1151 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001152 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001154 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001155 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001156 log.Fields{"device-id": oFsm.deviceID})
1157 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1158 }
1159 }
1160 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1161 }
1162 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001163}
1164
dbainbri4d3a0dc2020-12-02 00:33:42 +00001165func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001166 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001167 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001168 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1169 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001170
mpagenkofc4f56e2020-11-04 17:17:49 +00001171 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
1172 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +00001173 loVlanEntryClear := uint8(0)
1174 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1175 //shallow copy is sufficient as no reference variables are used within struct
1176 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001177 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001178 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001179 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1180 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1181 "device-id": oFsm.deviceID})
1182
1183 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1184 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001185 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001186 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1187 } else {
1188 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1189 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +00001190 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001191 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1192 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +00001194 log.Fields{"current vlan list": oFsm.vlanFilterList,
1195 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001196 loVlanEntryClear = 1 //full VlanFilter clear request
1197 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001199 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001200 oFsm.pLastTxMeInstance = meInstance
1201 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001202 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001203 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001204 }
mpagenko01e726e2020-10-23 09:45:29 +00001205 } else {
1206 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1207 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001208 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001209 log.Fields{"current vlan list": oFsm.vlanFilterList,
1210 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1211 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1212 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1213 loVlanEntryRmPos = i
1214 break //abort search
1215 }
1216 }
1217 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +00001218 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001219 //valid entry was found - to be eclipsed
1220 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1221 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1222 if i < loVlanEntryRmPos {
1223 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1224 } else if i < (cVtfdTableSize - 1) {
1225 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1226 } else {
1227 vtfdFilterList[i] = 0 //set last byte if needed
1228 }
1229 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001230 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001231 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001232 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1233
mpagenkofc4f56e2020-11-04 17:17:49 +00001234 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001235 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
dbainbri4d3a0dc2020-12-02 00:33:42 +00001236 meInstance := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001237 oFsm.pAdaptFsm.commChan, vtfdID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001238 oFsm.pLastTxMeInstance = meInstance
1239 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001240 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001241 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001242 }
mpagenko01e726e2020-10-23 09:45:29 +00001243 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001245 log.Fields{"device-id": oFsm.deviceID})
1246 }
1247 }
1248 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001249 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1250 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001251 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001252 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001253 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001254 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001255 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001256 go func(a_pBaseFsm *fsm.FSM) {
1257 _ = a_pBaseFsm.Event(vlanEvReset)
1258 }(pConfigVlanStateBaseFsm)
1259 return
1260 }
mpagenko01e726e2020-10-23 09:45:29 +00001261 }
1262
mpagenko15ff4a52021-03-02 10:09:20 +00001263 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001264 if loVlanEntryClear == 1 {
1265 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1266 oFsm.numVlanFilterEntries = 0
1267 } else if loVlanEntryClear == 2 {
1268 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1269 // this loop now includes the 0 element on previous last valid entry
1270 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1271 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1272 }
1273 oFsm.numVlanFilterEntries--
1274 }
mpagenko15ff4a52021-03-02 10:09:20 +00001275 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001276 }
1277 }
1278
mpagenkofc4f56e2020-11-04 17:17:49 +00001279 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001280 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001281 } else {
1282 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001283 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001284 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001285 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001286 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001287 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001288 }(pConfigVlanStateBaseFsm)
1289 }
mpagenkodff5dda2020-08-28 11:52:01 +00001290}
1291
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001293 var tpID uint8
1294 // Extract the tpID
1295 if len(e.Args) > 0 {
1296 tpID = e.Args[0].(uint8)
1297 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1298 } else {
1299 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1300 }
mpagenko01e726e2020-10-23 09:45:29 +00001301 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001302 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1303 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1304 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1305 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1306
mpagenko01e726e2020-10-23 09:45:29 +00001307 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1308 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001309 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001310 "device-id": oFsm.deviceID})
1311 } else {
1312 //cut off the actual flow by slicing out the first element
1313 oFsm.uniRemoveFlowsSlice = append(
1314 oFsm.uniRemoveFlowsSlice[:0],
1315 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001316 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001317 "device-id": oFsm.deviceID})
1318 }
1319 oFsm.mutexFlowParams.Unlock()
1320
mpagenkof1fc3862021-02-16 10:09:52 +00001321 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001322 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001323 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1324 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001325 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001326 go func(a_pAFsm *AdapterFsm) {
1327 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001328 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001329 }
1330 }(pConfigVlanStateAFsm)
1331 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001332
1333 oFsm.mutexFlowParams.RLock()
1334 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001335 if deletedCookie == oFsm.delayNewRuleCookie {
1336 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1337 select {
1338 case <-oFsm.chCookieDeleted:
1339 logger.Debug(ctx, "flushed CookieDeleted")
1340 default:
1341 }
1342 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1343 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001344 oFsm.mutexFlowParams.RUnlock()
1345 // If all pending flow removes are completed and TP ID is valid, processing any pending TP delete
1346 if noOfFlowRem == 0 && tpID > 0 {
1347 logger.Debugw(ctx, "processing pending tp delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
1348 // If we are here then all flows are removed.
1349 oFsm.pDeviceHandler.ProcessPendingTpDelete(ctx, oFsm.pOnuUniPort, tpID)
1350 }
mpagenkodff5dda2020-08-28 11:52:01 +00001351}
1352
dbainbri4d3a0dc2020-12-02 00:33:42 +00001353func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1354 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001355
1356 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1357 if pConfigVlanStateAFsm != nil {
1358 // abort running message processing
1359 fsmAbortMsg := Message{
1360 Type: TestMsg,
1361 Data: TestMessage{
1362 TestMessageVal: AbortMessageProcessing,
1363 },
1364 }
1365 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1366
mpagenko9a304ea2020-12-16 15:54:01 +00001367 //try to restart the FSM to 'disabled'
1368 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001369 go func(a_pAFsm *AdapterFsm) {
1370 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301371 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001372 }
1373 }(pConfigVlanStateAFsm)
1374 }
1375}
1376
dbainbri4d3a0dc2020-12-02 00:33:42 +00001377func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1378 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001379 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001380 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001381 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1382 // current code removes the complete FSM including all flow/rule configuration done so far
1383 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1384 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001385 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001386 if oFsm.clearPersistency {
1387 //permanently remove possibly stored persistent data
1388 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1389 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001390 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001391 }
1392 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001394 }
mpagenkof1fc3862021-02-16 10:09:52 +00001395 if oFsm.delayNewRuleCookie != 0 {
1396 // looks like the waiting AddFlow is stuck
1397 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1398 }
mpagenko9a304ea2020-12-16 15:54:01 +00001399 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001400 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001401 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001402 }
1403}
1404
dbainbri4d3a0dc2020-12-02 00:33:42 +00001405func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1406 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001407loop:
1408 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001409 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001411 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301412 message, ok := <-oFsm.pAdaptFsm.commChan
1413 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001414 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301415 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1416 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1417 break loop
1418 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001419 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301420
1421 switch message.Type {
1422 case TestMsg:
1423 msg, _ := message.Data.(TestMessage)
1424 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001425 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001426 break loop
1427 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001428 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301429 case OMCI:
1430 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001431 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301432 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001433 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301434 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001435 }
1436 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001438}
1439
dbainbri4d3a0dc2020-12-02 00:33:42 +00001440func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1441 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001442 "msgType": msg.OmciMsg.MessageType})
1443
1444 switch msg.OmciMsg.MessageType {
1445 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001446 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001447 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1448 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001449 return
1450 }
mpagenkodff5dda2020-08-28 11:52:01 +00001451 } //CreateResponseType
1452 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001453 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001454 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1455 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001457 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001458 return
1459 }
1460 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1461 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001462 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001463 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001464 return
1465 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001466 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001467 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001469 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001470 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1471 return
1472 }
mpagenko01e726e2020-10-23 09:45:29 +00001473 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1474 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1475 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001476 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001477 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001478 oFsm.omciMIdsResponseReceived <- true
1479 }
1480 }
1481 }
1482 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001483 case omci.DeleteResponseType:
1484 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001485 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1486 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001487 return
1488 }
1489 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001490 default:
1491 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001492 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001493 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001494 return
1495 }
1496 }
1497}
1498
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001500 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1501 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001503 log.Fields{"device-id": oFsm.deviceID})
1504 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1505 oFsm.deviceID)
1506 }
1507 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1508 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001510 log.Fields{"device-id": oFsm.deviceID})
1511 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1512 oFsm.deviceID)
1513 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001515 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001516 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001517 "Error": msgObj.Result})
1518 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1519 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1520 oFsm.deviceID)
1521 }
1522 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1523 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1524 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1525 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001526 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1527 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1528 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001529 {
1530 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1531 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1532 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1533 } else { // let the MultiEntity config proceed by stopping the wait function
1534 oFsm.omciMIdsResponseReceived <- true
1535 }
1536 }
1537 }
1538 }
1539 return nil
1540}
1541
dbainbri4d3a0dc2020-12-02 00:33:42 +00001542func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001543 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1544 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001546 log.Fields{"device-id": oFsm.deviceID})
1547 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1548 oFsm.deviceID)
1549 }
1550 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1551 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001552 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001553 log.Fields{"device-id": oFsm.deviceID})
1554 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1555 oFsm.deviceID)
1556 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001557 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001558 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001559 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001560 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1561 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1562 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1563 oFsm.deviceID)
1564 }
1565 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1566 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1567 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001568 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001569 { // let the MultiEntity config proceed by stopping the wait function
1570 oFsm.omciMIdsResponseReceived <- true
1571 }
1572 }
1573 }
1574 return nil
1575}
1576
dbainbri4d3a0dc2020-12-02 00:33:42 +00001577func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001578 if aFlowEntryNo == 0 {
1579 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001580 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1581 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001582 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001583 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1584 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001585 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001586 associationType := 2 // default to uniPPTP
1587 if oFsm.pOnuUniPort.portType == uniVEIP {
1588 associationType = 10
1589 }
1590 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001591 meParams := me.ParamData{
1592 EntityID: oFsm.evtocdID,
1593 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001594 "AssociationType": uint8(associationType),
1595 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001596 },
1597 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001598 meInstance := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001599 oFsm.pAdaptFsm.commChan, meParams)
1600 //accept also nil as (error) return value for writing to LastTx
1601 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001602 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001603
1604 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001605 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001606 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001607 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001608 log.Fields{"device-id": oFsm.deviceID})
1609 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1610 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1611 }
1612
1613 // Set the EVTOCD ME default params
1614 meParams = me.ParamData{
1615 EntityID: oFsm.evtocdID,
1616 Attributes: me.AttributeValueMap{
1617 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1618 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1619 "DownstreamMode": uint8(cDefaultDownstreamMode),
1620 },
1621 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 meInstance = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001623 oFsm.pAdaptFsm.commChan, meParams)
1624 //accept also nil as (error) return value for writing to LastTx
1625 // - this avoids misinterpretation of new received OMCI messages
1626 oFsm.pLastTxMeInstance = meInstance
1627
1628 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001629 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001630 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001632 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301633 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001634 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001635 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001636 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001637
mpagenko551a4d42020-12-08 18:09:20 +00001638 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001639 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001640 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001641 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001643 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001644 sliceEvtocdRule := make([]uint8, 16)
1645 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1646 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1647 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1648 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1649 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1650
1651 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1652 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1653 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1654 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1655 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1656
1657 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1658 0<<cTreatTTROffset| // Do not pop any tags
1659 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1660 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1661 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1662
1663 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1664 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1665 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1666 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1667
1668 meParams := me.ParamData{
1669 EntityID: oFsm.evtocdID,
1670 Attributes: me.AttributeValueMap{
1671 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1672 },
1673 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001674 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001675 oFsm.pAdaptFsm.commChan, meParams)
1676 //accept also nil as (error) return value for writing to LastTx
1677 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001678 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001679
1680 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001682 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001683 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001684 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301685 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001686 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1687
mpagenkodff5dda2020-08-28 11:52:01 +00001688 }
1689 } else {
1690 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1691 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001692 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1693 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1694 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1695 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001696 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001698 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001699 sliceEvtocdRule := make([]uint8, 16)
1700 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1701 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1702 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1703 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1704 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1705
1706 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001707 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1708 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001709 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1710 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1711
1712 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001713 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001714 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1715 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1716 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1717
1718 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001719 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1720 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001721 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001722 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001723
1724 meParams := me.ParamData{
1725 EntityID: oFsm.evtocdID,
1726 Attributes: me.AttributeValueMap{
1727 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1728 },
1729 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001730 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001731 oFsm.pAdaptFsm.commChan, meParams)
1732 //accept also nil as (error) return value for writing to LastTx
1733 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001734 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001735
1736 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001737 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001738 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001740 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301741 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001742 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001743 }
1744 } else {
1745 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1746 { // just for local var's
1747 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001749 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001750 sliceEvtocdRule := make([]uint8, 16)
1751 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1752 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1753 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1754 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1755 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1756
1757 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1758 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1759 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1760 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1761 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1762
1763 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1764 0<<cTreatTTROffset| // Do not pop any tags
1765 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1766 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1767 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1768
1769 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1770 0<<cTreatPrioOffset| // vlan prio set to 0
1771 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001772 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001773 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1774
mpagenko551a4d42020-12-08 18:09:20 +00001775 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001776 meParams := me.ParamData{
1777 EntityID: oFsm.evtocdID,
1778 Attributes: me.AttributeValueMap{
1779 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1780 },
1781 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001782 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001783 oFsm.pAdaptFsm.commChan, meParams)
1784 //accept also nil as (error) return value for writing to LastTx
1785 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001786 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001787
1788 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001790 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001791 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001792 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301793 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001794 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1795
mpagenkodff5dda2020-08-28 11:52:01 +00001796 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001797 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001798 { // just for local var's
1799 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001800 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001801 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001802 sliceEvtocdRule := make([]uint8, 16)
1803 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1804 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1805 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1806 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1807 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1808
1809 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1810 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1811 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1812 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1813 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1814
1815 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1816 1<<cTreatTTROffset| // pop the prio-tag
1817 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1818 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1819 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1820
mpagenko551a4d42020-12-08 18:09:20 +00001821 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001822 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1823 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1824 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001825 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001826 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001827 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001828
1829 meParams := me.ParamData{
1830 EntityID: oFsm.evtocdID,
1831 Attributes: me.AttributeValueMap{
1832 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1833 },
1834 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001835 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001836 oFsm.pAdaptFsm.commChan, meParams)
1837 //accept also nil as (error) return value for writing to LastTx
1838 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001839 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001840
1841 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001842 err := oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001843 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001844 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001845 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301846 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001847 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1848
mpagenkodff5dda2020-08-28 11:52:01 +00001849 }
1850 } //just for local var's
1851 }
1852 }
1853
mpagenkofc4f56e2020-11-04 17:17:49 +00001854 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00001855 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001856 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001857 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00001858}
1859
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00001861 // configured Input/Output TPID is not modified again - no influence if no filter is applied
1862 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1863 //transparent transmission was set
1864 //perhaps the config is not needed for removal,
1865 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001867 "device-id": oFsm.deviceID})
1868 sliceEvtocdRule := make([]uint8, 16)
1869 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1870 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1871 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1872 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1873 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1874
1875 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1876 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1877 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1878 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1879 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1880
1881 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1882 0<<cTreatTTROffset| // Do not pop any tags
1883 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1884 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1885 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1886
1887 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1888 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1889 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1890 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
1891
1892 meParams := me.ParamData{
1893 EntityID: oFsm.evtocdID,
1894 Attributes: me.AttributeValueMap{
1895 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1896 },
1897 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001898 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001899 oFsm.pAdaptFsm.commChan, meParams)
1900 //accept also nil as (error) return value for writing to LastTx
1901 // - this avoids misinterpretation of new received OMCI messages
1902 oFsm.pLastTxMeInstance = meInstance
1903
1904 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001905 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001906 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001907 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001908 log.Fields{"device-id": oFsm.deviceID})
1909 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1910 return
1911 }
1912 } else {
1913 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1914 if oFsm.acceptIncrementalEvtoOption {
1915 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001917 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1918 sliceEvtocdRule := make([]uint8, 16)
1919 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1920 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1921 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1922 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1923 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1924
1925 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1926 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1927 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
1928 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1929 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1930
1931 // delete indication for the indicated Filter
1932 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
1933 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
1934
1935 meParams := me.ParamData{
1936 EntityID: oFsm.evtocdID,
1937 Attributes: me.AttributeValueMap{
1938 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1939 },
1940 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001942 oFsm.pAdaptFsm.commChan, meParams)
1943 //accept also nil as (error) return value for writing to LastTx
1944 // - this avoids misinterpretation of new received OMCI messages
1945 oFsm.pLastTxMeInstance = meInstance
1946
1947 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001948 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001949 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001950 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001951 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
1952 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1953 return
1954 }
1955 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001956 // VOL-3685
1957 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
1958 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
1959 // indeed, but the traffic landing upstream would carry old vlan sometimes.
1960 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
1961 // later when the flow is being re-installed.
1962 // Of course this is applicable to case only where single service (or single tcont) is in use and
1963 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
1964 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
1965 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
1966 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001967 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001968 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
1969 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00001970 meParams := me.ParamData{
1971 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00001972 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001973 meInstance := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00001974 oFsm.pAdaptFsm.commChan, meParams)
1975 //accept also nil as (error) return value for writing to LastTx
1976 // - this avoids misinterpretation of new received OMCI messages
1977 oFsm.pLastTxMeInstance = meInstance
1978
1979 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001980 err := oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00001981 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001982 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001983 log.Fields{"device-id": oFsm.deviceID})
1984 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1985 return
1986 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001987 } else {
1988 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
1989 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00001990 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001991 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
1992 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
1993 { // just for local var's
1994 // this defines stacking scenario: untagged->singletagged
1995 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
1996 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
1997 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
1998 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00001999 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002000 "device-id": oFsm.deviceID})
2001 sliceEvtocdRule := make([]uint8, 16)
2002 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2003 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2004 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2005 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2006 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002007
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002008 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2009 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2010 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2011 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2012 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002013
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002014 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2015 0<<cTreatTTROffset| // Do not pop any tags
2016 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2017 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2018 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002019
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002020 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2021 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2022 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2023 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002024
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002025 meParams := me.ParamData{
2026 EntityID: oFsm.evtocdID,
2027 Attributes: me.AttributeValueMap{
2028 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2029 },
2030 }
2031 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(), ConstDefaultOmciTimeout, true,
2032 oFsm.pAdaptFsm.commChan, meParams)
2033 //accept also nil as (error) return value for writing to LastTx
2034 // - this avoids misinterpretation of new received OMCI messages
2035 oFsm.pLastTxMeInstance = meInstance
2036
2037 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002038 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002039 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002040 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002041 log.Fields{"device-id": oFsm.deviceID})
2042 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2043 return
2044 }
2045 } // just for local var's
2046 { // just for local var's
2047 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002048 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002049 "device-id": oFsm.deviceID})
2050 sliceEvtocdRule := make([]uint8, 16)
2051 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2052 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2053 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2054 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2055 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2056
2057 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2058 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2059 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2060 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2061 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2062
2063 // delete indication for the indicated Filter
2064 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2065 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2066
2067 meParams := me.ParamData{
2068 EntityID: oFsm.evtocdID,
2069 Attributes: me.AttributeValueMap{
2070 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2071 },
2072 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 meInstance := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx), ConstDefaultOmciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002074 oFsm.pAdaptFsm.commChan, meParams)
2075 //accept also nil as (error) return value for writing to LastTx
2076 // - this avoids misinterpretation of new received OMCI messages
2077 oFsm.pLastTxMeInstance = meInstance
2078
2079 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002080 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002081 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002082 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002083 log.Fields{"device-id": oFsm.deviceID})
2084 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2085 return
2086 }
mpagenko01e726e2020-10-23 09:45:29 +00002087 }
2088 } //just for local var's
2089 }
2090 }
2091
mpagenkofc4f56e2020-11-04 17:17:49 +00002092 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002093 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002094 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002095}
2096
dbainbri4d3a0dc2020-12-02 00:33:42 +00002097func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenkodff5dda2020-08-28 11:52:01 +00002098 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302099 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002100 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002101 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002102 case <-time.After(30 * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002103 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002104 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002105 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302106 if success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Debug(ctx, "UniVlanConfigFsm multi entity response received")
mpagenkodff5dda2020-08-28 11:52:01 +00002108 return nil
2109 }
2110 // should not happen so far
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Warnw(ctx, "UniVlanConfigFsm multi entity response error", log.Fields{"for device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002112 return fmt.Errorf("uniVlanConfigFsm multi entity responseError %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002113 }
2114}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002115
mpagenko551a4d42020-12-08 18:09:20 +00002116func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002117 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002118 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002120 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002121 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002122 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002123 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002124 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2125 }
2126
dbainbri4d3a0dc2020-12-02 00:33:42 +00002127 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002128 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002129 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002130 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002131 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002132 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2133 }
2134
dbainbri4d3a0dc2020-12-02 00:33:42 +00002135 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002136 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002137 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002138 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002139 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002140 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2141 }
2142
2143 meParams := me.ParamData{
2144 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2145 Attributes: me.AttributeValueMap{
2146 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2147 "PortNum": 0xf0, //fixed unique ANI side indication
2148 "TpType": 6, //MCGemIWTP
2149 "TpPointer": multicastGemPortID,
2150 },
2151 }
2152 meInstance := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(), ConstDefaultOmciTimeout, true,
2153 oFsm.pAdaptFsm.commChan, meParams)
2154 //accept also nil as (error) return value for writing to LastTx
2155 // - this avoids misinterpretation of new received OMCI messages
2156 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002157 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002158 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002159 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002160 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002161 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002162 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2163 }
2164
2165 // ==> Start creating VTFD for mcast vlan
2166
2167 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2168 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
2169 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
2170
dbainbri4d3a0dc2020-12-02 00:33:42 +00002171 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002172 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2173 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2174 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2175
2176 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2177 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2178 // new vlan associated with a different TP.
2179 vtfdFilterList[0] = uint16(vlanID)
2180
2181 meParams = me.ParamData{
2182 EntityID: mcastVtfdID,
2183 Attributes: me.AttributeValueMap{
2184 "VlanFilterList": vtfdFilterList,
2185 "ForwardOperation": uint8(0x10), //VID investigation
2186 "NumberOfEntries": oFsm.numVlanFilterEntries,
2187 },
2188 }
2189 meInstance = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(), ConstDefaultOmciTimeout, true,
2190 oFsm.pAdaptFsm.commChan, meParams)
2191 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002192 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002193 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002194 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002195 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002196 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002197 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2198 }
2199
2200 return nil
2201}
2202
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002204 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2205 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002206 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002207 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2208 return err
2209 }
2210 meParams := me.ParamData{
2211 EntityID: instID,
2212 Attributes: me.AttributeValueMap{
2213 "MeType": 0,
2214 //Direct reference to the Operation profile
2215 //TODO ANI side used on UNI side, not the clearest option.
2216 "MulticastOperationsProfilePointer": macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo),
2217 },
2218 }
2219 meInstance := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(), ConstDefaultOmciTimeout, true,
2220 oFsm.pAdaptFsm.commChan, meParams)
2221 //accept also nil as (error) return value for writing to LastTx
2222 // - this avoids misinterpretation of new received OMCI messages
2223 oFsm.pLastTxMeInstance = meInstance
2224 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002225 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002226 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002227 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002228 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2229 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2230 }
2231 return nil
2232}
2233
dbainbri4d3a0dc2020-12-02 00:33:42 +00002234func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002235 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
2236 meParams := me.ParamData{
2237 EntityID: instID,
2238 Attributes: me.AttributeValueMap{
2239 "IgmpVersion": 2,
2240 "IgmpFunction": 0,
2241 //0 means false
2242 "ImmediateLeave": 0,
2243 "Robustness": 2,
2244 "QuerierIp": 0,
2245 "QueryInterval": 125,
2246 "QuerierMaxResponseTime": 100,
2247 "LastMemberResponseTime": 10,
2248 //0 means false
2249 "UnauthorizedJoinBehaviour": 0,
2250 },
2251 }
2252 meInstance := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2253 oFsm.pAdaptFsm.commChan, meParams)
2254 //accept also nil as (error) return value for writing to LastTx
2255 // - this avoids misinterpretation of new received OMCI messages
2256 oFsm.pLastTxMeInstance = meInstance
2257 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002258 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002259 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002260 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002261 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2262 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2263 }
2264 return nil
2265}
2266
dbainbri4d3a0dc2020-12-02 00:33:42 +00002267func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002268 instID := macBridgePortAniEID + uint16(oFsm.pOnuUniPort.macBpNo)
2269 //TODO check that this is correct
2270 // Table control
2271 //setCtrl = 1
2272 //rowPartId = 0
2273 //test = 0
2274 //rowKey = 0
2275 tableCtrlStr := "0100000000000000"
2276 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002277 dynamicAccessCL := make([]uint8, 24)
2278 copy(dynamicAccessCL, tableCtrl)
2279 //Multicast GemPortId
2280 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2281 // python version waits for installation of flows, see line 723 onward of
2282 // brcm_openomci_onu_handler.py
2283 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2284 //Source IP all to 0
2285 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2286 //TODO start and end are hardcoded, get from TP
2287 // Destination IP address start of range
2288 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2289 // Destination IP address end of range
2290 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2291 //imputed group bandwidth
2292 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2293
2294 meParams := me.ParamData{
2295 EntityID: instID,
2296 Attributes: me.AttributeValueMap{
2297 "DynamicAccessControlListTable": dynamicAccessCL,
2298 },
2299 }
2300 meInstance := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(), ConstDefaultOmciTimeout, true,
2301 oFsm.pAdaptFsm.commChan, meParams)
2302 //accept also nil as (error) return value for writing to LastTx
2303 // - this avoids misinterpretation of new received OMCI messages
2304 oFsm.pLastTxMeInstance = meInstance
2305 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002306 err := oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002307 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002308 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002309 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
2310 return fmt.Errorf("createMulticastOperationProfile responseError %s", oFsm.deviceID)
2311 }
2312 return nil
2313}
Girish Gowdra26a40922021-01-29 17:14:34 -08002314
2315// IsFlowRemovePending returns true if there are pending flows to remove, else false.
2316func (oFsm *UniVlanConfigFsm) IsFlowRemovePending() bool {
2317 oFsm.mutexFlowParams.RLock()
2318 defer oFsm.mutexFlowParams.RUnlock()
2319 return len(oFsm.uniRemoveFlowsSlice) > 0
2320}