blob: a18a216cf538c8a37697f847349265377b12fdc5 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/binary"
mpagenkof582d6a2021-06-18 15:58:10 +000023 "errors"
Andrea Campanella6515c582020-10-05 11:25:00 +020024 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030025 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028 "time"
29
mpagenko01e726e2020-10-23 09:45:29 +000030 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000031 "github.com/looplab/fsm"
32 "github.com/opencord/omci-lib-go"
33 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000034 "github.com/opencord/voltha-lib-go/v4/pkg/log"
35 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000036)
37
38const (
39 // internal predefined values
40 cDefaultDownstreamMode = 0
41 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000042 cVtfdTableSize = 12 //as per G.988
43 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000044)
45
46const (
mpagenkof1fc3862021-02-16 10:09:52 +000047 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
48 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
49 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
50 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
51 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
52)
53
54const (
mpagenkodff5dda2020-08-28 11:52:01 +000055 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
56 cFilterPrioOffset = 28
57 cFilterVidOffset = 15
58 cFilterTpidOffset = 12
59 cFilterEtherTypeOffset = 0
60 cTreatTTROffset = 30
61 cTreatPrioOffset = 16
62 cTreatVidOffset = 3
63 cTreatTpidOffset = 0
64)
65const (
66 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
67 cFilterOuterOffset = 0
68 cFilterInnerOffset = 4
69 cTreatOuterOffset = 8
70 cTreatInnerOffset = 12
71)
72const (
73 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
74 cPrioIgnoreTag uint32 = 15
75 cPrioDefaultFilter uint32 = 14
76 cPrioDoNotFilter uint32 = 8
77 cDoNotFilterVid uint32 = 4096
78 cDoNotFilterTPID uint32 = 0
79 cDoNotFilterEtherType uint32 = 0
80 cDoNotAddPrio uint32 = 15
81 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053082 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000083 cDontCareVid uint32 = 0
84 cDontCareTpid uint32 = 0
85 cSetOutputTpidCopyDei uint32 = 4
86)
87
88const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000089 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000090 vlanEvStart = "vlanEvStart"
mpagenkof1d21d12021-06-11 13:14:45 +000091 vlanEvPrepareDone = "vlanEvPrepareDone"
mpagenko535d6ef2021-02-26 13:15:34 +000092 vlanEvWaitTechProf = "vlanEvWaitTechProf"
93 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
94 vlanEvContinueConfig = "vlanEvContinueConfig"
95 vlanEvStartConfig = "vlanEvStartConfig"
96 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
97 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
98 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
99 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
100 vlanEvRenew = "vlanEvRenew"
101 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
102 vlanEvRemFlowDone = "vlanEvRemFlowDone"
103 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000104 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
105 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000106 vlanEvReset = "vlanEvReset"
107 vlanEvRestart = "vlanEvRestart"
108 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
109 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000110)
mpagenko01e726e2020-10-23 09:45:29 +0000111
mpagenkodff5dda2020-08-28 11:52:01 +0000112const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000113 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000114 vlanStDisabled = "vlanStDisabled"
mpagenkof1d21d12021-06-11 13:14:45 +0000115 vlanStPreparing = "vlanStPreparing"
mpagenkodff5dda2020-08-28 11:52:01 +0000116 vlanStStarting = "vlanStStarting"
117 vlanStWaitingTechProf = "vlanStWaitingTechProf"
118 vlanStConfigVtfd = "vlanStConfigVtfd"
119 vlanStConfigEvtocd = "vlanStConfigEvtocd"
120 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000121 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000122 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000123 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000124 vlanStCleanupDone = "vlanStCleanupDone"
125 vlanStResetting = "vlanStResetting"
126)
mpagenkof1fc3862021-02-16 10:09:52 +0000127const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
128const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000129
mpagenko01e726e2020-10-23 09:45:29 +0000130type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000131 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000132 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
133 MatchPcp uint32 `json:"match_pcp"`
134 TagsToRemove uint32 `json:"tags_to_remove"`
135 SetVid uint32 `json:"set_vid"`
136 SetPcp uint32 `json:"set_pcp"`
137}
138
139type uniVlanFlowParams struct {
140 CookieSlice []uint64 `json:"cookie_slice"`
141 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
142}
143
144type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000145 isSuspendedOnAdd bool
146 removeChannel chan bool
147 cookie uint64 //just the last cookie valid for removal
148 vlanRuleParams uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000149}
150
mpagenkobb47bc22021-04-20 13:29:09 +0000151//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
152// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000153type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530154 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000155 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530156 pOmciCC *omciCC
157 pOnuUniPort *onuUniPort
158 pUniTechProf *onuUniTechProf
159 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000160 requestEvent OnuDeviceEvent
161 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
162 pAdaptFsm *AdapterFsm
163 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000164 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000165 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000166 isAwaitingResponse bool
167 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000168 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000169 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000170 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000171 uniVlanFlowParamsSlice []uniVlanFlowParams
172 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 numUniFlows uint8 // expected number of flows should be less than 12
174 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000175 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000176 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000177 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000178 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000179 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000180 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000181 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000182 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000183 signalOnFlowDelete bool
184 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000185 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
186 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200187 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
188 // thus notification needs to be sent on chan.
189 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000190}
191
mpagenko01e726e2020-10-23 09:45:29 +0000192//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
193// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000194func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000195 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000196 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200197 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000198 instFsm := &UniVlanConfigFsm{
199 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000200 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000201 pOmciCC: apDevOmciCC,
202 pOnuUniPort: apUniPort,
203 pUniTechProf: apUniTechProf,
204 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000205 requestEvent: aRequestEvent,
206 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000207 numUniFlows: 0,
208 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000209 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000210 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200211 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000212 }
213
mpagenko01e726e2020-10-23 09:45:29 +0000214 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000215 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000216 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000217 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000218 return nil
219 }
mpagenkodff5dda2020-08-28 11:52:01 +0000220 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
221 vlanStDisabled,
222 fsm.Events{
mpagenkof1d21d12021-06-11 13:14:45 +0000223 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStPreparing},
224 {Name: vlanEvPrepareDone, Src: []string{vlanStPreparing}, Dst: vlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000225 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000226 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000227 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
228 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
229 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000230 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
231 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000232 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
233 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
234 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
235 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000236 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
237 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
238 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000239 /*
240 {Name: vlanEvTimeoutSimple, Src: []string{
241 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
242 {Name: vlanEvTimeoutMids, Src: []string{
243 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
244 */
245 // exceptional treatment for all states except vlanStResetting
246 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000247 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000248 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000249 Dst: vlanStResetting},
250 // the only way to get to resource-cleared disabled state again is via "resseting"
251 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000252 // transitions for reconcile handling according to VOL-3834
mpagenkof1d21d12021-06-11 13:14:45 +0000253 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStPreparing}, Dst: vlanStConfigDone},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000254 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
255 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000256 },
mpagenkodff5dda2020-08-28 11:52:01 +0000257 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000258 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
mpagenkof1d21d12021-06-11 13:14:45 +0000259 "enter_" + vlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
261 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
262 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
263 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
264 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
265 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
266 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
267 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
268 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000269 },
270 )
271 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000272 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000273 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000274 return nil
275 }
276
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000278
dbainbri4d3a0dc2020-12-02 00:33:42 +0000279 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000280 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000281 return instFsm
282}
283
mpagenko01e726e2020-10-23 09:45:29 +0000284//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000285func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000286 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
287 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000288 TpID: aTpID,
289 MatchVid: uint32(aMatchVlan),
290 SetVid: uint32(aSetVlan),
291 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000292 }
293 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000294 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
295 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000296
mpagenko01e726e2020-10-23 09:45:29 +0000297 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000298 //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 +0000299 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000300 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
301 } else {
302 if !oFsm.acceptIncrementalEvtoOption {
303 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000304 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000305 }
306 }
307
mpagenko01e726e2020-10-23 09:45:29 +0000308 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000309 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000310 loRuleParams.TagsToRemove = 0 //no tag pop action
311 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
312 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000313 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
314 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
315 // might collide with NoMatchVid/CopyPrio(/setVid) setting
316 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000317 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000318 }
319 }
mpagenko01e726e2020-10-23 09:45:29 +0000320
321 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
322 loFlowParams.CookieSlice = make([]uint64, 0)
323 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
324
325 //no mutex protection is required for initial access and adding the first flow is always possible
326 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
327 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000329 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
330 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
331 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
332 "SetPcp": loRuleParams.SetPcp,
333 "device-id": oFsm.deviceID})
334 oFsm.numUniFlows = 1
335 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
336
337 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000338 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000339 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000340 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000341 return err
342 }
343
344 return nil
345}
346
mpagenko7d6bb022021-03-11 15:07:55 +0000347//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000348func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000349 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000350 oFsm.mutexIsAwaitingResponse.Lock()
351 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000352 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000353 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
354 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
355 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000356 //use channel to indicate that the response waiting shall be aborted
357 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000358 } else {
359 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000360 }
mpagenkocf48e452021-04-23 09:23:00 +0000361
mpagenko7d6bb022021-03-11 15:07:55 +0000362 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
363 pAdaptFsm := oFsm.pAdaptFsm
364 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000365 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000366 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000367 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000368 }
mpagenko7d6bb022021-03-11 15:07:55 +0000369 }
370}
371
mpagenko551a4d42020-12-08 18:09:20 +0000372//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
373func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
374 //mutex protection is required for possible concurrent access to FSM members
375 oFsm.mutexFlowParams.RLock()
376 defer oFsm.mutexFlowParams.RUnlock()
377 return oFsm.TpIDWaitingFor
378}
379
mpagenko2418ab02020-11-12 12:58:06 +0000380//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
381func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
382 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000383 oFsm.mutexFlowParams.Lock()
384 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000385 oFsm.clearPersistency = aClear
386}
387
mpagenko01e726e2020-10-23 09:45:29 +0000388//SetUniFlowParams verifies on existence of flow parameters to be configured,
389// optionally udates the cookie list or appends a new flow if there is space
390// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000391// ignore complexity by now
392// nolint: gocyclo
393func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200394 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool) error {
mpagenko01e726e2020-10-23 09:45:29 +0000395 loRuleParams := uniVlanRuleParams{
396 TpID: aTpID,
397 MatchVid: uint32(aMatchVlan),
398 SetVid: uint32(aSetVlan),
399 SetPcp: uint32(aSetPcp),
400 }
401 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
402 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
403 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
404
405 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
406 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
407 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
408 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
409 } else {
410 if !oFsm.acceptIncrementalEvtoOption {
411 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
412 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
413 }
414 }
415
416 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
417 // no prio/vid filtering requested
418 loRuleParams.TagsToRemove = 0 //no tag pop action
419 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
420 if loRuleParams.SetPcp == cCopyPrioFromInner {
421 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
422 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
423 // might collide with NoMatchVid/CopyPrio(/setVid) setting
424 // this was some precondition setting taken over from py adapter ..
425 loRuleParams.SetPcp = 0
426 }
427 }
428
mpagenkof1d21d12021-06-11 13:14:45 +0000429 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
430 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
431 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
432 oFsm.mutexFlowParams.RLock()
433 if len(oFsm.uniRemoveFlowsSlice) > 0 {
434 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
435 if removeUniFlowParams.vlanRuleParams == loRuleParams {
436 // the flow to add is the same as the one already in progress of deleting
437 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000438 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
439 if flow >= len(oFsm.uniRemoveFlowsSlice) {
440 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
441 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
442 oFsm.mutexFlowParams.RUnlock()
443 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
444 }
mpagenkof1d21d12021-06-11 13:14:45 +0000445 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
446 oFsm.mutexFlowParams.RUnlock()
447 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
448 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
449 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
450 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
451 }
452 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000453 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000454 }
455 }
456 }
457 oFsm.mutexFlowParams.RUnlock()
458
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000459 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000460 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000461 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200462 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000463 //mutex protection is required for possible concurrent access to FSM members
464 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000465 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
466 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
467 // countable run time optimization (perhaps with including the hash in kvStore storage?)
468 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000469 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000470 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000471 "device-id": oFsm.deviceID})
472 var cookieMatch bool
473 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
474 cookieMatch = false
475 for _, cookie := range storedUniFlowParams.CookieSlice {
476 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000478 "device-id": oFsm.deviceID, "cookie": cookie})
479 cookieMatch = true
480 break //found new cookie - no further search for this requested cookie
481 }
482 }
483 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000484 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
485 if delayedCookie != 0 {
486 //a delay for adding the cookie to this rule is requested
487 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
488 oFsm.mutexFlowParams.Unlock()
489 oFsm.suspendNewRule(ctx)
490 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
491 oFsm.mutexFlowParams.Lock()
492 } else {
493 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
494 "device-id": oFsm.deviceID, "cookie": newCookie})
495 //as range works with copies of the slice we have to write to the original slice!!
496 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
497 newCookie)
498 flowCookieModify = true
499 }
mpagenko01e726e2020-10-23 09:45:29 +0000500 }
501 } //for all new cookies
502 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000503 }
504 }
mpagenkof1fc3862021-02-16 10:09:52 +0000505 oFsm.mutexFlowParams.Unlock()
506
507 if !flowEntryMatch { //it is (was) a new rule
508 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
509 requestAppendRule = true //default assumption here is that rule is to be appended
510 flowCookieModify = true //and that the the flow data base is to be updated
511 if delayedCookie != 0 { //it was suspended
512 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
513 }
514 }
515 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
516 if requestAppendRule {
517 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000518 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000519 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
520 loFlowParams.CookieSlice = make([]uint64, 0)
521 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
522 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000523 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000524 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
525 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
526 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800527 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000528 "device-id": oFsm.deviceID})
529
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000530 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000531 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
532
533 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
534 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
535 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000536 //attention: take care to release the mutexFlowParams when calling the FSM directly -
537 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000538 oFsm.mutexFlowParams.Unlock()
539 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000540 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
541 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
542 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
543 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000544 }
545 return nil
546 }
mpagenko01e726e2020-10-23 09:45:29 +0000547 // note: theoretical it would be possible to clear the same rule from the remove slice
548 // (for entries that have not yet been started with removal)
549 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
550 // 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 +0000551
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000552 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
553 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000554 if oFsm.configuredUniFlow == 0 {
555 // this is a restart with a complete new flow, we can re-use the initial flow config control
556 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000557 //attention: take care to release the mutexFlowParams when calling the FSM directly -
558 // synchronous FSM 'event/state' functions may rely on this mutex
559 oFsm.mutexFlowParams.Unlock()
560 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
561 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
562 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
563 }
mpagenko551a4d42020-12-08 18:09:20 +0000564 } else {
565 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000566 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000567 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
568 //check introduced after having observed some panic here
569 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
570 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
571 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
572 oFsm.mutexFlowParams.Unlock()
573 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
574 }
mpagenko9a304ea2020-12-16 15:54:01 +0000575 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000576 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000577 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000578 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
579 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000580 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
581 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
582 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000583
584 //attention: take care to release the mutexFlowParams when calling the FSM directly -
585 // synchronous FSM 'event/state' functions may rely on this mutex
586 oFsm.mutexFlowParams.Unlock()
587 var fsmErr error
588 if loTechProfDone {
589 // let the vlan processing continue with next rule
590 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
591 } else {
592 // set to waiting for Techprofile
593 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
594 }
595 if fsmErr != nil {
596 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
597 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
598 }
mpagenko551a4d42020-12-08 18:09:20 +0000599 }
mpagenkobb47bc22021-04-20 13:29:09 +0000600 } else {
601 // if not in the appropriate state a new entry will be automatically considered later
602 // when the configDone state is reached
603 oFsm.mutexFlowParams.Unlock()
604 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000605 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000606 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000607 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000608 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000609 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
610 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000611 } else {
612 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000613 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000614 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000615 if oFsm.numUniFlows == oFsm.configuredUniFlow {
616 //all requested rules really have been configured
617 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000618 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000619 if oFsm.pDeviceHandler != nil {
620 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000621 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000622 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000623 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
624 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000625 }
626 } else {
627 // avoid device reason update as the rule config connected to this flow may still be in progress
628 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000629 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000630 log.Fields{"device-id": oFsm.deviceID,
631 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000632 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000633 }
634 }
mpagenko01e726e2020-10-23 09:45:29 +0000635
mpagenkof1fc3862021-02-16 10:09:52 +0000636 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000637 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000638 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000639 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
640 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000641 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000642 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000643 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000644 }
mpagenko15ff4a52021-03-02 10:09:20 +0000645 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000646 }
647 return nil
648}
649
mpagenkof1d21d12021-06-11 13:14:45 +0000650func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
651 oFsm.mutexFlowParams.Lock()
652 deleteChannel := apRemoveFlowParams.removeChannel
653 apRemoveFlowParams.isSuspendedOnAdd = true
654 oFsm.mutexFlowParams.Unlock()
655
656 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
657 select {
658 case success := <-deleteChannel:
659 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
660 if success {
661 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
662 "device-id": oFsm.deviceID})
663 return nil
664 }
665 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
666 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
667 oFsm.mutexFlowParams.Lock()
668 if apRemoveFlowParams != nil {
669 apRemoveFlowParams.isSuspendedOnAdd = false
670 }
671 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000672 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000673 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000674 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000675 }
mpagenkof1d21d12021-06-11 13:14:45 +0000676}
677
mpagenkof1fc3862021-02-16 10:09:52 +0000678// VOL-3828 flow config sequence workaround ########### start ##########
679func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
680 //assumes mutexFlowParams.Lock() protection from caller!
681 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
682 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000683 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000684 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
685 newCookie := aCookieSlice[0]
686 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
687 for _, cookie := range storedUniFlowParams.CookieSlice {
688 if cookie == newCookie {
689 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
690 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
691 oFsm.delayNewRuleCookie = newCookie
692 return newCookie //found new cookie in some existing rule
693 }
694 } // for all stored cookies of the actual inspected rule
695 } //for all rules
696 }
697 return 0 //no delay requested
698}
699func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
700 oFsm.mutexFlowParams.RLock()
701 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
702 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
703 oFsm.mutexFlowParams.RUnlock()
704 select {
705 case <-oFsm.chCookieDeleted:
706 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
707 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000708 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000709 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
710 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
711 }
712 oFsm.mutexFlowParams.Lock()
713 oFsm.delayNewRuleCookie = 0
714 oFsm.mutexFlowParams.Unlock()
715}
716func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
717 oFsm.mutexFlowParams.Lock()
718 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
719 oFsm.mutexFlowParams.Unlock()
720
721 if delayedCookie != 0 {
722 oFsm.suspendNewRule(ctx)
723 }
724 return delayedCookie
725}
726
727//returns flowModified, RuleAppendRequest
728func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
729 flowEntryMatch := false
730 oFsm.mutexFlowParams.Lock()
731 defer oFsm.mutexFlowParams.Unlock()
732 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
733 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
734 flowEntryMatch = true
735 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
736 "device-id": oFsm.deviceID})
737 cookieMatch := false
738 for _, cookie := range storedUniFlowParams.CookieSlice {
739 if cookie == aCookie {
740 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
741 "device-id": oFsm.deviceID, "cookie": cookie})
742 cookieMatch = true
743 break //found new cookie - no further search for this requested cookie
744 }
745 }
746 if !cookieMatch {
747 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
748 "device-id": oFsm.deviceID, "cookie": aCookie})
749 //as range works with copies of the slice we have to write to the original slice!!
750 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
751 aCookie)
752 return true, false //flowModified, NoRuleAppend
753 }
754 break // found rule - no further rule search
755 }
756 }
757 if !flowEntryMatch { //it is a new rule
758 return true, true //flowModified, RuleAppend
759 }
760 return false, false //flowNotModified, NoRuleAppend
761}
762
763// VOL-3828 flow config sequence workaround ########### end ##########
764
mpagenko01e726e2020-10-23 09:45:29 +0000765//RemoveUniFlowParams verifies on existence of flow cookie,
766// if found removes cookie from flow cookie list and if this is empty
767// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000768func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000769 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000770 flowCookieMatch := false
771 //mutex protection is required for possible concurrent access to FSM members
772 oFsm.mutexFlowParams.Lock()
773 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000774remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000775 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
776 for i, cookie := range storedUniFlowParams.CookieSlice {
777 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000778 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000779 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000780 deletedCookie = aCookie
781 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000782 //remove the cookie from the cookie slice and verify it is getting empty
783 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000784 // had to shift content to function due to sca complexity
785 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenko01e726e2020-10-23 09:45:29 +0000786 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000787 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000788 //cut off the requested cookie by slicing out this element
789 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
790 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
791 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000792 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000793 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000794 // state transition notification is checked in deviceHandler
795 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000796 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
797 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000798 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000799 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000800 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000801 if deletedCookie == oFsm.delayNewRuleCookie {
802 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
803 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
804 //simply use the first one
805 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
806 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
807 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
808 }
mpagenko01e726e2020-10-23 09:45:29 +0000809 }
mpagenko01e726e2020-10-23 09:45:29 +0000810 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000811 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000812 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
813 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000815 return err
816 }
mpagenko01e726e2020-10-23 09:45:29 +0000817 }
mpagenkof1fc3862021-02-16 10:09:52 +0000818 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000819 }
820 }
mpagenko01e726e2020-10-23 09:45:29 +0000821 } //search all flows
822 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000823 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000824 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
825 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000826 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
827 // state transition notification is checked in deviceHandler
828 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000829 // success indication without the need to write to kvStore (no change)
830 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000831 }
mpagenko01e726e2020-10-23 09:45:29 +0000832 return nil
833 } //unknown cookie
834
835 return nil
836}
837
mpagenkof582d6a2021-06-18 15:58:10 +0000838// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
839func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
840 aUniFlowParams uniVlanFlowParams, aCookie uint64) bool {
841 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
842 var cancelPendingConfig bool = false
843 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
844 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
845 "device-id": oFsm.deviceID})
846 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
847 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
848 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
849 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
850 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
851 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
852 log.Fields{"device-id": oFsm.deviceID})
853 cancelPendingConfig = true
854 } else {
855 //create a new element for the removeVlanFlow slice
856 loRemoveParams = uniRemoveVlanFlowParams{
857 vlanRuleParams: aUniFlowParams.VlanRuleParams,
858 cookie: aCookie,
859 }
860 loRemoveParams.removeChannel = make(chan bool)
861 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
862 }
863
864 usedTpID := aUniFlowParams.VlanRuleParams.TpID
865 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
866 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
867 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
868 if !cancelPendingConfig {
869 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
870 "device-id": oFsm.deviceID})
871 if oFsm.pUniTechProf != nil {
872 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
873 }
874 }
875 } else {
876 if !cancelPendingConfig {
877 oFsm.updateTechProfileToDelete(ctx, usedTpID)
878 }
879 }
880 //trigger the FSM to remove the relevant rule
881 if cancelPendingConfig {
882 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
883 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
884 //call from 'non-configured' state of the rules
885 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
886 //something quite inconsistent detected, perhaps just try to recover with FSM reset
887 oFsm.mutexFlowParams.Unlock()
888 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvReset); fsmErr != nil {
889 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
890 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
891 }
892 return false //data base update could not be done, return like cookie not found
893 }
894
895 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
896 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
897 // synchronous FSM 'event/state' functions may rely on this mutex
898 oFsm.mutexFlowParams.Unlock()
899 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
900 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
901 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
902 }
903 oFsm.mutexFlowParams.Lock()
904 return true
905 }
906 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
907 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
908 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
909 "tp-id": loRemoveParams.vlanRuleParams.TpID,
910 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
911 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
912 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
913 // synchronous FSM 'event/state' functions may rely on this mutex
914 oFsm.mutexFlowParams.Unlock()
915 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
916 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
917 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
918 }
919 oFsm.mutexFlowParams.Lock()
920 } // if not in the appropriate state a new entry will be automatically considered later
921 // when the configDone state is reached
922 return true
923}
924
mpagenkof1d21d12021-06-11 13:14:45 +0000925//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
926// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
927// from the start of the deletion request to avoid to much interference
928// so when called, there can only be one cookie active for this flow
929// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000930func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000931 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
932 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000933 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000934removeFromSlice_loop:
935 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000936 // if UniFlowParams exists, cookieSlice should always have at least one element
937 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
938 if cookieSliceLen == 1 {
939 if storedUniFlowParams.CookieSlice[0] == aCookie {
940 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +0000941 }
mpagenkof582d6a2021-06-18 15:58:10 +0000942 } else if cookieSliceLen == 0 {
943 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
944 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
945 return errors.New(errStr)
946 } else {
947 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
948 logger.Errorw(ctx, errStr, log.Fields{
949 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
950 for _, cookie := range storedUniFlowParams.CookieSlice {
951 if cookie == aCookie {
952 cookieFound = true
953 break
954 }
955 }
956 }
957 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +0000958 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
959 "device-id": oFsm.deviceID, "cookie": aCookie})
960 //remove the actual element from the addVlanFlow slice
961 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
962 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
963 oFsm.numUniFlows = 0 //no more flows
964 oFsm.configuredUniFlow = 0 //no more flows configured
965 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
966 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
967 //request that this profile gets deleted before a new flow add is allowed
968 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
969 "device-id": oFsm.deviceID})
970 } else {
971 oFsm.numUniFlows--
972 if aWasConfigured && oFsm.configuredUniFlow > 0 {
973 oFsm.configuredUniFlow--
974 }
975 //cut off the requested flow by slicing out this element
976 oFsm.uniVlanFlowParamsSlice = append(
977 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
978 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
979 "device-id": oFsm.deviceID})
980 }
981 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
982 }
983 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +0000984 if !cookieFound {
985 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
986 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
987 return errors.New(errStr)
988 }
989 return nil
mpagenkof1d21d12021-06-11 13:14:45 +0000990}
991
992// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +0000993func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
994 //here we have to check, if there are still other flows referencing to the actual ProfileId
995 // before we can request that this profile gets deleted before a new flow add is allowed
996 tpIDInOtherFlows := false
997 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
998 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
999 tpIDInOtherFlows = true
1000 break // search loop can be left
1001 }
1002 }
1003 if tpIDInOtherFlows {
1004 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1005 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1006 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001007 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 +00001008 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenkof1d21d12021-06-11 13:14:45 +00001009 if oFsm.pUniTechProf != nil {
1010 //request that this profile gets deleted before a new flow add is allowed
1011 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
1012 }
mpagenkof1fc3862021-02-16 10:09:52 +00001013 }
1014}
1015
mpagenkof1d21d12021-06-11 13:14:45 +00001016func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1017 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001018
1019 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001020 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001021 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001022 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001023 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001024 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001025 //let the state machine run forward from here directly
1026 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1027 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001028 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1029 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
1030 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001031 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001032 go func(a_pAFsm *AdapterFsm) {
1033 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
1034 }(pConfigVlanStateAFsm)
1035 return
1036 }
mpagenkof1d21d12021-06-11 13:14:45 +00001037 // Can't call FSM Event directly, decoupling it
1038 go func(a_pAFsm *AdapterFsm) {
1039 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
1040 }(pConfigVlanStateAFsm)
1041 return
1042 }
1043 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1044 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1045 //should never happen, else: recovery would be needed from outside the FSM
1046}
1047
1048func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1049 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1050 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1051 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001052 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001053 //possibly the entry is not valid anymore based on intermediate delete requests
1054 //just a basic protection ...
1055 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1056 oFsm.mutexFlowParams.Unlock()
1057 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1058 "device-id": oFsm.deviceID})
1059 // Can't call FSM Event directly, decoupling it
1060 go func(a_pAFsm *AdapterFsm) {
1061 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1062 }(pConfigVlanStateAFsm)
1063 return
1064 }
mpagenko9a304ea2020-12-16 15:54:01 +00001065 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1066 //store the actual rule that shall be worked upon in the following transient states
1067 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +00001068 tpID := oFsm.actualUniVlanConfigRule.TpID
1069 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001070 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001071 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1072 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1073 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +00001074 //cmp also usage in EVTOCDE create in omci_cc
1075 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +00001076 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001077 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001078 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1079 if aPAFsm != nil && aPAFsm.pFsm != nil {
1080 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001081 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001082 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001083 } else {
1084 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001085 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001086 }
1087 }
mpagenko551a4d42020-12-08 18:09:20 +00001088 }(pConfigVlanStateAFsm, loTechProfDone)
1089 } else {
1090 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1091 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1092 //should never happen, else: recovery would be needed from outside the FSM
1093 return
mpagenkodff5dda2020-08-28 11:52:01 +00001094 }
1095}
1096
dbainbri4d3a0dc2020-12-02 00:33:42 +00001097func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001098 //mutex protection is required for possible concurrent access to FSM members
1099 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001100 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001101 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001102 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001103 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001104 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001105 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001106 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001107 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001108 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001109 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301110 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001111 }(pConfigVlanStateAFsm)
1112 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001113 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1114 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001115 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001116 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001117 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001118 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1119 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001120 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001121 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001122 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001123 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001124 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1125 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001126 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001127 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001128 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001129 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1130 "ForwardOperation": uint8(0x10), //VID investigation
1131 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001132 },
1133 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001134 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001135 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001136 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001137 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001138 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001139 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001140 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001141 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1142 log.Fields{"device-id": oFsm.deviceID})
1143 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1144 if pConfigVlanStateAFsm != nil {
1145 go func(a_pAFsm *AdapterFsm) {
1146 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1147 }(pConfigVlanStateAFsm)
1148 }
1149 return
1150 }
mpagenkodff5dda2020-08-28 11:52:01 +00001151 //accept also nil as (error) return value for writing to LastTx
1152 // - this avoids misinterpretation of new received OMCI messages
1153 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1154 // send shall return (dual format) error code that can be used here for immediate error treatment
1155 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001156 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001157 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001158 }
1159}
1160
dbainbri4d3a0dc2020-12-02 00:33:42 +00001161func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1162 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001163 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001164 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001165 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001166 //using the first element in the slice because it's the first flow per definition here
1167 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001168 //This is correct passing scenario
1169 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001170 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001171 tpID := oFsm.actualUniVlanConfigRule.TpID
1172 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1174 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001175 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenkof1d21d12021-06-11 13:14:45 +00001176 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001177 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001178 vlanID)
1179 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001181 log.Fields{"device-id": oFsm.deviceID})
1182 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1183 }
mpagenkof1d21d12021-06-11 13:14:45 +00001184 oFsm.mutexFlowParams.RLock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001185 }
mpagenkof1d21d12021-06-11 13:14:45 +00001186 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001187 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1188 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1189 }
1190 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001191}
1192
dbainbri4d3a0dc2020-12-02 00:33:42 +00001193func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001194
mpagenkof1d21d12021-06-11 13:14:45 +00001195 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001196
mpagenkof1fc3862021-02-16 10:09:52 +00001197 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001198 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001199 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1200 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1201 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001202 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001203 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1204 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1205 //should never happen, else: recovery would be needed from outside the FSM
1206 return
1207 }
1208 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001209 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1210 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001211 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1212 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1213 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1214 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001215 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001216 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001217 go func(a_pBaseFsm *fsm.FSM) {
1218 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1219 }(pConfigVlanStateBaseFsm)
1220 return
1221 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001222 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1223 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001224 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001225 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001226 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001227 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1228 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001229 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1230 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001231 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001232 return
1233 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001234 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001235 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001236 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001237 // this is a restart with a complete new flow, we can re-use the initial flow config control
1238 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001239 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001240 go func(a_pBaseFsm *fsm.FSM) {
1241 _ = a_pBaseFsm.Event(vlanEvRenew)
1242 }(pConfigVlanStateBaseFsm)
1243 return
1244 }
1245
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001246 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001247 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001248 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1249 //check introduced after having observed some panic in this processing
1250 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1251 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1252 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1253 oFsm.mutexFlowParams.Unlock()
1254 go func(a_pAFsm *AdapterFsm) {
1255 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1256 }(pConfigVlanStateAFsm)
1257 return
1258 }
mpagenko9a304ea2020-12-16 15:54:01 +00001259 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001260 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001261 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001262 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001263 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001264 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1265 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1266 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkof1d21d12021-06-11 13:14:45 +00001267 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001268 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001269 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1270 if aTechProfDone {
1271 // let the vlan processing continue with next rule
1272 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1273 } else {
1274 // set to waiting for Techprofile
1275 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1276 }
1277 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001278 return
1279 }
mpagenkof1d21d12021-06-11 13:14:45 +00001280 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001281 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001282 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001283 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1284 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001285 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001286 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001287 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001288 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001289 }
1290}
1291
dbainbri4d3a0dc2020-12-02 00:33:42 +00001292func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001293
1294 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1295 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1296 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1297 go func(a_pBaseFsm *fsm.FSM) {
1298 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1299 }(oFsm.pAdaptFsm.pFsm)
1300 return
1301 }
mpagenko15ff4a52021-03-02 10:09:20 +00001302 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001304 "recent flow-number": oFsm.configuredUniFlow,
1305 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001306 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001307
mpagenko9a304ea2020-12-16 15:54:01 +00001308 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001309 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001310 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001311 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001312 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001313 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1314 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1315 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1316 // 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 +00001317 if oFsm.numVlanFilterEntries == 0 {
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))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001321 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001322 logger.Debugw(ctx, "UniVlanConfigFsm create 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})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001326 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001327 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001328
mpagenko01e726e2020-10-23 09:45:29 +00001329 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001330 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1331 oFsm.numVlanFilterEntries = 1
1332 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001333 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001334 Attributes: me.AttributeValueMap{
1335 "VlanFilterList": vtfdFilterList,
1336 "ForwardOperation": uint8(0x10), //VID investigation
1337 "NumberOfEntries": oFsm.numVlanFilterEntries,
1338 },
1339 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001340 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001341 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001342 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001343 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001344 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001345 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001346 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1347 log.Fields{"device-id": oFsm.deviceID})
1348 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1349 if pConfigVlanStateAFsm != nil {
1350 go func(a_pAFsm *AdapterFsm) {
1351 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1352 }(pConfigVlanStateAFsm)
1353 }
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 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001364 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1365 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001366 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001367
dbainbri4d3a0dc2020-12-02 00:33:42 +00001368 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001369 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001370 "device-id": oFsm.deviceID,
1371 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001372 // setVid is assumed to be masked already by the caller to 12 bit
1373 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001374 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001375 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001376
1377 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1378 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1379 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001380 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001381
1382 oFsm.numVlanFilterEntries++
1383 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001384 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001385 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001386 "VlanFilterList": vtfdFilterList,
1387 "ForwardOperation": uint8(0x10), //VID investigation
1388 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001389 },
1390 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001391 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001392 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001393 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001394 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001395 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001396 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001397 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1398 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1399 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1400 return
1401 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001402 //accept also nil as (error) return value for writing to LastTx
1403 // - this avoids misinterpretation of new received OMCI messages
1404 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1405 // send shall return (dual format) error code that can be used here for immediate error treatment
1406 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001407 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001408 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001409 }
1410 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001412 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001413 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001414 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001415 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001416 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001417 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001418 go func(a_pBaseFsm *fsm.FSM) {
1419 _ = a_pBaseFsm.Event(vlanEvReset)
1420 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001421 return
1422 }
1423 }
mpagenkof1d21d12021-06-11 13:14:45 +00001424
mpagenkof1fc3862021-02-16 10:09:52 +00001425 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001426 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001427 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001428 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001429 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001430 configuredUniFlow := oFsm.configuredUniFlow
1431 oFsm.mutexFlowParams.RUnlock()
1432 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001433 //This is correct passing scenario
1434 if errEvto == nil {
1435 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001436 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001437 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001438 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001439 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001440 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001441 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001442 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001443 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001444 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001445 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001446 log.Fields{"device-id": oFsm.deviceID})
1447 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1448 }
1449 }
1450 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1451 }
1452 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001453}
1454
dbainbri4d3a0dc2020-12-02 00:33:42 +00001455func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001456 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001458 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1459 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001460
mpagenkofc4f56e2020-11-04 17:17:49 +00001461 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001462 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001463 loVlanEntryClear := uint8(0)
1464 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1465 //shallow copy is sufficient as no reference variables are used within struct
1466 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001467 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001468 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001469 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1470 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1471 "device-id": oFsm.deviceID})
1472
1473 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1474 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001475 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001476 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1477 } else {
1478 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1479 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001480 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001481 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1482 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001483 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001484 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001485 "device-id": oFsm.deviceID,
1486 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001487 loVlanEntryClear = 1 //full VlanFilter clear request
1488 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001489 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001490 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001491 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001492 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001493 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001494 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1495 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1496 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1497 return
1498 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001499 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001500 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001501 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001502 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001503 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001504 }
mpagenko01e726e2020-10-23 09:45:29 +00001505 } else {
1506 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1507 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001508 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001509 log.Fields{"current vlan list": oFsm.vlanFilterList,
1510 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1511 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1512 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1513 loVlanEntryRmPos = i
1514 break //abort search
1515 }
1516 }
1517 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001518 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001519 //valid entry was found - to be eclipsed
1520 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1521 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1522 if i < loVlanEntryRmPos {
1523 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1524 } else if i < (cVtfdTableSize - 1) {
1525 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1526 } else {
1527 vtfdFilterList[i] = 0 //set last byte if needed
1528 }
1529 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001531 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001532 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1533 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001534
mpagenkofc4f56e2020-11-04 17:17:49 +00001535 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001536 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001537 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001538 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001539 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001540 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001541 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001542 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1543 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1544 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1545 return
1546 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001547 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001548 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001549 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001550 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001551 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001552 }
mpagenko01e726e2020-10-23 09:45:29 +00001553 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001554 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001555 log.Fields{"device-id": oFsm.deviceID})
1556 }
1557 }
1558 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001559 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1560 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001561 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001562 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001563 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001564 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001565 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001566 go func(a_pBaseFsm *fsm.FSM) {
1567 _ = a_pBaseFsm.Event(vlanEvReset)
1568 }(pConfigVlanStateBaseFsm)
1569 return
1570 }
mpagenko01e726e2020-10-23 09:45:29 +00001571 }
1572
mpagenko15ff4a52021-03-02 10:09:20 +00001573 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001574 if loVlanEntryClear == 1 {
1575 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1576 oFsm.numVlanFilterEntries = 0
1577 } else if loVlanEntryClear == 2 {
1578 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1579 // this loop now includes the 0 element on previous last valid entry
1580 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1581 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1582 }
1583 oFsm.numVlanFilterEntries--
1584 }
mpagenko15ff4a52021-03-02 10:09:20 +00001585 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001586 }
1587 }
1588
mpagenkofc4f56e2020-11-04 17:17:49 +00001589 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001591 } else {
1592 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001593 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001594 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001595 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001596 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001597 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001598 }(pConfigVlanStateBaseFsm)
1599 }
mpagenkodff5dda2020-08-28 11:52:01 +00001600}
1601
dbainbri4d3a0dc2020-12-02 00:33:42 +00001602func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001603 var tpID uint8
1604 // Extract the tpID
1605 if len(e.Args) > 0 {
1606 tpID = e.Args[0].(uint8)
1607 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1608 } else {
1609 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1610 }
mpagenko01e726e2020-10-23 09:45:29 +00001611 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001612 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001613
mpagenkof582d6a2021-06-18 15:58:10 +00001614 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1615 if pConfigVlanStateAFsm == nil {
1616 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1617 log.Fields{"device-id": oFsm.deviceID})
1618 //would have to be fixed from outside somehow
1619 return
1620 }
1621
mpagenkof1d21d12021-06-11 13:14:45 +00001622 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1623 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001624 //call from 'configured' state of the rule
1625 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1626 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1627 oFsm.mutexFlowParams.Unlock()
1628 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
1629 go func(a_pAFsm *AdapterFsm) {
1630 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1631 }(pConfigVlanStateAFsm)
1632 return
1633 }
mpagenkof1d21d12021-06-11 13:14:45 +00001634 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1635 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1636 oFsm.mutexFlowParams.Unlock()
1637 removeChannel <- true
1638 oFsm.mutexFlowParams.Lock()
1639 }
1640
mpagenkof1fc3862021-02-16 10:09:52 +00001641 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1642 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1643 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1644
mpagenko01e726e2020-10-23 09:45:29 +00001645 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1646 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001647 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001648 "device-id": oFsm.deviceID})
1649 } else {
1650 //cut off the actual flow by slicing out the first element
1651 oFsm.uniRemoveFlowsSlice = append(
1652 oFsm.uniRemoveFlowsSlice[:0],
1653 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001654 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001655 "device-id": oFsm.deviceID})
1656 }
1657 oFsm.mutexFlowParams.Unlock()
1658
mpagenkof1fc3862021-02-16 10:09:52 +00001659 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001660 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001661 // Can't call FSM Event directly, decoupling it
1662 go func(a_pAFsm *AdapterFsm) {
1663 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
1664 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001665
mpagenkobb47bc22021-04-20 13:29:09 +00001666 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001667 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001668 if deletedCookie == oFsm.delayNewRuleCookie {
1669 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1670 select {
1671 case <-oFsm.chCookieDeleted:
1672 logger.Debug(ctx, "flushed CookieDeleted")
1673 default:
1674 }
1675 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1676 }
mpagenkobb47bc22021-04-20 13:29:09 +00001677 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1678 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1679 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 -08001680 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001681 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1682 oFsm.flowDeleteChannel <- true
1683 oFsm.signalOnFlowDelete = false
1684 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001685 }
mpagenkobb47bc22021-04-20 13:29:09 +00001686 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001687}
1688
dbainbri4d3a0dc2020-12-02 00:33:42 +00001689func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1690 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001691
1692 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1693 if pConfigVlanStateAFsm != nil {
1694 // abort running message processing
1695 fsmAbortMsg := Message{
1696 Type: TestMsg,
1697 Data: TestMessage{
1698 TestMessageVal: AbortMessageProcessing,
1699 },
1700 }
1701 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1702
mpagenko9a304ea2020-12-16 15:54:01 +00001703 //try to restart the FSM to 'disabled'
1704 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001705 go func(a_pAFsm *AdapterFsm) {
1706 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301707 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001708 }
1709 }(pConfigVlanStateAFsm)
1710 }
1711}
1712
dbainbri4d3a0dc2020-12-02 00:33:42 +00001713func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1714 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001715 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001716 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001717 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001718
1719 oFsm.mutexFlowParams.RLock()
1720 if oFsm.delayNewRuleCookie != 0 {
1721 // looks like the waiting AddFlow is stuck
1722 oFsm.mutexFlowParams.RUnlock()
1723 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/terminate
1724 oFsm.mutexFlowParams.RLock()
1725 }
1726 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1727 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1728 if removeUniFlowParams.isSuspendedOnAdd {
1729 removeChannel := removeUniFlowParams.removeChannel
1730 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1731 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1732 oFsm.mutexFlowParams.RUnlock()
1733 removeChannel <- false
1734 oFsm.mutexFlowParams.RLock()
1735 }
1736 }
1737 }
1738
mpagenkodff5dda2020-08-28 11:52:01 +00001739 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001740 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1741 // current code removes the complete FSM including all flow/rule configuration done so far
1742 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1743 // maybe a more sophisticated approach is possible without clearing the data
1744 if oFsm.clearPersistency {
1745 //permanently remove possibly stored persistent data
1746 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1747 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001748 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001749 }
1750 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001751 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001752 }
mpagenko9a304ea2020-12-16 15:54:01 +00001753 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001754 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001755 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001756 return
mpagenkodff5dda2020-08-28 11:52:01 +00001757 }
mpagenkof1d21d12021-06-11 13:14:45 +00001758 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001759}
1760
dbainbri4d3a0dc2020-12-02 00:33:42 +00001761func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1762 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001763loop:
1764 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001765 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001766 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001767 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301768 message, ok := <-oFsm.pAdaptFsm.commChan
1769 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001770 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301771 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1772 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1773 break loop
1774 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001775 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301776
1777 switch message.Type {
1778 case TestMsg:
1779 msg, _ := message.Data.(TestMessage)
1780 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001782 break loop
1783 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001784 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301785 case OMCI:
1786 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001787 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301788 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001789 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301790 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001791 }
1792 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001793 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001794}
1795
dbainbri4d3a0dc2020-12-02 00:33:42 +00001796func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1797 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001798 "msgType": msg.OmciMsg.MessageType})
1799
1800 switch msg.OmciMsg.MessageType {
1801 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001802 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001803 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1804 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001805 return
1806 }
mpagenkodff5dda2020-08-28 11:52:01 +00001807 } //CreateResponseType
1808 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001809 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001810 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1811 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001812 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001813 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001814 return
1815 }
1816 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1817 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001818 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001819 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001820 return
1821 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001822 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001823 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001825 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001826 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1827 return
1828 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001829 oFsm.mutexPLastTxMeInstance.RLock()
1830 if oFsm.pLastTxMeInstance != nil {
1831 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1832 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1833 switch oFsm.pLastTxMeInstance.GetName() {
1834 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
1835 { // let the MultiEntity config proceed by stopping the wait function
1836 oFsm.mutexPLastTxMeInstance.RUnlock()
1837 oFsm.omciMIdsResponseReceived <- true
1838 return
1839 }
1840 default:
1841 {
1842 logger.Warnw(ctx, "Unsupported ME name received!",
1843 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1844 }
mpagenkodff5dda2020-08-28 11:52:01 +00001845 }
1846 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001847 } else {
1848 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001849 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001850 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001851 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001852 case omci.DeleteResponseType:
1853 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1855 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001856 return
1857 }
1858 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001859 default:
1860 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001861 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001862 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001863 return
1864 }
1865 }
1866}
1867
dbainbri4d3a0dc2020-12-02 00:33:42 +00001868func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001869 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1870 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001871 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001872 log.Fields{"device-id": oFsm.deviceID})
1873 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1874 oFsm.deviceID)
1875 }
1876 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1877 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001878 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001879 log.Fields{"device-id": oFsm.deviceID})
1880 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1881 oFsm.deviceID)
1882 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001883 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001884 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001886 "Error": msgObj.Result})
1887 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1888 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1889 oFsm.deviceID)
1890 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001891 oFsm.mutexPLastTxMeInstance.RLock()
1892 if oFsm.pLastTxMeInstance != nil {
1893 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1894 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1895 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1896 switch oFsm.pLastTxMeInstance.GetName() {
1897 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1898 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1899 "ExtendedVlanTaggingOperationConfigurationData":
1900 {
1901 oFsm.mutexPLastTxMeInstance.RUnlock()
1902 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1903 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1904 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1905 } else { // let the MultiEntity config proceed by stopping the wait function
1906 oFsm.omciMIdsResponseReceived <- true
1907 }
1908 return nil
1909 }
1910 default:
1911 {
1912 logger.Warnw(ctx, "Unsupported ME name received!",
1913 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001914 }
1915 }
1916 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001917 } else {
1918 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001919 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001920 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001921 return nil
1922}
1923
dbainbri4d3a0dc2020-12-02 00:33:42 +00001924func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001925 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1926 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001928 log.Fields{"device-id": oFsm.deviceID})
1929 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1930 oFsm.deviceID)
1931 }
1932 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1933 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001935 log.Fields{"device-id": oFsm.deviceID})
1936 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1937 oFsm.deviceID)
1938 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001940 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001942 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1943 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1944 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1945 oFsm.deviceID)
1946 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001947 oFsm.mutexPLastTxMeInstance.RLock()
1948 if oFsm.pLastTxMeInstance != nil {
1949 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1950 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1951 switch oFsm.pLastTxMeInstance.GetName() {
1952 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
1953 { // let the MultiEntity config proceed by stopping the wait function
1954 oFsm.mutexPLastTxMeInstance.RUnlock()
1955 oFsm.omciMIdsResponseReceived <- true
1956 return nil
1957 }
1958 default:
1959 {
1960 logger.Warnw(ctx, "Unsupported ME name received!",
1961 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1962 }
mpagenko01e726e2020-10-23 09:45:29 +00001963 }
1964 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001965 } else {
1966 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001967 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001968 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001969 return nil
1970}
1971
dbainbri4d3a0dc2020-12-02 00:33:42 +00001972func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00001973 oFsm.mutexFlowParams.RLock()
1974 evtocdID := oFsm.evtocdID
1975 oFsm.mutexFlowParams.RUnlock()
1976
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001977 if aFlowEntryNo == 0 {
1978 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001979 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1980 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001981 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001982 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00001983 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001984 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001985 associationType := 2 // default to uniPPTP
1986 if oFsm.pOnuUniPort.portType == uniVEIP {
1987 associationType = 10
1988 }
1989 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001990 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00001991 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001992 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001993 "AssociationType": uint8(associationType),
1994 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001995 },
1996 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001997 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001998 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
1999 true, oFsm.pAdaptFsm.commChan, meParams)
2000 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002001 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002002 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2003 log.Fields{"device-id": oFsm.deviceID})
2004 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2005 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2006 }
mpagenkodff5dda2020-08-28 11:52:01 +00002007 //accept also nil as (error) return value for writing to LastTx
2008 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002009 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002010 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002011
2012 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002013 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002014 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002015 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002016 log.Fields{"device-id": oFsm.deviceID})
2017 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2018 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2019 }
2020
2021 // Set the EVTOCD ME default params
2022 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002023 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002024 Attributes: me.AttributeValueMap{
2025 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2026 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2027 "DownstreamMode": uint8(cDefaultDownstreamMode),
2028 },
2029 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002030 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002031 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2032 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002033 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002034 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002035 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002036 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2037 log.Fields{"device-id": oFsm.deviceID})
2038 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2039 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2040 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002041 //accept also nil as (error) return value for writing to LastTx
2042 // - this avoids misinterpretation of new received OMCI messages
2043 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002044 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002045
2046 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002047 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002048 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002050 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302051 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002052 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002053 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002054 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002055
mpagenko551a4d42020-12-08 18:09:20 +00002056 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002057 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002058 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002059 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002060 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002061 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002062 sliceEvtocdRule := make([]uint8, 16)
2063 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2064 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2065 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2066 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2067 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2068
2069 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2070 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2071 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2072 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2073 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2074
2075 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2076 0<<cTreatTTROffset| // Do not pop any tags
2077 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2078 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2079 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2080
2081 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2082 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2083 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2084 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2085
2086 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002087 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002088 Attributes: me.AttributeValueMap{
2089 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2090 },
2091 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002092 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002093 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2094 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002095 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002096 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002097 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002098 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2099 log.Fields{"device-id": oFsm.deviceID})
2100 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2101 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2102 }
mpagenkodff5dda2020-08-28 11:52:01 +00002103 //accept also nil as (error) return value for writing to LastTx
2104 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002105 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002106 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002107
2108 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002109 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002110 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002111 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002112 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302113 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002114 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2115
mpagenkodff5dda2020-08-28 11:52:01 +00002116 }
2117 } else {
2118 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2119 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002120 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2121 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2122 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2123 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002124 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002125 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002126 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002127 sliceEvtocdRule := make([]uint8, 16)
2128 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2129 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2130 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2131 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2132 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2133
2134 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002135 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2136 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002137 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2138 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2139
2140 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002141 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002142 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2143 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2144 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2145
2146 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002147 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2148 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002149 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002150 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002151
2152 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002153 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002154 Attributes: me.AttributeValueMap{
2155 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2156 },
2157 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002158 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002159 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2160 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002161 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002162 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002163 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002164 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2165 log.Fields{"device-id": oFsm.deviceID})
2166 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2167 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2168 }
mpagenkodff5dda2020-08-28 11:52:01 +00002169 //accept also nil as (error) return value for writing to LastTx
2170 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002171 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002172 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002173
2174 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002175 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002176 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002177 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002178 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302179 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002180 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002181 }
2182 } else {
2183 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2184 { // just for local var's
2185 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002186 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002187 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002188 sliceEvtocdRule := make([]uint8, 16)
2189 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2190 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2191 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2192 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2193 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2194
2195 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2196 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2197 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2198 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2199 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2200
2201 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2202 0<<cTreatTTROffset| // Do not pop any tags
2203 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2204 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2205 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2206
2207 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2208 0<<cTreatPrioOffset| // vlan prio set to 0
2209 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002210 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002211 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2212
mpagenko551a4d42020-12-08 18:09:20 +00002213 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002214 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002215 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002216 Attributes: me.AttributeValueMap{
2217 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2218 },
2219 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002220 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002221 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2222 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002223 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002224 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002225 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002226 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2227 log.Fields{"device-id": oFsm.deviceID})
2228 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2229 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2230 }
mpagenkodff5dda2020-08-28 11:52:01 +00002231 //accept also nil as (error) return value for writing to LastTx
2232 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002233 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002234 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002235
2236 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002237 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002238 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002239 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002240 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302241 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002242 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2243
mpagenkodff5dda2020-08-28 11:52:01 +00002244 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002245 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002246 { // just for local var's
2247 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002248 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002249 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002250 sliceEvtocdRule := make([]uint8, 16)
2251 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2252 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2253 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2254 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2255 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2256
2257 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2258 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2259 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2260 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2261 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2262
2263 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2264 1<<cTreatTTROffset| // pop the prio-tag
2265 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2266 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2267 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2268
mpagenko551a4d42020-12-08 18:09:20 +00002269 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002270 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2271 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2272 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002273 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002274 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002275 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002276
2277 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002278 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002279 Attributes: me.AttributeValueMap{
2280 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2281 },
2282 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002283 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002284 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2285 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002286 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002287 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002288 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002289 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2290 log.Fields{"device-id": oFsm.deviceID})
2291 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2292 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2293 }
mpagenkodff5dda2020-08-28 11:52:01 +00002294 //accept also nil as (error) return value for writing to LastTx
2295 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002296 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002297 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002298
2299 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002300 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002301 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002302 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002303 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302304 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002305 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2306
mpagenkodff5dda2020-08-28 11:52:01 +00002307 }
2308 } //just for local var's
2309 }
2310 }
2311
mpagenkofc4f56e2020-11-04 17:17:49 +00002312 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002313 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002314 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002315 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002316 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002317 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002318}
2319
dbainbri4d3a0dc2020-12-02 00:33:42 +00002320func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002321 oFsm.mutexFlowParams.RLock()
2322 evtocdID := oFsm.evtocdID
2323 oFsm.mutexFlowParams.RUnlock()
2324
mpagenko01e726e2020-10-23 09:45:29 +00002325 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2326 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2327 //transparent transmission was set
2328 //perhaps the config is not needed for removal,
2329 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002330 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002331 "device-id": oFsm.deviceID})
2332 sliceEvtocdRule := make([]uint8, 16)
2333 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2334 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2335 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2336 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2337 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2338
2339 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2340 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2341 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2342 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2343 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2344
2345 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2346 0<<cTreatTTROffset| // Do not pop any tags
2347 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2348 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2349 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2350
2351 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2352 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2353 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2354 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2355
2356 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002357 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002358 Attributes: me.AttributeValueMap{
2359 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2360 },
2361 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002362 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002363 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2364 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002365 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002366 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002367 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002368 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2369 log.Fields{"device-id": oFsm.deviceID})
2370 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2371 return
2372 }
mpagenko01e726e2020-10-23 09:45:29 +00002373 //accept also nil as (error) return value for writing to LastTx
2374 // - this avoids misinterpretation of new received OMCI messages
2375 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002376 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002377
2378 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002379 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002380 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002381 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002382 log.Fields{"device-id": oFsm.deviceID})
2383 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2384 return
2385 }
2386 } else {
2387 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002388 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002389 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002390 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002391 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002392 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002393 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2394 sliceEvtocdRule := make([]uint8, 16)
2395 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2396 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2397 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2398 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2399 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2400
2401 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2402 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2403 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2404 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2405 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2406
2407 // delete indication for the indicated Filter
2408 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2409 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2410
2411 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002412 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002413 Attributes: me.AttributeValueMap{
2414 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2415 },
2416 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002417 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002418 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2419 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002420 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002421 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002422 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002423 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2424 log.Fields{"device-id": oFsm.deviceID})
2425 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2426 return
2427 }
mpagenko01e726e2020-10-23 09:45:29 +00002428 //accept also nil as (error) return value for writing to LastTx
2429 // - this avoids misinterpretation of new received OMCI messages
2430 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002431 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002432
2433 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002434 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002435 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002436 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002437 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2438 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2439 return
2440 }
2441 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002442 // VOL-3685
2443 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2444 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2445 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2446 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2447 // later when the flow is being re-installed.
2448 // Of course this is applicable to case only where single service (or single tcont) is in use and
2449 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2450 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2451 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002452 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2453 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002455 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2456 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002457 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002458 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002459 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002460 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002461 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2462 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002463 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002464 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002465 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002466 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2467 log.Fields{"device-id": oFsm.deviceID})
2468 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2469 return
2470 }
mpagenko01e726e2020-10-23 09:45:29 +00002471 //accept also nil as (error) return value for writing to LastTx
2472 // - this avoids misinterpretation of new received OMCI messages
2473 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002474 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002475
2476 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002477 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002478 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002479 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002480 log.Fields{"device-id": oFsm.deviceID})
2481 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2482 return
2483 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002484 } else {
2485 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2486 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002487 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002488 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002489 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002490 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2491 { // just for local var's
2492 // this defines stacking scenario: untagged->singletagged
2493 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2494 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2495 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2496 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002497 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002498 "device-id": oFsm.deviceID})
2499 sliceEvtocdRule := make([]uint8, 16)
2500 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2501 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2502 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2503 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2504 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002505
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002506 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2507 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2508 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2509 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2510 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002511
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002512 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2513 0<<cTreatTTROffset| // Do not pop any tags
2514 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2515 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2516 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002517
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002518 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2519 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2520 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2521 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002522
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002523 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002524 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002525 Attributes: me.AttributeValueMap{
2526 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2527 },
2528 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002529 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2530 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002531 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002532 if err != nil {
2533 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2534 log.Fields{"device-id": oFsm.deviceID})
2535 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2536 return
2537 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002538 //accept also nil as (error) return value for writing to LastTx
2539 // - this avoids misinterpretation of new received OMCI messages
2540 oFsm.pLastTxMeInstance = meInstance
2541
2542 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002543 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002544 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002545 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002546 log.Fields{"device-id": oFsm.deviceID})
2547 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2548 return
2549 }
2550 } // just for local var's
2551 { // just for local var's
2552 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002554 "device-id": oFsm.deviceID})
2555 sliceEvtocdRule := make([]uint8, 16)
2556 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2557 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2558 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2559 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2560 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2561
2562 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2563 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2564 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2565 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2566 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2567
2568 // delete indication for the indicated Filter
2569 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2570 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2571
2572 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002573 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002574 Attributes: me.AttributeValueMap{
2575 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2576 },
2577 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002578 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002579 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2580 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002581 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002582 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002583 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002584 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2585 log.Fields{"device-id": oFsm.deviceID})
2586 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2587 return
2588 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002589 //accept also nil as (error) return value for writing to LastTx
2590 // - this avoids misinterpretation of new received OMCI messages
2591 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002592 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002593
2594 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002595 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002596 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002597 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002598 log.Fields{"device-id": oFsm.deviceID})
2599 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2600 return
2601 }
mpagenko01e726e2020-10-23 09:45:29 +00002602 }
2603 } //just for local var's
2604 }
2605 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002606 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002607 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002608 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002609}
2610
dbainbri4d3a0dc2020-12-02 00:33:42 +00002611func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002612 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002613 if oFsm.isCanceled {
2614 // FSM already canceled before entering wait
2615 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2616 oFsm.mutexIsAwaitingResponse.Unlock()
2617 return fmt.Errorf(cErrWaitAborted)
2618 }
mpagenko7d6bb022021-03-11 15:07:55 +00002619 oFsm.isAwaitingResponse = true
2620 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002621 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302622 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002623 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002624 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002625 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002626 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002627 oFsm.mutexIsAwaitingResponse.Lock()
2628 oFsm.isAwaitingResponse = false
2629 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002630 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002631 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302632 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002633 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002634 oFsm.mutexIsAwaitingResponse.Lock()
2635 oFsm.isAwaitingResponse = false
2636 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002637 return nil
2638 }
mpagenko7d6bb022021-03-11 15:07:55 +00002639 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002640 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002641 oFsm.mutexIsAwaitingResponse.Lock()
2642 oFsm.isAwaitingResponse = false
2643 oFsm.mutexIsAwaitingResponse.Unlock()
2644 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002645 }
2646}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002647
mpagenko551a4d42020-12-08 18:09:20 +00002648func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002649 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002650 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002651 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002652 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002653 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002654 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002655 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002656 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2657 }
2658
dbainbri4d3a0dc2020-12-02 00:33:42 +00002659 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002660 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002661 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002662 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002663 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002664 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2665 }
2666
dbainbri4d3a0dc2020-12-02 00:33:42 +00002667 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002668 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002669 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002670 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002671 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002672 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2673 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002674 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2675 if errMacBpCdEID != nil {
2676 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2677 log.Fields{"device-id": oFsm.deviceID})
2678 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2679 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002680
Mahir Gunyel6781f962021-05-16 23:30:08 -07002681 }
2682 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2683 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2684 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002685 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002686 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002687 Attributes: me.AttributeValueMap{
2688 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2689 "PortNum": 0xf0, //fixed unique ANI side indication
2690 "TpType": 6, //MCGemIWTP
2691 "TpPointer": multicastGemPortID,
2692 },
2693 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002694 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002695 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2696 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2697 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002698 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002699 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2700 log.Fields{"device-id": oFsm.deviceID})
2701 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2702 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2703 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002704 //accept also nil as (error) return value for writing to LastTx
2705 // - this avoids misinterpretation of new received OMCI messages
2706 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002707 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002708 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002709 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002710 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002711 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002712 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002713 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2714 }
2715
2716 // ==> Start creating VTFD for mcast vlan
2717
2718 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2719 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002720 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002721
dbainbri4d3a0dc2020-12-02 00:33:42 +00002722 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002723 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2724 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2725 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2726
2727 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2728 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2729 // new vlan associated with a different TP.
2730 vtfdFilterList[0] = uint16(vlanID)
2731
2732 meParams = me.ParamData{
2733 EntityID: mcastVtfdID,
2734 Attributes: me.AttributeValueMap{
2735 "VlanFilterList": vtfdFilterList,
2736 "ForwardOperation": uint8(0x10), //VID investigation
2737 "NumberOfEntries": oFsm.numVlanFilterEntries,
2738 },
2739 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002740 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002741 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2742 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2743 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002744 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002745 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2746 log.Fields{"device-id": oFsm.deviceID})
2747 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2748 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2749 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002750 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002751 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002752 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002753 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002756 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002757 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2758 }
2759
2760 return nil
2761}
2762
dbainbri4d3a0dc2020-12-02 00:33:42 +00002763func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002764 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002765 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002766 logger.Errorw(ctx, "error generrating me instance id",
2767 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002768 return err
2769 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002770 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2771 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002772 meParams := me.ParamData{
2773 EntityID: instID,
2774 Attributes: me.AttributeValueMap{
2775 "MeType": 0,
2776 //Direct reference to the Operation profile
2777 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002778 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002779 },
2780 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002781 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002782 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2783 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002784 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002785 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002786 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002787 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2788 log.Fields{"device-id": oFsm.deviceID})
2789 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2790 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2791 oFsm.deviceID, err)
2792 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002793 //accept also nil as (error) return value for writing to LastTx
2794 // - this avoids misinterpretation of new received OMCI messages
2795 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002796 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002797 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002799 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002800 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002801 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2802 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2803 }
2804 return nil
2805}
2806
dbainbri4d3a0dc2020-12-02 00:33:42 +00002807func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002808 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002809 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002810 logger.Errorw(ctx, "error generating me instance id",
2811 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002812 return err
2813 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002814 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2815 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002816 meParams := me.ParamData{
2817 EntityID: instID,
2818 Attributes: me.AttributeValueMap{
2819 "IgmpVersion": 2,
2820 "IgmpFunction": 0,
2821 //0 means false
2822 "ImmediateLeave": 0,
2823 "Robustness": 2,
2824 "QuerierIp": 0,
2825 "QueryInterval": 125,
2826 "QuerierMaxResponseTime": 100,
2827 "LastMemberResponseTime": 10,
2828 //0 means false
2829 "UnauthorizedJoinBehaviour": 0,
2830 },
2831 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002832 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002833 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2834 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002835 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002836 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002837 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002838 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2839 log.Fields{"device-id": oFsm.deviceID})
2840 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2841 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2842 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002843 //accept also nil as (error) return value for writing to LastTx
2844 // - this avoids misinterpretation of new received OMCI messages
2845 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002846 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002847 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002848 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002849 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002850 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002851 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002852 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002853 }
2854 return nil
2855}
2856
dbainbri4d3a0dc2020-12-02 00:33:42 +00002857func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002858 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002859 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002860 logger.Errorw(ctx, "error generating me instance id",
2861 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002862 return err
2863 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002864 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2865 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002866 //TODO check that this is correct
2867 // Table control
2868 //setCtrl = 1
2869 //rowPartId = 0
2870 //test = 0
2871 //rowKey = 0
2872 tableCtrlStr := "0100000000000000"
2873 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002874 dynamicAccessCL := make([]uint8, 24)
2875 copy(dynamicAccessCL, tableCtrl)
2876 //Multicast GemPortId
2877 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2878 // python version waits for installation of flows, see line 723 onward of
2879 // brcm_openomci_onu_handler.py
2880 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2881 //Source IP all to 0
2882 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2883 //TODO start and end are hardcoded, get from TP
2884 // Destination IP address start of range
2885 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2886 // Destination IP address end of range
2887 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2888 //imputed group bandwidth
2889 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2890
2891 meParams := me.ParamData{
2892 EntityID: instID,
2893 Attributes: me.AttributeValueMap{
2894 "DynamicAccessControlListTable": dynamicAccessCL,
2895 },
2896 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002897 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002898 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2899 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002900 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002901 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002902 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002903 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2904 log.Fields{"device-id": oFsm.deviceID})
2905 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2906 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2907 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002908 //accept also nil as (error) return value for writing to LastTx
2909 // - this avoids misinterpretation of new received OMCI messages
2910 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002911 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002912 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002913 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002914 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002915 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002916 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002917 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002918 }
2919 return nil
2920}
Girish Gowdra26a40922021-01-29 17:14:34 -08002921
2922// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002923func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2924 oFsm.mutexFlowParams.Lock()
2925 defer oFsm.mutexFlowParams.Unlock()
2926 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2927 //flow removal is still ongoing/pending
2928 oFsm.signalOnFlowDelete = true
2929 oFsm.flowDeleteChannel = aFlowDeleteChannel
2930 return true
2931 }
2932 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002933}