blob: dcc0f050aed2038cc7d3e29107681a5f3de70760 [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
39 cDefaultDownstreamMode = 0
40 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000041 cVtfdTableSize = 12 //as per G.988
42 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000043)
44
45const (
mpagenkof1fc3862021-02-16 10:09:52 +000046 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
47 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
48 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
49 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
50 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
51)
52
53const (
mpagenkodff5dda2020-08-28 11:52:01 +000054 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
55 cFilterPrioOffset = 28
56 cFilterVidOffset = 15
57 cFilterTpidOffset = 12
58 cFilterEtherTypeOffset = 0
59 cTreatTTROffset = 30
60 cTreatPrioOffset = 16
61 cTreatVidOffset = 3
62 cTreatTpidOffset = 0
63)
64const (
65 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
66 cFilterOuterOffset = 0
67 cFilterInnerOffset = 4
68 cTreatOuterOffset = 8
69 cTreatInnerOffset = 12
70)
71const (
72 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
73 cPrioIgnoreTag uint32 = 15
74 cPrioDefaultFilter uint32 = 14
75 cPrioDoNotFilter uint32 = 8
76 cDoNotFilterVid uint32 = 4096
77 cDoNotFilterTPID uint32 = 0
78 cDoNotFilterEtherType uint32 = 0
79 cDoNotAddPrio uint32 = 15
80 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053081 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000082 cDontCareVid uint32 = 0
83 cDontCareTpid uint32 = 0
84 cSetOutputTpidCopyDei uint32 = 4
85)
86
87const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000088 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000089 vlanEvStart = "vlanEvStart"
mpagenkof1d21d12021-06-11 13:14:45 +000090 vlanEvPrepareDone = "vlanEvPrepareDone"
mpagenko535d6ef2021-02-26 13:15:34 +000091 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"
mpagenkof1d21d12021-06-11 13:14:45 +0000114 vlanStPreparing = "vlanStPreparing"
mpagenkodff5dda2020-08-28 11:52:01 +0000115 vlanStStarting = "vlanStStarting"
116 vlanStWaitingTechProf = "vlanStWaitingTechProf"
117 vlanStConfigVtfd = "vlanStConfigVtfd"
118 vlanStConfigEvtocd = "vlanStConfigEvtocd"
119 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000120 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000121 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000122 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000123 vlanStCleanupDone = "vlanStCleanupDone"
124 vlanStResetting = "vlanStResetting"
125)
mpagenkof1fc3862021-02-16 10:09:52 +0000126const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
127const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000128
mpagenko01e726e2020-10-23 09:45:29 +0000129type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000130 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000131 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
132 MatchPcp uint32 `json:"match_pcp"`
133 TagsToRemove uint32 `json:"tags_to_remove"`
134 SetVid uint32 `json:"set_vid"`
135 SetPcp uint32 `json:"set_pcp"`
136}
137
138type uniVlanFlowParams struct {
139 CookieSlice []uint64 `json:"cookie_slice"`
140 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
141}
142
143type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000144 isSuspendedOnAdd bool
145 removeChannel chan bool
146 cookie uint64 //just the last cookie valid for removal
147 vlanRuleParams uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000148}
149
mpagenkobb47bc22021-04-20 13:29:09 +0000150//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
151// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000152type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530153 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000154 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530155 pOmciCC *omciCC
156 pOnuUniPort *onuUniPort
157 pUniTechProf *onuUniTechProf
158 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000159 requestEvent OnuDeviceEvent
160 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
161 pAdaptFsm *AdapterFsm
162 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000163 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000164 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000165 isAwaitingResponse bool
166 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000167 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000168 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000169 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000170 uniVlanFlowParamsSlice []uniVlanFlowParams
171 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000172 numUniFlows uint8 // expected number of flows should be less than 12
173 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000174 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000175 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000176 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000177 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000178 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000179 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000180 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000181 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000182 signalOnFlowDelete bool
183 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000184 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
185 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200186 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
187 // thus notification needs to be sent on chan.
188 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000189}
190
mpagenko01e726e2020-10-23 09:45:29 +0000191//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
192// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000193func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000194 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000195 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200196 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000197 instFsm := &UniVlanConfigFsm{
198 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000199 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000200 pOmciCC: apDevOmciCC,
201 pOnuUniPort: apUniPort,
202 pUniTechProf: apUniTechProf,
203 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000204 requestEvent: aRequestEvent,
205 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000206 numUniFlows: 0,
207 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000208 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000209 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200210 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000211 }
212
mpagenko01e726e2020-10-23 09:45:29 +0000213 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000214 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000215 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000216 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000217 return nil
218 }
mpagenkodff5dda2020-08-28 11:52:01 +0000219 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
220 vlanStDisabled,
221 fsm.Events{
mpagenkof1d21d12021-06-11 13:14:45 +0000222 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStPreparing},
223 {Name: vlanEvPrepareDone, Src: []string{vlanStPreparing}, Dst: vlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000224 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000225 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000226 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
227 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
228 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000229 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
230 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000231 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
232 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
233 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
234 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000235 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
236 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
237 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000238 /*
239 {Name: vlanEvTimeoutSimple, Src: []string{
240 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
241 {Name: vlanEvTimeoutMids, Src: []string{
242 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
243 */
244 // exceptional treatment for all states except vlanStResetting
245 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000246 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000247 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000248 Dst: vlanStResetting},
249 // the only way to get to resource-cleared disabled state again is via "resseting"
250 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000251 // transitions for reconcile handling according to VOL-3834
mpagenkof1d21d12021-06-11 13:14:45 +0000252 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStPreparing}, Dst: vlanStConfigDone},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000253 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
254 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000255 },
mpagenkodff5dda2020-08-28 11:52:01 +0000256 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000257 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
mpagenkof1d21d12021-06-11 13:14:45 +0000258 "enter_" + vlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000259 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
260 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
261 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
262 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
263 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
264 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
265 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
266 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
267 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000268 },
269 )
270 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000271 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000272 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000273 return nil
274 }
275
dbainbri4d3a0dc2020-12-02 00:33:42 +0000276 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000277
dbainbri4d3a0dc2020-12-02 00:33:42 +0000278 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000279 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000280 return instFsm
281}
282
mpagenko01e726e2020-10-23 09:45:29 +0000283//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000284func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000285 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
286 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000287 TpID: aTpID,
288 MatchVid: uint32(aMatchVlan),
289 SetVid: uint32(aSetVlan),
290 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000291 }
292 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000293 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
294 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000298 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000299 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
300 } else {
301 if !oFsm.acceptIncrementalEvtoOption {
302 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000303 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000304 }
305 }
306
mpagenko01e726e2020-10-23 09:45:29 +0000307 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000308 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.TagsToRemove = 0 //no tag pop action
310 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
311 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000312 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
313 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
314 // might collide with NoMatchVid/CopyPrio(/setVid) setting
315 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000316 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000317 }
318 }
mpagenko01e726e2020-10-23 09:45:29 +0000319
320 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
321 loFlowParams.CookieSlice = make([]uint64, 0)
322 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
323
324 //no mutex protection is required for initial access and adding the first flow is always possible
325 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
326 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000327 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000328 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
329 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
330 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
331 "SetPcp": loRuleParams.SetPcp,
332 "device-id": oFsm.deviceID})
333 oFsm.numUniFlows = 1
334 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
335
336 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000337 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000338 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000339 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000340 return err
341 }
342
343 return nil
344}
345
mpagenko7d6bb022021-03-11 15:07:55 +0000346//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000347func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000348 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000349 oFsm.mutexIsAwaitingResponse.Lock()
350 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000351 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000352 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
353 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
354 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000355 //use channel to indicate that the response waiting shall be aborted
356 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000357 } else {
358 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000359 }
mpagenkocf48e452021-04-23 09:23:00 +0000360
mpagenko7d6bb022021-03-11 15:07:55 +0000361 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
362 pAdaptFsm := oFsm.pAdaptFsm
363 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000364 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000365 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000366 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000367 }
mpagenko7d6bb022021-03-11 15:07:55 +0000368 }
369}
370
mpagenko551a4d42020-12-08 18:09:20 +0000371//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
372func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
373 //mutex protection is required for possible concurrent access to FSM members
374 oFsm.mutexFlowParams.RLock()
375 defer oFsm.mutexFlowParams.RUnlock()
376 return oFsm.TpIDWaitingFor
377}
378
mpagenko2418ab02020-11-12 12:58:06 +0000379//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
380func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
381 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000382 oFsm.mutexFlowParams.Lock()
383 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000384 oFsm.clearPersistency = aClear
385}
386
mpagenko01e726e2020-10-23 09:45:29 +0000387//SetUniFlowParams verifies on existence of flow parameters to be configured,
388// optionally udates the cookie list or appends a new flow if there is space
389// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000390// ignore complexity by now
391// nolint: gocyclo
392func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200393 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool) error {
mpagenko01e726e2020-10-23 09:45:29 +0000394 loRuleParams := uniVlanRuleParams{
395 TpID: aTpID,
396 MatchVid: uint32(aMatchVlan),
397 SetVid: uint32(aSetVlan),
398 SetPcp: uint32(aSetPcp),
399 }
400 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
401 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
402 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
403
404 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
405 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
406 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
407 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
408 } else {
409 if !oFsm.acceptIncrementalEvtoOption {
410 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
411 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
412 }
413 }
414
415 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
416 // no prio/vid filtering requested
417 loRuleParams.TagsToRemove = 0 //no tag pop action
418 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
419 if loRuleParams.SetPcp == cCopyPrioFromInner {
420 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
421 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
422 // might collide with NoMatchVid/CopyPrio(/setVid) setting
423 // this was some precondition setting taken over from py adapter ..
424 loRuleParams.SetPcp = 0
425 }
426 }
427
mpagenkof1d21d12021-06-11 13:14:45 +0000428 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
429 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
430 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
431 oFsm.mutexFlowParams.RLock()
432 if len(oFsm.uniRemoveFlowsSlice) > 0 {
433 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
434 if removeUniFlowParams.vlanRuleParams == loRuleParams {
435 // the flow to add is the same as the one already in progress of deleting
436 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
437 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
438 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
439 oFsm.mutexFlowParams.RUnlock()
440 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
441 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
442 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
443 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
444 }
445 oFsm.mutexFlowParams.RLock()
446 }
447 }
448 }
449 oFsm.mutexFlowParams.RUnlock()
450
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000451 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000452 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000453 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200454 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000455 //mutex protection is required for possible concurrent access to FSM members
456 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000457 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
458 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
459 // countable run time optimization (perhaps with including the hash in kvStore storage?)
460 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000461 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000462 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000463 "device-id": oFsm.deviceID})
464 var cookieMatch bool
465 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
466 cookieMatch = false
467 for _, cookie := range storedUniFlowParams.CookieSlice {
468 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000469 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000470 "device-id": oFsm.deviceID, "cookie": cookie})
471 cookieMatch = true
472 break //found new cookie - no further search for this requested cookie
473 }
474 }
475 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000476 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
477 if delayedCookie != 0 {
478 //a delay for adding the cookie to this rule is requested
479 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
480 oFsm.mutexFlowParams.Unlock()
481 oFsm.suspendNewRule(ctx)
482 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
483 oFsm.mutexFlowParams.Lock()
484 } else {
485 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
486 "device-id": oFsm.deviceID, "cookie": newCookie})
487 //as range works with copies of the slice we have to write to the original slice!!
488 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
489 newCookie)
490 flowCookieModify = true
491 }
mpagenko01e726e2020-10-23 09:45:29 +0000492 }
493 } //for all new cookies
494 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000495 }
496 }
mpagenkof1fc3862021-02-16 10:09:52 +0000497 oFsm.mutexFlowParams.Unlock()
498
499 if !flowEntryMatch { //it is (was) a new rule
500 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
501 requestAppendRule = true //default assumption here is that rule is to be appended
502 flowCookieModify = true //and that the the flow data base is to be updated
503 if delayedCookie != 0 { //it was suspended
504 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
505 }
506 }
507 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
508 if requestAppendRule {
509 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000510 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000511 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
512 loFlowParams.CookieSlice = make([]uint64, 0)
513 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
514 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000515 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000516 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
517 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
518 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800519 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000520 "device-id": oFsm.deviceID})
521
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000522 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000523 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
524
525 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
526 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
527 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000528 //attention: take care to release the mutexFlowParams when calling the FSM directly -
529 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000530 oFsm.mutexFlowParams.Unlock()
531 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000532 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
533 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
534 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
535 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000536 }
537 return nil
538 }
mpagenko01e726e2020-10-23 09:45:29 +0000539 // note: theoretical it would be possible to clear the same rule from the remove slice
540 // (for entries that have not yet been started with removal)
541 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
542 // 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 +0000543
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000544 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
545 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000546 if oFsm.configuredUniFlow == 0 {
547 // this is a restart with a complete new flow, we can re-use the initial flow config control
548 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000549 //attention: take care to release the mutexFlowParams when calling the FSM directly -
550 // synchronous FSM 'event/state' functions may rely on this mutex
551 oFsm.mutexFlowParams.Unlock()
552 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
553 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
554 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
555 }
mpagenko551a4d42020-12-08 18:09:20 +0000556 } else {
557 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000558 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000559 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
560 //check introduced after having observed some panic here
561 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
562 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
563 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
564 oFsm.mutexFlowParams.Unlock()
565 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
566 }
mpagenko9a304ea2020-12-16 15:54:01 +0000567 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000568 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000569 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000570 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
571 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000572 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
573 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
574 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000575
576 //attention: take care to release the mutexFlowParams when calling the FSM directly -
577 // synchronous FSM 'event/state' functions may rely on this mutex
578 oFsm.mutexFlowParams.Unlock()
579 var fsmErr error
580 if loTechProfDone {
581 // let the vlan processing continue with next rule
582 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
583 } else {
584 // set to waiting for Techprofile
585 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
586 }
587 if fsmErr != nil {
588 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
589 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
590 }
mpagenko551a4d42020-12-08 18:09:20 +0000591 }
mpagenkobb47bc22021-04-20 13:29:09 +0000592 } else {
593 // if not in the appropriate state a new entry will be automatically considered later
594 // when the configDone state is reached
595 oFsm.mutexFlowParams.Unlock()
596 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000597 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000598 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000599 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000600 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000601 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
602 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000603 } else {
604 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000605 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000606 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000607 if oFsm.numUniFlows == oFsm.configuredUniFlow {
608 //all requested rules really have been configured
609 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000610 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000611 if oFsm.pDeviceHandler != nil {
612 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000613 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000614 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000615 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
616 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000617 }
618 } else {
619 // avoid device reason update as the rule config connected to this flow may still be in progress
620 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000622 log.Fields{"device-id": oFsm.deviceID,
623 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000624 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000625 }
626 }
mpagenko01e726e2020-10-23 09:45:29 +0000627
mpagenkof1fc3862021-02-16 10:09:52 +0000628 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000629 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000630 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000631 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
632 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000633 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000634 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000635 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000636 }
mpagenko15ff4a52021-03-02 10:09:20 +0000637 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000638 }
639 return nil
640}
641
mpagenkof1d21d12021-06-11 13:14:45 +0000642func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
643 oFsm.mutexFlowParams.Lock()
644 deleteChannel := apRemoveFlowParams.removeChannel
645 apRemoveFlowParams.isSuspendedOnAdd = true
646 oFsm.mutexFlowParams.Unlock()
647
648 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
649 select {
650 case success := <-deleteChannel:
651 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
652 if success {
653 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
654 "device-id": oFsm.deviceID})
655 return nil
656 }
657 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
658 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
659 oFsm.mutexFlowParams.Lock()
660 if apRemoveFlowParams != nil {
661 apRemoveFlowParams.isSuspendedOnAdd = false
662 }
663 oFsm.mutexFlowParams.Unlock()
664 logger.Errorw(ctx, "timeout waiting for deletion of rule, just try to continue", log.Fields{
665 "device-id": oFsm.deviceID})
666 }
667 return nil
668}
669
mpagenkof1fc3862021-02-16 10:09:52 +0000670// VOL-3828 flow config sequence workaround ########### start ##########
671func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
672 //assumes mutexFlowParams.Lock() protection from caller!
673 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
674 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000675 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000676 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
677 newCookie := aCookieSlice[0]
678 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
679 for _, cookie := range storedUniFlowParams.CookieSlice {
680 if cookie == newCookie {
681 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
682 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
683 oFsm.delayNewRuleCookie = newCookie
684 return newCookie //found new cookie in some existing rule
685 }
686 } // for all stored cookies of the actual inspected rule
687 } //for all rules
688 }
689 return 0 //no delay requested
690}
691func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
692 oFsm.mutexFlowParams.RLock()
693 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
694 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
695 oFsm.mutexFlowParams.RUnlock()
696 select {
697 case <-oFsm.chCookieDeleted:
698 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
699 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000700 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000701 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
702 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
703 }
704 oFsm.mutexFlowParams.Lock()
705 oFsm.delayNewRuleCookie = 0
706 oFsm.mutexFlowParams.Unlock()
707}
708func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
709 oFsm.mutexFlowParams.Lock()
710 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
711 oFsm.mutexFlowParams.Unlock()
712
713 if delayedCookie != 0 {
714 oFsm.suspendNewRule(ctx)
715 }
716 return delayedCookie
717}
718
719//returns flowModified, RuleAppendRequest
720func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
721 flowEntryMatch := false
722 oFsm.mutexFlowParams.Lock()
723 defer oFsm.mutexFlowParams.Unlock()
724 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
725 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
726 flowEntryMatch = true
727 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
728 "device-id": oFsm.deviceID})
729 cookieMatch := false
730 for _, cookie := range storedUniFlowParams.CookieSlice {
731 if cookie == aCookie {
732 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
733 "device-id": oFsm.deviceID, "cookie": cookie})
734 cookieMatch = true
735 break //found new cookie - no further search for this requested cookie
736 }
737 }
738 if !cookieMatch {
739 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
740 "device-id": oFsm.deviceID, "cookie": aCookie})
741 //as range works with copies of the slice we have to write to the original slice!!
742 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
743 aCookie)
744 return true, false //flowModified, NoRuleAppend
745 }
746 break // found rule - no further rule search
747 }
748 }
749 if !flowEntryMatch { //it is a new rule
750 return true, true //flowModified, RuleAppend
751 }
752 return false, false //flowNotModified, NoRuleAppend
753}
754
755// VOL-3828 flow config sequence workaround ########### end ##########
756
mpagenko01e726e2020-10-23 09:45:29 +0000757//RemoveUniFlowParams verifies on existence of flow cookie,
758// if found removes cookie from flow cookie list and if this is empty
759// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000760func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000761 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000762 flowCookieMatch := false
763 //mutex protection is required for possible concurrent access to FSM members
764 oFsm.mutexFlowParams.Lock()
765 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000766remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000767 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
768 for i, cookie := range storedUniFlowParams.CookieSlice {
769 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000770 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000771 "device-id": oFsm.deviceID, "cookie": cookie})
772 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000773 deletedCookie = aCookie
774 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000775 //remove the cookie from the cookie slice and verify it is getting empty
776 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000777 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
778 var cancelPendingConfig bool = false
779 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000780 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000781 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000782 //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 +0000783 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000784 // 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 +0000785 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
786 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
mpagenkof1d21d12021-06-11 13:14:45 +0000787 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
mpagenko535d6ef2021-02-26 13:15:34 +0000788 log.Fields{"device-id": oFsm.deviceID})
789 cancelPendingConfig = true
790 } else {
791 //create a new element for the removeVlanFlow slice
792 loRemoveParams = uniRemoveVlanFlowParams{
793 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
794 cookie: aCookie,
795 }
mpagenkof1d21d12021-06-11 13:14:45 +0000796 loRemoveParams.removeChannel = make(chan bool)
mpagenko535d6ef2021-02-26 13:15:34 +0000797 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000798 }
mpagenko01e726e2020-10-23 09:45:29 +0000799
mpagenkof1d21d12021-06-11 13:14:45 +0000800 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000801 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
mpagenkof1d21d12021-06-11 13:14:45 +0000802 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000803 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
804 if !cancelPendingConfig {
mpagenkof1d21d12021-06-11 13:14:45 +0000805 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
806 "device-id": oFsm.deviceID})
807 if oFsm.pUniTechProf != nil {
808 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
809 }
mpagenko535d6ef2021-02-26 13:15:34 +0000810 }
mpagenko01e726e2020-10-23 09:45:29 +0000811 } else {
mpagenko535d6ef2021-02-26 13:15:34 +0000812 if !cancelPendingConfig {
813 oFsm.updateTechProfileToDelete(ctx, usedTpID)
814 }
mpagenko01e726e2020-10-23 09:45:29 +0000815 }
816 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000817 if cancelPendingConfig {
mpagenkof1d21d12021-06-11 13:14:45 +0000818 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
819 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
820 oFsm.removeFlowFromParamsSlice(ctx, aCookie, false) //call from 'non-configured' state of the rule
821
mpagenko535d6ef2021-02-26 13:15:34 +0000822 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenkobb47bc22021-04-20 13:29:09 +0000823 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
824 // synchronous FSM 'event/state' functions may rely on this mutex
825 oFsm.mutexFlowParams.Unlock()
826 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
827 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
828 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
829 }
830 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000831 } else {
832 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
833 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
834 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
835 "tp-id": loRemoveParams.vlanRuleParams.TpID,
836 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
837 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenkobb47bc22021-04-20 13:29:09 +0000838 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
839 // synchronous FSM 'event/state' functions may rely on this mutex
840 oFsm.mutexFlowParams.Unlock()
841 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
842 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
843 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
844 }
845 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000846 } // if not in the appropriate state a new entry will be automatically considered later
847 // when the configDone state is reached
848 }
mpagenko01e726e2020-10-23 09:45:29 +0000849 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000850 //cut off the requested cookie by slicing out this element
851 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
852 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
853 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000854 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000855 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000856 // state transition notification is checked in deviceHandler
857 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000858 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
859 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000860 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000861 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000862 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000863 if deletedCookie == oFsm.delayNewRuleCookie {
864 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
865 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
866 //simply use the first one
867 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
868 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
869 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
870 }
mpagenko01e726e2020-10-23 09:45:29 +0000871 }
mpagenko01e726e2020-10-23 09:45:29 +0000872 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000873 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000874 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
875 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000876 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000877 return err
878 }
mpagenko01e726e2020-10-23 09:45:29 +0000879 }
mpagenkof1fc3862021-02-16 10:09:52 +0000880 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000881 }
882 }
mpagenko01e726e2020-10-23 09:45:29 +0000883 } //search all flows
884 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000885 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000886 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
887 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000888 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
889 // state transition notification is checked in deviceHandler
890 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000891 // success indication without the need to write to kvStore (no change)
892 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000893 }
mpagenko01e726e2020-10-23 09:45:29 +0000894 return nil
895 } //unknown cookie
896
897 return nil
898}
899
mpagenkof1d21d12021-06-11 13:14:45 +0000900//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
901// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
902// from the start of the deletion request to avoid to much interference
903// so when called, there can only be one cookie active for this flow
904// requires mutexFlowParams to be locked at call
905func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) {
906 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
907 "device-id": oFsm.deviceID, "cookie": aCookie})
908removeFromSlice_loop:
909 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
910 // if UniFlowParams exists, cookieSlice is assumed to have always at least one element
911 if storedUniFlowParams.CookieSlice[0] == aCookie {
912 if len(storedUniFlowParams.CookieSlice) != 1 {
913 errStr := "UniVlanConfigFsm flow removal from ParamsSlice abort - unexpected cookie slice length"
914 logger.Errorw(ctx, errStr, log.Fields{
915 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
916 return
917 }
918 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
919 "device-id": oFsm.deviceID, "cookie": aCookie})
920 //remove the actual element from the addVlanFlow slice
921 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
922 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
923 oFsm.numUniFlows = 0 //no more flows
924 oFsm.configuredUniFlow = 0 //no more flows configured
925 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
926 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
927 //request that this profile gets deleted before a new flow add is allowed
928 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
929 "device-id": oFsm.deviceID})
930 } else {
931 oFsm.numUniFlows--
932 if aWasConfigured && oFsm.configuredUniFlow > 0 {
933 oFsm.configuredUniFlow--
934 }
935 //cut off the requested flow by slicing out this element
936 oFsm.uniVlanFlowParamsSlice = append(
937 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
938 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
939 "device-id": oFsm.deviceID})
940 }
941 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
942 }
943 } //search all flows
944}
945
946// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +0000947func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
948 //here we have to check, if there are still other flows referencing to the actual ProfileId
949 // before we can request that this profile gets deleted before a new flow add is allowed
950 tpIDInOtherFlows := false
951 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
952 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
953 tpIDInOtherFlows = true
954 break // search loop can be left
955 }
956 }
957 if tpIDInOtherFlows {
958 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
959 "device-id": oFsm.deviceID, "tp-id": usedTpID})
960 } else {
mpagenkof1d21d12021-06-11 13:14:45 +0000961 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore - set TechProfile to-delete", log.Fields{
mpagenkof1fc3862021-02-16 10:09:52 +0000962 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenkof1d21d12021-06-11 13:14:45 +0000963 if oFsm.pUniTechProf != nil {
964 //request that this profile gets deleted before a new flow add is allowed
965 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
966 }
mpagenkof1fc3862021-02-16 10:09:52 +0000967 }
968}
969
mpagenkof1d21d12021-06-11 13:14:45 +0000970func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
971 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000972
973 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000974 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000975 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000976 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000977 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000978 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000979 //let the state machine run forward from here directly
980 pConfigVlanStateAFsm := oFsm.pAdaptFsm
981 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000982 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
983 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
984 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +0000985 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000986 go func(a_pAFsm *AdapterFsm) {
987 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
988 }(pConfigVlanStateAFsm)
989 return
990 }
mpagenkof1d21d12021-06-11 13:14:45 +0000991 // Can't call FSM Event directly, decoupling it
992 go func(a_pAFsm *AdapterFsm) {
993 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
994 }(pConfigVlanStateAFsm)
995 return
996 }
997 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
998 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
999 //should never happen, else: recovery would be needed from outside the FSM
1000}
1001
1002func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1003 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1004 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1005 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001006 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001007 //possibly the entry is not valid anymore based on intermediate delete requests
1008 //just a basic protection ...
1009 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1010 oFsm.mutexFlowParams.Unlock()
1011 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1012 "device-id": oFsm.deviceID})
1013 // Can't call FSM Event directly, decoupling it
1014 go func(a_pAFsm *AdapterFsm) {
1015 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1016 }(pConfigVlanStateAFsm)
1017 return
1018 }
mpagenko9a304ea2020-12-16 15:54:01 +00001019 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1020 //store the actual rule that shall be worked upon in the following transient states
1021 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +00001022 tpID := oFsm.actualUniVlanConfigRule.TpID
1023 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001024 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001025 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1026 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1027 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +00001028 //cmp also usage in EVTOCDE create in omci_cc
1029 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +00001030 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001031 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001032 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1033 if aPAFsm != nil && aPAFsm.pFsm != nil {
1034 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001035 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001036 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001037 } else {
1038 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001039 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001040 }
1041 }
mpagenko551a4d42020-12-08 18:09:20 +00001042 }(pConfigVlanStateAFsm, loTechProfDone)
1043 } else {
1044 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1045 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1046 //should never happen, else: recovery would be needed from outside the FSM
1047 return
mpagenkodff5dda2020-08-28 11:52:01 +00001048 }
1049}
1050
dbainbri4d3a0dc2020-12-02 00:33:42 +00001051func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001052 //mutex protection is required for possible concurrent access to FSM members
1053 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001054 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001055 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001056 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001057 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001058 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001059 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001060 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001061 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001062 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001063 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301064 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001065 }(pConfigVlanStateAFsm)
1066 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001067 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1068 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001069 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001070 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001071 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001072 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1073 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001074 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001075 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001076 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001077 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001078 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1079 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001080 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001081 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001082 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001083 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1084 "ForwardOperation": uint8(0x10), //VID investigation
1085 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001086 },
1087 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001089 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001090 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001091 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001092 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001093 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001094 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001095 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1096 log.Fields{"device-id": oFsm.deviceID})
1097 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1098 if pConfigVlanStateAFsm != nil {
1099 go func(a_pAFsm *AdapterFsm) {
1100 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1101 }(pConfigVlanStateAFsm)
1102 }
1103 return
1104 }
mpagenkodff5dda2020-08-28 11:52:01 +00001105 //accept also nil as (error) return value for writing to LastTx
1106 // - this avoids misinterpretation of new received OMCI messages
1107 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1108 // send shall return (dual format) error code that can be used here for immediate error treatment
1109 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001110 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001111 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001112 }
1113}
1114
dbainbri4d3a0dc2020-12-02 00:33:42 +00001115func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1116 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001117 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001118 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001119 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001120 //using the first element in the slice because it's the first flow per definition here
1121 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001122 //This is correct passing scenario
1123 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001124 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001125 tpID := oFsm.actualUniVlanConfigRule.TpID
1126 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001127 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1128 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001129 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenkof1d21d12021-06-11 13:14:45 +00001130 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001131 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001132 vlanID)
1133 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001134 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001135 log.Fields{"device-id": oFsm.deviceID})
1136 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1137 }
mpagenkof1d21d12021-06-11 13:14:45 +00001138 oFsm.mutexFlowParams.RLock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001139 }
mpagenkof1d21d12021-06-11 13:14:45 +00001140 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001141 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1142 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1143 }
1144 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001145}
1146
dbainbri4d3a0dc2020-12-02 00:33:42 +00001147func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001148
mpagenkof1d21d12021-06-11 13:14:45 +00001149 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001150
mpagenkof1fc3862021-02-16 10:09:52 +00001151 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001152 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001153 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1154 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1155 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001156 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001157 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1158 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1159 //should never happen, else: recovery would be needed from outside the FSM
1160 return
1161 }
1162 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001163 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1164 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001165 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1166 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1167 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1168 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001169 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001170 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001171 go func(a_pBaseFsm *fsm.FSM) {
1172 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1173 }(pConfigVlanStateBaseFsm)
1174 return
1175 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001176 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1177 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001178 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001179 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001180 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001181 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1182 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001183 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1184 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001185 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001186 return
1187 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001188 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001189 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001190 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001191 // this is a restart with a complete new flow, we can re-use the initial flow config control
1192 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001193 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001194 go func(a_pBaseFsm *fsm.FSM) {
1195 _ = a_pBaseFsm.Event(vlanEvRenew)
1196 }(pConfigVlanStateBaseFsm)
1197 return
1198 }
1199
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001200 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001201 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001202 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1203 //check introduced after having observed some panic in this processing
1204 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1205 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1206 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1207 oFsm.mutexFlowParams.Unlock()
1208 go func(a_pAFsm *AdapterFsm) {
1209 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1210 }(pConfigVlanStateAFsm)
1211 return
1212 }
mpagenko9a304ea2020-12-16 15:54:01 +00001213 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001214 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001215 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001216 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001217 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001218 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1219 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1220 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkof1d21d12021-06-11 13:14:45 +00001221 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001222 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001223 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1224 if aTechProfDone {
1225 // let the vlan processing continue with next rule
1226 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1227 } else {
1228 // set to waiting for Techprofile
1229 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1230 }
1231 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001232 return
1233 }
mpagenkof1d21d12021-06-11 13:14:45 +00001234 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001236 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001237 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1238 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001239 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001240 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001241 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001243 }
1244}
1245
dbainbri4d3a0dc2020-12-02 00:33:42 +00001246func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001247
1248 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1249 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1250 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1251 go func(a_pBaseFsm *fsm.FSM) {
1252 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1253 }(oFsm.pAdaptFsm.pFsm)
1254 return
1255 }
mpagenko15ff4a52021-03-02 10:09:20 +00001256 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001257 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001258 "recent flow-number": oFsm.configuredUniFlow,
1259 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001260 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001261
mpagenko9a304ea2020-12-16 15:54:01 +00001262 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001263 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001265 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001266 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001267 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1268 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1269 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1270 // in practice should have no influence by now as no other state transition is currently accepted (while cancel() is ensured)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001271 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001272 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1273 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001274 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001275 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001276 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001277 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001278 "device-id": oFsm.deviceID,
1279 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001280 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001281 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001282
mpagenko01e726e2020-10-23 09:45:29 +00001283 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001284 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1285 oFsm.numVlanFilterEntries = 1
1286 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001287 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001288 Attributes: me.AttributeValueMap{
1289 "VlanFilterList": vtfdFilterList,
1290 "ForwardOperation": uint8(0x10), //VID investigation
1291 "NumberOfEntries": oFsm.numVlanFilterEntries,
1292 },
1293 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001294 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001295 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001296 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001297 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001298 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001299 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001300 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1301 log.Fields{"device-id": oFsm.deviceID})
1302 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1303 if pConfigVlanStateAFsm != nil {
1304 go func(a_pAFsm *AdapterFsm) {
1305 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1306 }(pConfigVlanStateAFsm)
1307 }
1308 return
1309 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001310 //accept also nil as (error) return value for writing to LastTx
1311 // - this avoids misinterpretation of new received OMCI messages
1312 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1313 // send shall return (dual format) error code that can be used here for immediate error treatment
1314 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001315 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001316 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001317 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001318 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1319 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001320 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001321
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001323 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001324 "device-id": oFsm.deviceID,
1325 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001326 // setVid is assumed to be masked already by the caller to 12 bit
1327 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001328 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001329 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001330
1331 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1332 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1333 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001334 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001335
1336 oFsm.numVlanFilterEntries++
1337 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001338 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001339 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001340 "VlanFilterList": vtfdFilterList,
1341 "ForwardOperation": uint8(0x10), //VID investigation
1342 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001343 },
1344 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001345 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001346 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001347 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001348 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001349 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001350 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001351 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1352 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1353 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1354 return
1355 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001356 //accept also nil as (error) return value for writing to LastTx
1357 // - this avoids misinterpretation of new received OMCI messages
1358 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1359 // send shall return (dual format) error code that can be used here for immediate error treatment
1360 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001361 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001362 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001363 }
1364 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001365 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001366 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001367 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001369 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001370 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001371 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001372 go func(a_pBaseFsm *fsm.FSM) {
1373 _ = a_pBaseFsm.Event(vlanEvReset)
1374 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001375 return
1376 }
1377 }
mpagenkof1d21d12021-06-11 13:14:45 +00001378
mpagenkof1fc3862021-02-16 10:09:52 +00001379 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001380 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001381 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001382 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001383 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001384 configuredUniFlow := oFsm.configuredUniFlow
1385 oFsm.mutexFlowParams.RUnlock()
1386 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001387 //This is correct passing scenario
1388 if errEvto == nil {
1389 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001390 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001391 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001392 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001394 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001395 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001396 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001397 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001398 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001399 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001400 log.Fields{"device-id": oFsm.deviceID})
1401 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1402 }
1403 }
1404 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1405 }
1406 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001407}
1408
dbainbri4d3a0dc2020-12-02 00:33:42 +00001409func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001410 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001412 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1413 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001414
mpagenkofc4f56e2020-11-04 17:17:49 +00001415 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001416 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001417 loVlanEntryClear := uint8(0)
1418 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1419 //shallow copy is sufficient as no reference variables are used within struct
1420 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001421 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001422 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001423 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1424 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1425 "device-id": oFsm.deviceID})
1426
1427 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1428 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001429 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001430 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1431 } else {
1432 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1433 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001434 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001435 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1436 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001437 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001438 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001439 "device-id": oFsm.deviceID,
1440 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001441 loVlanEntryClear = 1 //full VlanFilter clear request
1442 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001443 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001444 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001445 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001446 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001447 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001448 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1449 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1450 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1451 return
1452 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001453 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001454 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001455 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001456 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001457 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001458 }
mpagenko01e726e2020-10-23 09:45:29 +00001459 } else {
1460 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1461 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001462 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001463 log.Fields{"current vlan list": oFsm.vlanFilterList,
1464 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1465 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1466 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1467 loVlanEntryRmPos = i
1468 break //abort search
1469 }
1470 }
1471 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001472 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001473 //valid entry was found - to be eclipsed
1474 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1475 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1476 if i < loVlanEntryRmPos {
1477 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1478 } else if i < (cVtfdTableSize - 1) {
1479 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1480 } else {
1481 vtfdFilterList[i] = 0 //set last byte if needed
1482 }
1483 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001484 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001485 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001486 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1487 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001488
mpagenkofc4f56e2020-11-04 17:17:49 +00001489 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001490 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001491 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001492 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001493 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001494 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001495 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001496 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1497 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1498 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1499 return
1500 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001501 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001502 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001503 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001504 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001505 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001506 }
mpagenko01e726e2020-10-23 09:45:29 +00001507 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001509 log.Fields{"device-id": oFsm.deviceID})
1510 }
1511 }
1512 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001513 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1514 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001516 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001517 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001518 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001519 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001520 go func(a_pBaseFsm *fsm.FSM) {
1521 _ = a_pBaseFsm.Event(vlanEvReset)
1522 }(pConfigVlanStateBaseFsm)
1523 return
1524 }
mpagenko01e726e2020-10-23 09:45:29 +00001525 }
1526
mpagenko15ff4a52021-03-02 10:09:20 +00001527 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001528 if loVlanEntryClear == 1 {
1529 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1530 oFsm.numVlanFilterEntries = 0
1531 } else if loVlanEntryClear == 2 {
1532 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1533 // this loop now includes the 0 element on previous last valid entry
1534 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1535 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1536 }
1537 oFsm.numVlanFilterEntries--
1538 }
mpagenko15ff4a52021-03-02 10:09:20 +00001539 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001540 }
1541 }
1542
mpagenkofc4f56e2020-11-04 17:17:49 +00001543 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001544 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001545 } else {
1546 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001548 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001549 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001550 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001551 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001552 }(pConfigVlanStateBaseFsm)
1553 }
mpagenkodff5dda2020-08-28 11:52:01 +00001554}
1555
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001557 var tpID uint8
1558 // Extract the tpID
1559 if len(e.Args) > 0 {
1560 tpID = e.Args[0].(uint8)
1561 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1562 } else {
1563 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1564 }
mpagenko01e726e2020-10-23 09:45:29 +00001565 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001566 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001567
1568 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1569 // stop the suspension of a add-activity waiting for the end of removal
1570 oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true) //call from 'configured' state of the rule
1571 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1572 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1573 oFsm.mutexFlowParams.Unlock()
1574 removeChannel <- true
1575 oFsm.mutexFlowParams.Lock()
1576 }
1577
mpagenkof1fc3862021-02-16 10:09:52 +00001578 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1579 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1580 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1581
mpagenko01e726e2020-10-23 09:45:29 +00001582 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1583 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001584 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001585 "device-id": oFsm.deviceID})
1586 } else {
1587 //cut off the actual flow by slicing out the first element
1588 oFsm.uniRemoveFlowsSlice = append(
1589 oFsm.uniRemoveFlowsSlice[:0],
1590 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001591 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001592 "device-id": oFsm.deviceID})
1593 }
1594 oFsm.mutexFlowParams.Unlock()
1595
mpagenkof1fc3862021-02-16 10:09:52 +00001596 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001597 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001598 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1599 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001600 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001601 go func(a_pAFsm *AdapterFsm) {
1602 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001603 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001604 }
1605 }(pConfigVlanStateAFsm)
1606 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001607
mpagenkobb47bc22021-04-20 13:29:09 +00001608 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001609 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001610 if deletedCookie == oFsm.delayNewRuleCookie {
1611 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1612 select {
1613 case <-oFsm.chCookieDeleted:
1614 logger.Debug(ctx, "flushed CookieDeleted")
1615 default:
1616 }
1617 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1618 }
mpagenkobb47bc22021-04-20 13:29:09 +00001619 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1620 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1621 logger.Debugw(ctx, "signal flow removal for pending TP delete", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID})
Girish Gowdra26a40922021-01-29 17:14:34 -08001622 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001623 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1624 oFsm.flowDeleteChannel <- true
1625 oFsm.signalOnFlowDelete = false
1626 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001627 }
mpagenkobb47bc22021-04-20 13:29:09 +00001628 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001629}
1630
dbainbri4d3a0dc2020-12-02 00:33:42 +00001631func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1632 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001633
1634 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1635 if pConfigVlanStateAFsm != nil {
1636 // abort running message processing
1637 fsmAbortMsg := Message{
1638 Type: TestMsg,
1639 Data: TestMessage{
1640 TestMessageVal: AbortMessageProcessing,
1641 },
1642 }
1643 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1644
mpagenko9a304ea2020-12-16 15:54:01 +00001645 //try to restart the FSM to 'disabled'
1646 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001647 go func(a_pAFsm *AdapterFsm) {
1648 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301649 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001650 }
1651 }(pConfigVlanStateAFsm)
1652 }
1653}
1654
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1656 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001657 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001658 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001659 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001660
1661 oFsm.mutexFlowParams.RLock()
1662 if oFsm.delayNewRuleCookie != 0 {
1663 // looks like the waiting AddFlow is stuck
1664 oFsm.mutexFlowParams.RUnlock()
1665 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/terminate
1666 oFsm.mutexFlowParams.RLock()
1667 }
1668 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1669 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1670 if removeUniFlowParams.isSuspendedOnAdd {
1671 removeChannel := removeUniFlowParams.removeChannel
1672 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1673 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1674 oFsm.mutexFlowParams.RUnlock()
1675 removeChannel <- false
1676 oFsm.mutexFlowParams.RLock()
1677 }
1678 }
1679 }
1680
mpagenkodff5dda2020-08-28 11:52:01 +00001681 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001682 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1683 // current code removes the complete FSM including all flow/rule configuration done so far
1684 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1685 // maybe a more sophisticated approach is possible without clearing the data
1686 if oFsm.clearPersistency {
1687 //permanently remove possibly stored persistent data
1688 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1689 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001690 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001691 }
1692 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001693 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001694 }
mpagenko9a304ea2020-12-16 15:54:01 +00001695 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001696 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001697 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001698 return
mpagenkodff5dda2020-08-28 11:52:01 +00001699 }
mpagenkof1d21d12021-06-11 13:14:45 +00001700 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001701}
1702
dbainbri4d3a0dc2020-12-02 00:33:42 +00001703func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1704 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001705loop:
1706 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001707 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001709 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301710 message, ok := <-oFsm.pAdaptFsm.commChan
1711 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001712 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301713 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1714 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1715 break loop
1716 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301718
1719 switch message.Type {
1720 case TestMsg:
1721 msg, _ := message.Data.(TestMessage)
1722 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001723 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001724 break loop
1725 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001726 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301727 case OMCI:
1728 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001729 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301730 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001731 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301732 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001733 }
1734 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001735 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001736}
1737
dbainbri4d3a0dc2020-12-02 00:33:42 +00001738func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1739 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001740 "msgType": msg.OmciMsg.MessageType})
1741
1742 switch msg.OmciMsg.MessageType {
1743 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001744 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001745 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1746 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001747 return
1748 }
mpagenkodff5dda2020-08-28 11:52:01 +00001749 } //CreateResponseType
1750 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001751 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001752 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1753 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001754 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001755 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001756 return
1757 }
1758 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1759 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001760 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001761 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001762 return
1763 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001764 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001765 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001767 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001768 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1769 return
1770 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001771 oFsm.mutexPLastTxMeInstance.RLock()
1772 if oFsm.pLastTxMeInstance != nil {
1773 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1774 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1775 switch oFsm.pLastTxMeInstance.GetName() {
1776 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
1777 { // let the MultiEntity config proceed by stopping the wait function
1778 oFsm.mutexPLastTxMeInstance.RUnlock()
1779 oFsm.omciMIdsResponseReceived <- true
1780 return
1781 }
1782 default:
1783 {
1784 logger.Warnw(ctx, "Unsupported ME name received!",
1785 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1786 }
mpagenkodff5dda2020-08-28 11:52:01 +00001787 }
1788 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001789 } else {
1790 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001791 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001792 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001793 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001794 case omci.DeleteResponseType:
1795 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1797 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001798 return
1799 }
1800 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001801 default:
1802 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001804 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001805 return
1806 }
1807 }
1808}
1809
dbainbri4d3a0dc2020-12-02 00:33:42 +00001810func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001811 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1812 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001813 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001814 log.Fields{"device-id": oFsm.deviceID})
1815 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1816 oFsm.deviceID)
1817 }
1818 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1819 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001820 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001821 log.Fields{"device-id": oFsm.deviceID})
1822 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1823 oFsm.deviceID)
1824 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001825 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001826 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001827 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001828 "Error": msgObj.Result})
1829 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1830 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1831 oFsm.deviceID)
1832 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001833 oFsm.mutexPLastTxMeInstance.RLock()
1834 if oFsm.pLastTxMeInstance != nil {
1835 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1836 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1837 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1838 switch oFsm.pLastTxMeInstance.GetName() {
1839 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1840 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1841 "ExtendedVlanTaggingOperationConfigurationData":
1842 {
1843 oFsm.mutexPLastTxMeInstance.RUnlock()
1844 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1845 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1846 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1847 } else { // let the MultiEntity config proceed by stopping the wait function
1848 oFsm.omciMIdsResponseReceived <- true
1849 }
1850 return nil
1851 }
1852 default:
1853 {
1854 logger.Warnw(ctx, "Unsupported ME name received!",
1855 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001856 }
1857 }
1858 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001859 } else {
1860 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001861 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001862 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001863 return nil
1864}
1865
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001867 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1868 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001870 log.Fields{"device-id": oFsm.deviceID})
1871 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1872 oFsm.deviceID)
1873 }
1874 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1875 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001877 log.Fields{"device-id": oFsm.deviceID})
1878 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1879 oFsm.deviceID)
1880 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001882 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001884 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1885 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1886 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1887 oFsm.deviceID)
1888 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001889 oFsm.mutexPLastTxMeInstance.RLock()
1890 if oFsm.pLastTxMeInstance != nil {
1891 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1892 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1893 switch oFsm.pLastTxMeInstance.GetName() {
1894 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
1895 { // let the MultiEntity config proceed by stopping the wait function
1896 oFsm.mutexPLastTxMeInstance.RUnlock()
1897 oFsm.omciMIdsResponseReceived <- true
1898 return nil
1899 }
1900 default:
1901 {
1902 logger.Warnw(ctx, "Unsupported ME name received!",
1903 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1904 }
mpagenko01e726e2020-10-23 09:45:29 +00001905 }
1906 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001907 } else {
1908 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001909 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001910 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001911 return nil
1912}
1913
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001915 oFsm.mutexFlowParams.RLock()
1916 evtocdID := oFsm.evtocdID
1917 oFsm.mutexFlowParams.RUnlock()
1918
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001919 if aFlowEntryNo == 0 {
1920 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001921 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1922 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001923 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001924 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00001925 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001926 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001927 associationType := 2 // default to uniPPTP
1928 if oFsm.pOnuUniPort.portType == uniVEIP {
1929 associationType = 10
1930 }
1931 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001932 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00001933 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001934 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001935 "AssociationType": uint8(associationType),
1936 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001937 },
1938 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001939 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001940 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
1941 true, oFsm.pAdaptFsm.commChan, meParams)
1942 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001943 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001944 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
1945 log.Fields{"device-id": oFsm.deviceID})
1946 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1947 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
1948 }
mpagenkodff5dda2020-08-28 11:52:01 +00001949 //accept also nil as (error) return value for writing to LastTx
1950 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001951 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001952 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001953
1954 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001955 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001956 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001957 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001958 log.Fields{"device-id": oFsm.deviceID})
1959 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1960 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1961 }
1962
1963 // Set the EVTOCD ME default params
1964 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00001965 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001966 Attributes: me.AttributeValueMap{
1967 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1968 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1969 "DownstreamMode": uint8(cDefaultDownstreamMode),
1970 },
1971 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001972 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001973 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1974 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001975 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001976 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001977 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001978 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1979 log.Fields{"device-id": oFsm.deviceID})
1980 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1981 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1982 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001983 //accept also nil as (error) return value for writing to LastTx
1984 // - this avoids misinterpretation of new received OMCI messages
1985 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001986 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001987
1988 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001990 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001991 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001992 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301993 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001994 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001995 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001996 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001997
mpagenko551a4d42020-12-08 18:09:20 +00001998 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001999 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002000 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002001 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002002 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002003 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002004 sliceEvtocdRule := make([]uint8, 16)
2005 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2006 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2007 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2008 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2009 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2010
2011 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2012 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2013 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2014 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2015 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2016
2017 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2018 0<<cTreatTTROffset| // Do not pop any tags
2019 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2020 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2021 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2022
2023 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2024 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2025 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2026 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2027
2028 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002029 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002030 Attributes: me.AttributeValueMap{
2031 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2032 },
2033 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002034 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002035 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2036 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002037 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002038 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002039 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002040 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2041 log.Fields{"device-id": oFsm.deviceID})
2042 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2043 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2044 }
mpagenkodff5dda2020-08-28 11:52:01 +00002045 //accept also nil as (error) return value for writing to LastTx
2046 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002047 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002048 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002049
2050 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002051 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002052 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002053 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002054 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302055 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002056 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2057
mpagenkodff5dda2020-08-28 11:52:01 +00002058 }
2059 } else {
2060 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2061 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002062 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2063 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2064 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2065 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002066 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002067 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002068 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002069 sliceEvtocdRule := make([]uint8, 16)
2070 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2071 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2072 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2073 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2074 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2075
2076 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002077 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2078 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002079 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2080 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2081
2082 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002083 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002084 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2085 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2086 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2087
2088 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002089 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2090 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002091 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002092 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002093
2094 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002095 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002096 Attributes: me.AttributeValueMap{
2097 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2098 },
2099 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002100 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002101 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2102 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002103 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002104 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002105 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002106 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2107 log.Fields{"device-id": oFsm.deviceID})
2108 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2109 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2110 }
mpagenkodff5dda2020-08-28 11:52:01 +00002111 //accept also nil as (error) return value for writing to LastTx
2112 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002113 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002114 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002115
2116 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002117 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002118 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002119 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002120 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302121 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002122 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002123 }
2124 } else {
2125 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2126 { // just for local var's
2127 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002128 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002129 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002130 sliceEvtocdRule := make([]uint8, 16)
2131 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2132 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2133 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2134 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2135 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2136
2137 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2138 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2139 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2140 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2141 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2142
2143 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2144 0<<cTreatTTROffset| // Do not pop any tags
2145 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2146 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2147 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2148
2149 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2150 0<<cTreatPrioOffset| // vlan prio set to 0
2151 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002152 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002153 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2154
mpagenko551a4d42020-12-08 18:09:20 +00002155 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002156 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002157 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002158 Attributes: me.AttributeValueMap{
2159 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2160 },
2161 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002162 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002163 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2164 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002165 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002166 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002167 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002168 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2169 log.Fields{"device-id": oFsm.deviceID})
2170 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2171 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2172 }
mpagenkodff5dda2020-08-28 11:52:01 +00002173 //accept also nil as (error) return value for writing to LastTx
2174 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002175 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002176 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002177
2178 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002179 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002180 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002181 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002182 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302183 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002184 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2185
mpagenkodff5dda2020-08-28 11:52:01 +00002186 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002187 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002188 { // just for local var's
2189 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002190 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002191 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002192 sliceEvtocdRule := make([]uint8, 16)
2193 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2194 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2195 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2196 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2197 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2198
2199 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2200 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2201 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2202 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2203 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2204
2205 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2206 1<<cTreatTTROffset| // pop the prio-tag
2207 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2208 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2209 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2210
mpagenko551a4d42020-12-08 18:09:20 +00002211 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002212 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2213 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2214 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002215 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002216 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002217 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002218
2219 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002220 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002221 Attributes: me.AttributeValueMap{
2222 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2223 },
2224 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002225 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002226 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2227 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002228 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002229 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002230 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002231 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2232 log.Fields{"device-id": oFsm.deviceID})
2233 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2234 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2235 }
mpagenkodff5dda2020-08-28 11:52:01 +00002236 //accept also nil as (error) return value for writing to LastTx
2237 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002238 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002239 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002240
2241 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002242 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002243 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002244 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002245 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302246 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002247 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2248
mpagenkodff5dda2020-08-28 11:52:01 +00002249 }
2250 } //just for local var's
2251 }
2252 }
2253
mpagenkofc4f56e2020-11-04 17:17:49 +00002254 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002255 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002256 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002257 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002258 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002259 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002260}
2261
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002263 oFsm.mutexFlowParams.RLock()
2264 evtocdID := oFsm.evtocdID
2265 oFsm.mutexFlowParams.RUnlock()
2266
mpagenko01e726e2020-10-23 09:45:29 +00002267 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2268 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2269 //transparent transmission was set
2270 //perhaps the config is not needed for removal,
2271 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002272 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002273 "device-id": oFsm.deviceID})
2274 sliceEvtocdRule := make([]uint8, 16)
2275 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2276 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2277 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2278 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2279 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2280
2281 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2282 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2283 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2284 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2285 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2286
2287 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2288 0<<cTreatTTROffset| // Do not pop any tags
2289 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2290 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2291 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2292
2293 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2294 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2295 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2296 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2297
2298 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002299 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002300 Attributes: me.AttributeValueMap{
2301 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2302 },
2303 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002304 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002305 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2306 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002307 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002308 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002309 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2311 log.Fields{"device-id": oFsm.deviceID})
2312 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2313 return
2314 }
mpagenko01e726e2020-10-23 09:45:29 +00002315 //accept also nil as (error) return value for writing to LastTx
2316 // - this avoids misinterpretation of new received OMCI messages
2317 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002318 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002319
2320 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002321 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002322 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002323 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002324 log.Fields{"device-id": oFsm.deviceID})
2325 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2326 return
2327 }
2328 } else {
2329 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002330 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002331 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002332 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002333 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002334 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002335 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2336 sliceEvtocdRule := make([]uint8, 16)
2337 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2338 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2339 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2340 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2341 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2342
2343 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2344 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2345 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2346 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2347 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2348
2349 // delete indication for the indicated Filter
2350 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2351 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2352
2353 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002354 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002355 Attributes: me.AttributeValueMap{
2356 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2357 },
2358 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002359 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002360 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2361 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002362 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002363 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002364 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002365 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2366 log.Fields{"device-id": oFsm.deviceID})
2367 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2368 return
2369 }
mpagenko01e726e2020-10-23 09:45:29 +00002370 //accept also nil as (error) return value for writing to LastTx
2371 // - this avoids misinterpretation of new received OMCI messages
2372 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002373 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002374
2375 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002376 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002377 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002378 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002379 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2380 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2381 return
2382 }
2383 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002384 // VOL-3685
2385 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2386 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2387 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2388 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2389 // later when the flow is being re-installed.
2390 // Of course this is applicable to case only where single service (or single tcont) is in use and
2391 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2392 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2393 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002394 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2395 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002396 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002397 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2398 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002399 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002400 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002401 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002402 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002403 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2404 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002405 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002406 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002407 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002408 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2409 log.Fields{"device-id": oFsm.deviceID})
2410 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2411 return
2412 }
mpagenko01e726e2020-10-23 09:45:29 +00002413 //accept also nil as (error) return value for writing to LastTx
2414 // - this avoids misinterpretation of new received OMCI messages
2415 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002416 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002417
2418 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002419 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002420 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002421 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002422 log.Fields{"device-id": oFsm.deviceID})
2423 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2424 return
2425 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002426 } else {
2427 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2428 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002429 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002430 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002431 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002432 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2433 { // just for local var's
2434 // this defines stacking scenario: untagged->singletagged
2435 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2436 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2437 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2438 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002439 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002440 "device-id": oFsm.deviceID})
2441 sliceEvtocdRule := make([]uint8, 16)
2442 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2443 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2444 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2445 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2446 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002447
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002448 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2449 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2450 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2451 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2452 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002453
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002454 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2455 0<<cTreatTTROffset| // Do not pop any tags
2456 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2457 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2458 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002459
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002460 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2461 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2462 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2463 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002464
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002465 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002466 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002467 Attributes: me.AttributeValueMap{
2468 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2469 },
2470 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002471 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2472 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002473 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002474 if err != nil {
2475 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2476 log.Fields{"device-id": oFsm.deviceID})
2477 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2478 return
2479 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002480 //accept also nil as (error) return value for writing to LastTx
2481 // - this avoids misinterpretation of new received OMCI messages
2482 oFsm.pLastTxMeInstance = meInstance
2483
2484 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002485 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002486 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002488 log.Fields{"device-id": oFsm.deviceID})
2489 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2490 return
2491 }
2492 } // just for local var's
2493 { // just for local var's
2494 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002495 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002496 "device-id": oFsm.deviceID})
2497 sliceEvtocdRule := make([]uint8, 16)
2498 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2499 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2500 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2501 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2502 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2503
2504 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2505 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2506 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2507 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2508 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2509
2510 // delete indication for the indicated Filter
2511 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2512 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2513
2514 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002515 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002516 Attributes: me.AttributeValueMap{
2517 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2518 },
2519 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002520 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002521 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2522 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002523 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002524 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002525 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002526 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2527 log.Fields{"device-id": oFsm.deviceID})
2528 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2529 return
2530 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002531 //accept also nil as (error) return value for writing to LastTx
2532 // - this avoids misinterpretation of new received OMCI messages
2533 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002534 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002535
2536 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002537 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002538 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002539 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002540 log.Fields{"device-id": oFsm.deviceID})
2541 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2542 return
2543 }
mpagenko01e726e2020-10-23 09:45:29 +00002544 }
2545 } //just for local var's
2546 }
2547 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002548 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002549 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002550 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002551}
2552
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002554 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002555 if oFsm.isCanceled {
2556 // FSM already canceled before entering wait
2557 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2558 oFsm.mutexIsAwaitingResponse.Unlock()
2559 return fmt.Errorf(cErrWaitAborted)
2560 }
mpagenko7d6bb022021-03-11 15:07:55 +00002561 oFsm.isAwaitingResponse = true
2562 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002563 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302564 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002565 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002566 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002567 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002568 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002569 oFsm.mutexIsAwaitingResponse.Lock()
2570 oFsm.isAwaitingResponse = false
2571 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002572 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002573 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302574 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002575 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002576 oFsm.mutexIsAwaitingResponse.Lock()
2577 oFsm.isAwaitingResponse = false
2578 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002579 return nil
2580 }
mpagenko7d6bb022021-03-11 15:07:55 +00002581 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002582 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002583 oFsm.mutexIsAwaitingResponse.Lock()
2584 oFsm.isAwaitingResponse = false
2585 oFsm.mutexIsAwaitingResponse.Unlock()
2586 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002587 }
2588}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002589
mpagenko551a4d42020-12-08 18:09:20 +00002590func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002591 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002592 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002593 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002594 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002595 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002596 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002597 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002598 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2599 }
2600
dbainbri4d3a0dc2020-12-02 00:33:42 +00002601 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002602 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002603 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002604 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002605 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002606 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2607 }
2608
dbainbri4d3a0dc2020-12-02 00:33:42 +00002609 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002610 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002612 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002613 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002614 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2615 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002616 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2617 if errMacBpCdEID != nil {
2618 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2619 log.Fields{"device-id": oFsm.deviceID})
2620 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2621 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002622
Mahir Gunyel6781f962021-05-16 23:30:08 -07002623 }
2624 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2625 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2626 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002627 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002628 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002629 Attributes: me.AttributeValueMap{
2630 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2631 "PortNum": 0xf0, //fixed unique ANI side indication
2632 "TpType": 6, //MCGemIWTP
2633 "TpPointer": multicastGemPortID,
2634 },
2635 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002636 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002637 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2638 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2639 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002640 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002641 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2642 log.Fields{"device-id": oFsm.deviceID})
2643 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2644 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2645 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002646 //accept also nil as (error) return value for writing to LastTx
2647 // - this avoids misinterpretation of new received OMCI messages
2648 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002649 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002650 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002651 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002652 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002653 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002654 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002655 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2656 }
2657
2658 // ==> Start creating VTFD for mcast vlan
2659
2660 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2661 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002662 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002663
dbainbri4d3a0dc2020-12-02 00:33:42 +00002664 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002665 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2666 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2667 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2668
2669 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2670 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2671 // new vlan associated with a different TP.
2672 vtfdFilterList[0] = uint16(vlanID)
2673
2674 meParams = me.ParamData{
2675 EntityID: mcastVtfdID,
2676 Attributes: me.AttributeValueMap{
2677 "VlanFilterList": vtfdFilterList,
2678 "ForwardOperation": uint8(0x10), //VID investigation
2679 "NumberOfEntries": oFsm.numVlanFilterEntries,
2680 },
2681 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002682 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002683 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2684 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2685 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002686 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002687 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2688 log.Fields{"device-id": oFsm.deviceID})
2689 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2690 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2691 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002692 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002693 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002694 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002695 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002696 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002697 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002698 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002699 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2700 }
2701
2702 return nil
2703}
2704
dbainbri4d3a0dc2020-12-02 00:33:42 +00002705func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002706 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002707 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002708 logger.Errorw(ctx, "error generrating me instance id",
2709 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002710 return err
2711 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002712 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2713 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002714 meParams := me.ParamData{
2715 EntityID: instID,
2716 Attributes: me.AttributeValueMap{
2717 "MeType": 0,
2718 //Direct reference to the Operation profile
2719 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002720 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002721 },
2722 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002723 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002724 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2725 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002726 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002727 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002728 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002729 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2730 log.Fields{"device-id": oFsm.deviceID})
2731 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2732 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2733 oFsm.deviceID, err)
2734 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002735 //accept also nil as (error) return value for writing to LastTx
2736 // - this avoids misinterpretation of new received OMCI messages
2737 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002738 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002739 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002740 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002741 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002742 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002743 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2744 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2745 }
2746 return nil
2747}
2748
dbainbri4d3a0dc2020-12-02 00:33:42 +00002749func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002750 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2751 if err != nil {
2752 logger.Errorw(ctx, "error fetching uni port me instance",
2753 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2754 return err
2755 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002756 instID += macBridgePortAniBaseEID
2757 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2758 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002759 meParams := me.ParamData{
2760 EntityID: instID,
2761 Attributes: me.AttributeValueMap{
2762 "IgmpVersion": 2,
2763 "IgmpFunction": 0,
2764 //0 means false
2765 "ImmediateLeave": 0,
2766 "Robustness": 2,
2767 "QuerierIp": 0,
2768 "QueryInterval": 125,
2769 "QuerierMaxResponseTime": 100,
2770 "LastMemberResponseTime": 10,
2771 //0 means false
2772 "UnauthorizedJoinBehaviour": 0,
2773 },
2774 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002775 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002776 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2777 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002778 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002779 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002780 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002781 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2782 log.Fields{"device-id": oFsm.deviceID})
2783 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2784 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2785 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002786 //accept also nil as (error) return value for writing to LastTx
2787 // - this avoids misinterpretation of new received OMCI messages
2788 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002789 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002790 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002791 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002792 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002793 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002794 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002795 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002796 }
2797 return nil
2798}
2799
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002801 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2802 if err != nil {
2803 logger.Errorw(ctx, "error fetching uni port me instance",
2804 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2805 return err
2806 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002807 instID += macBridgePortAniBaseEID
2808 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2809 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002810 //TODO check that this is correct
2811 // Table control
2812 //setCtrl = 1
2813 //rowPartId = 0
2814 //test = 0
2815 //rowKey = 0
2816 tableCtrlStr := "0100000000000000"
2817 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002818 dynamicAccessCL := make([]uint8, 24)
2819 copy(dynamicAccessCL, tableCtrl)
2820 //Multicast GemPortId
2821 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2822 // python version waits for installation of flows, see line 723 onward of
2823 // brcm_openomci_onu_handler.py
2824 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2825 //Source IP all to 0
2826 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2827 //TODO start and end are hardcoded, get from TP
2828 // Destination IP address start of range
2829 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2830 // Destination IP address end of range
2831 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2832 //imputed group bandwidth
2833 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2834
2835 meParams := me.ParamData{
2836 EntityID: instID,
2837 Attributes: me.AttributeValueMap{
2838 "DynamicAccessControlListTable": dynamicAccessCL,
2839 },
2840 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002841 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002842 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2843 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002845 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002846 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002847 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2848 log.Fields{"device-id": oFsm.deviceID})
2849 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2850 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2851 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002852 //accept also nil as (error) return value for writing to LastTx
2853 // - this avoids misinterpretation of new received OMCI messages
2854 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002855 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002856 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002857 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002858 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002859 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002861 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002862 }
2863 return nil
2864}
Girish Gowdra26a40922021-01-29 17:14:34 -08002865
2866// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002867func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2868 oFsm.mutexFlowParams.Lock()
2869 defer oFsm.mutexFlowParams.Unlock()
2870 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2871 //flow removal is still ongoing/pending
2872 oFsm.signalOnFlowDelete = true
2873 oFsm.flowDeleteChannel = aFlowDeleteChannel
2874 return true
2875 }
2876 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002877}