blob: c82880438c9478a96be2f01c342d7482362db536 [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
khenaidoo7d3c5582021-08-11 18:09:44 -040030 meters "github.com/opencord/voltha-lib-go/v7/pkg/meters"
31 "github.com/opencord/voltha-protos/v5/go/voltha"
ozgecanetsia82b91a62021-05-21 18:54:49 +030032
mpagenko01e726e2020-10-23 09:45:29 +000033 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000034 "github.com/looplab/fsm"
35 "github.com/opencord/omci-lib-go"
36 me "github.com/opencord/omci-lib-go/generated"
khenaidoo7d3c5582021-08-11 18:09:44 -040037 "github.com/opencord/voltha-lib-go/v7/pkg/log"
38 of "github.com/opencord/voltha-protos/v5/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000039)
40
41const (
42 // internal predefined values
43 cDefaultDownstreamMode = 0
44 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000045 cVtfdTableSize = 12 //as per G.988
46 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000047)
48
49const (
mpagenkof1fc3862021-02-16 10:09:52 +000050 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
51 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
52 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
53 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
54 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
55)
56
57const (
mpagenkodff5dda2020-08-28 11:52:01 +000058 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
59 cFilterPrioOffset = 28
60 cFilterVidOffset = 15
61 cFilterTpidOffset = 12
62 cFilterEtherTypeOffset = 0
63 cTreatTTROffset = 30
64 cTreatPrioOffset = 16
65 cTreatVidOffset = 3
66 cTreatTpidOffset = 0
67)
68const (
69 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
70 cFilterOuterOffset = 0
71 cFilterInnerOffset = 4
72 cTreatOuterOffset = 8
73 cTreatInnerOffset = 12
74)
75const (
76 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
77 cPrioIgnoreTag uint32 = 15
78 cPrioDefaultFilter uint32 = 14
79 cPrioDoNotFilter uint32 = 8
80 cDoNotFilterVid uint32 = 4096
81 cDoNotFilterTPID uint32 = 0
82 cDoNotFilterEtherType uint32 = 0
83 cDoNotAddPrio uint32 = 15
84 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053085 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000086 cDontCareVid uint32 = 0
87 cDontCareTpid uint32 = 0
88 cSetOutputTpidCopyDei uint32 = 4
89)
90
91const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000092 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000093 vlanEvStart = "vlanEvStart"
mpagenkof1d21d12021-06-11 13:14:45 +000094 vlanEvPrepareDone = "vlanEvPrepareDone"
mpagenko535d6ef2021-02-26 13:15:34 +000095 vlanEvWaitTechProf = "vlanEvWaitTechProf"
96 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
97 vlanEvContinueConfig = "vlanEvContinueConfig"
98 vlanEvStartConfig = "vlanEvStartConfig"
99 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
100 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
101 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
102 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
103 vlanEvRenew = "vlanEvRenew"
104 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
105 vlanEvRemFlowDone = "vlanEvRemFlowDone"
106 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000107 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
108 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000109 vlanEvReset = "vlanEvReset"
110 vlanEvRestart = "vlanEvRestart"
111 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
112 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000113)
mpagenko01e726e2020-10-23 09:45:29 +0000114
mpagenkodff5dda2020-08-28 11:52:01 +0000115const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000116 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000117 vlanStDisabled = "vlanStDisabled"
mpagenkof1d21d12021-06-11 13:14:45 +0000118 vlanStPreparing = "vlanStPreparing"
mpagenkodff5dda2020-08-28 11:52:01 +0000119 vlanStStarting = "vlanStStarting"
120 vlanStWaitingTechProf = "vlanStWaitingTechProf"
121 vlanStConfigVtfd = "vlanStConfigVtfd"
122 vlanStConfigEvtocd = "vlanStConfigEvtocd"
123 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000124 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000125 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000126 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000127 vlanStCleanupDone = "vlanStCleanupDone"
128 vlanStResetting = "vlanStResetting"
129)
mpagenkof1fc3862021-02-16 10:09:52 +0000130const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
131const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000132
mpagenko01e726e2020-10-23 09:45:29 +0000133type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000134 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000135 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
136 MatchPcp uint32 `json:"match_pcp"`
137 TagsToRemove uint32 `json:"tags_to_remove"`
138 SetVid uint32 `json:"set_vid"`
139 SetPcp uint32 `json:"set_pcp"`
140}
141
142type uniVlanFlowParams struct {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300143 CookieSlice []uint64 `json:"cookie_slice"`
144 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
145 Meter *voltha.OfpMeterConfig `json:"flow_meter"`
mpagenko01e726e2020-10-23 09:45:29 +0000146}
147
148type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000149 isSuspendedOnAdd bool
150 removeChannel chan bool
151 cookie uint64 //just the last cookie valid for removal
152 vlanRuleParams uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000153}
154
mpagenkobb47bc22021-04-20 13:29:09 +0000155//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
156// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000157type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000159 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530160 pOmciCC *omciCC
161 pOnuUniPort *onuUniPort
162 pUniTechProf *onuUniTechProf
163 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000164 requestEvent OnuDeviceEvent
165 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
166 pAdaptFsm *AdapterFsm
167 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000168 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000169 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000170 isAwaitingResponse bool
171 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000172 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000173 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000174 actualUniVlanConfigRule uniVlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300175 actualUniVlanConfigMeter *voltha.OfpMeterConfig
mpagenko01e726e2020-10-23 09:45:29 +0000176 uniVlanFlowParamsSlice []uniVlanFlowParams
177 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000178 numUniFlows uint8 // expected number of flows should be less than 12
179 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000180 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000181 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000182 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000183 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000184 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000185 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000186 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000187 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000188 signalOnFlowDelete bool
189 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000190 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
191 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200192 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
193 // thus notification needs to be sent on chan.
194 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000195}
196
mpagenko01e726e2020-10-23 09:45:29 +0000197//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
198// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000199func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000200 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000201 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300202 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000203 instFsm := &UniVlanConfigFsm{
204 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000205 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000206 pOmciCC: apDevOmciCC,
207 pOnuUniPort: apUniPort,
208 pUniTechProf: apUniTechProf,
209 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000210 requestEvent: aRequestEvent,
211 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000212 numUniFlows: 0,
213 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000214 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000215 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200216 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000217 }
218
mpagenko01e726e2020-10-23 09:45:29 +0000219 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000220 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000222 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000223 return nil
224 }
mpagenkodff5dda2020-08-28 11:52:01 +0000225 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
226 vlanStDisabled,
227 fsm.Events{
mpagenkof1d21d12021-06-11 13:14:45 +0000228 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStPreparing},
229 {Name: vlanEvPrepareDone, Src: []string{vlanStPreparing}, Dst: vlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000230 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000231 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000232 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
233 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
234 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000235 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
236 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000237 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
238 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
239 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
240 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000241 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
242 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
243 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000244 /*
245 {Name: vlanEvTimeoutSimple, Src: []string{
246 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
247 {Name: vlanEvTimeoutMids, Src: []string{
248 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
249 */
250 // exceptional treatment for all states except vlanStResetting
251 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000252 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000253 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000254 Dst: vlanStResetting},
255 // the only way to get to resource-cleared disabled state again is via "resseting"
256 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000257 // transitions for reconcile handling according to VOL-3834
mpagenkof1d21d12021-06-11 13:14:45 +0000258 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStPreparing}, Dst: vlanStConfigDone},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000259 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
260 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000261 },
mpagenkodff5dda2020-08-28 11:52:01 +0000262 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000263 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
mpagenkof1d21d12021-06-11 13:14:45 +0000264 "enter_" + vlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
266 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
267 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
268 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
269 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
270 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
271 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
272 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
273 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000274 },
275 )
276 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000278 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return nil
280 }
281
ozgecanetsia82b91a62021-05-21 18:54:49 +0300282 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000283
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000286 return instFsm
287}
288
mpagenko01e726e2020-10-23 09:45:29 +0000289//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000290func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300291 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000293 TpID: aTpID,
294 MatchVid: uint32(aMatchVlan),
295 SetVid: uint32(aSetVlan),
296 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 }
298 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000299 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
300 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301
mpagenko01e726e2020-10-23 09:45:29 +0000302 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000304 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000305 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
306 } else {
307 if !oFsm.acceptIncrementalEvtoOption {
308 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 }
311 }
312
mpagenko01e726e2020-10-23 09:45:29 +0000313 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000314 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000315 loRuleParams.TagsToRemove = 0 //no tag pop action
316 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
317 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000318 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
319 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
320 // might collide with NoMatchVid/CopyPrio(/setVid) setting
321 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000322 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000323 }
324 }
mpagenko01e726e2020-10-23 09:45:29 +0000325
326 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
327 loFlowParams.CookieSlice = make([]uint64, 0)
328 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300329 if aMeter != nil {
330 loFlowParams.Meter = aMeter
331 }
mpagenko01e726e2020-10-23 09:45:29 +0000332
333 //no mutex protection is required for initial access and adding the first flow is always possible
334 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
335 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000337 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
338 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
339 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
340 "SetPcp": loRuleParams.SetPcp,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300341 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000342
343 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
344 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
345 }
mpagenko01e726e2020-10-23 09:45:29 +0000346 oFsm.numUniFlows = 1
347 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
348
349 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000350 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000351 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000353 return err
354 }
355
356 return nil
357}
358
mpagenko7d6bb022021-03-11 15:07:55 +0000359//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000360func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000361 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000362 oFsm.mutexIsAwaitingResponse.Lock()
363 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000364 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000365 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
366 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
367 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000368 //use channel to indicate that the response waiting shall be aborted
369 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000370 } else {
371 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000372 }
mpagenkocf48e452021-04-23 09:23:00 +0000373
mpagenko7d6bb022021-03-11 15:07:55 +0000374 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
375 pAdaptFsm := oFsm.pAdaptFsm
376 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000377 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000378 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000379 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000380 }
mpagenko7d6bb022021-03-11 15:07:55 +0000381 }
382}
383
mpagenko551a4d42020-12-08 18:09:20 +0000384//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
385func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
386 //mutex protection is required for possible concurrent access to FSM members
387 oFsm.mutexFlowParams.RLock()
388 defer oFsm.mutexFlowParams.RUnlock()
389 return oFsm.TpIDWaitingFor
390}
391
mpagenko2418ab02020-11-12 12:58:06 +0000392//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
393func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
394 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000395 oFsm.mutexFlowParams.Lock()
396 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000397 oFsm.clearPersistency = aClear
398}
399
mpagenko01e726e2020-10-23 09:45:29 +0000400//SetUniFlowParams verifies on existence of flow parameters to be configured,
401// optionally udates the cookie list or appends a new flow if there is space
402// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000403// ignore complexity by now
404// nolint: gocyclo
405func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300406 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000407 loRuleParams := uniVlanRuleParams{
408 TpID: aTpID,
409 MatchVid: uint32(aMatchVlan),
410 SetVid: uint32(aSetVlan),
411 SetPcp: uint32(aSetPcp),
412 }
413 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
414 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
415 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000416 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
417 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
418 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
419 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
420 } else {
421 if !oFsm.acceptIncrementalEvtoOption {
422 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
423 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
424 }
425 }
426
427 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
428 // no prio/vid filtering requested
429 loRuleParams.TagsToRemove = 0 //no tag pop action
430 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
431 if loRuleParams.SetPcp == cCopyPrioFromInner {
432 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
433 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
434 // might collide with NoMatchVid/CopyPrio(/setVid) setting
435 // this was some precondition setting taken over from py adapter ..
436 loRuleParams.SetPcp = 0
437 }
438 }
439
mpagenkof1d21d12021-06-11 13:14:45 +0000440 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
441 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
442 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
443 oFsm.mutexFlowParams.RLock()
444 if len(oFsm.uniRemoveFlowsSlice) > 0 {
445 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
446 if removeUniFlowParams.vlanRuleParams == loRuleParams {
447 // the flow to add is the same as the one already in progress of deleting
448 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000449 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
450 if flow >= len(oFsm.uniRemoveFlowsSlice) {
451 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
452 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
453 oFsm.mutexFlowParams.RUnlock()
454 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
455 }
mpagenkof1d21d12021-06-11 13:14:45 +0000456 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
457 oFsm.mutexFlowParams.RUnlock()
458 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
459 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
460 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
461 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
462 }
463 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000464 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000465 }
466 }
467 }
468 oFsm.mutexFlowParams.RUnlock()
469
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000470 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000471 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000472 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200473 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000474 //mutex protection is required for possible concurrent access to FSM members
475 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000476 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
477 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
478 // countable run time optimization (perhaps with including the hash in kvStore storage?)
479 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000480 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000481 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300482 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
483 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
484 "SetPcp": loRuleParams.SetPcp,
485 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000486 var cookieMatch bool
487 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
488 cookieMatch = false
489 for _, cookie := range storedUniFlowParams.CookieSlice {
490 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000491 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000492 "device-id": oFsm.deviceID, "cookie": cookie})
493 cookieMatch = true
494 break //found new cookie - no further search for this requested cookie
495 }
496 }
497 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000498 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
499 if delayedCookie != 0 {
500 //a delay for adding the cookie to this rule is requested
501 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
502 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000503 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
504 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
505 "device-id": oFsm.deviceID, "cookie": delayedCookie})
506 return fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
507 }
mpagenkobc4170a2021-08-17 16:42:10 +0000508 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
mpagenkod6c05522021-08-23 15:59:06 +0000509 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +0000510 } else {
511 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
512 "device-id": oFsm.deviceID, "cookie": newCookie})
513 //as range works with copies of the slice we have to write to the original slice!!
514 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
515 newCookie)
516 flowCookieModify = true
517 }
mpagenko01e726e2020-10-23 09:45:29 +0000518 }
519 } //for all new cookies
520 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000521 }
522 }
mpagenkof1fc3862021-02-16 10:09:52 +0000523 oFsm.mutexFlowParams.Unlock()
524
525 if !flowEntryMatch { //it is (was) a new rule
mpagenkobc4170a2021-08-17 16:42:10 +0000526 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
527 if !deleteSuccess {
528 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
529 "device-id": oFsm.deviceID, "cookie": delayedCookie})
530 return fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
531 }
mpagenkof1fc3862021-02-16 10:09:52 +0000532 requestAppendRule = true //default assumption here is that rule is to be appended
533 flowCookieModify = true //and that the the flow data base is to be updated
534 if delayedCookie != 0 { //it was suspended
535 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
536 }
537 }
538 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
539 if requestAppendRule {
540 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000541 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000542 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
543 loFlowParams.CookieSlice = make([]uint64, 0)
544 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300545 if aMeter != nil {
546 loFlowParams.Meter = aMeter
547 }
mpagenko01e726e2020-10-23 09:45:29 +0000548 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000549 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000550 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
551 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
552 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800553 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300554 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000555
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +0000556 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
557 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
558 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000559 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000560 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
561
562 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
563 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
564 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000565 //attention: take care to release the mutexFlowParams when calling the FSM directly -
566 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000567 oFsm.mutexFlowParams.Unlock()
568 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000569 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
570 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
571 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
572 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000573 }
574 return nil
575 }
mpagenko01e726e2020-10-23 09:45:29 +0000576 // note: theoretical it would be possible to clear the same rule from the remove slice
577 // (for entries that have not yet been started with removal)
578 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
579 // 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 +0000580
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000581 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
582 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000583 if oFsm.configuredUniFlow == 0 {
584 // this is a restart with a complete new flow, we can re-use the initial flow config control
585 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000586 //attention: take care to release the mutexFlowParams when calling the FSM directly -
587 // synchronous FSM 'event/state' functions may rely on this mutex
588 oFsm.mutexFlowParams.Unlock()
589 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
590 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
591 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
592 }
mpagenko551a4d42020-12-08 18:09:20 +0000593 } else {
594 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000595 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000596 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
597 //check introduced after having observed some panic here
598 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
599 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
600 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
601 oFsm.mutexFlowParams.Unlock()
602 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
603 }
mpagenko9a304ea2020-12-16 15:54:01 +0000604 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300605 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +0000606 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000607 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000608 oFsm.TpIDWaitingFor = tpID
mpagenko45cc6a32021-07-23 10:06:57 +0000609 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000610 //attention: take care to release the mutexFlowParams when calling the FSM directly -
611 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko45cc6a32021-07-23 10:06:57 +0000612 // but it must be released already before calling getTechProfileDone() as it may already be locked
613 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000614 oFsm.mutexFlowParams.Unlock()
mpagenko45cc6a32021-07-23 10:06:57 +0000615 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
616 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
617 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
618 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
619
mpagenkobb47bc22021-04-20 13:29:09 +0000620 var fsmErr error
621 if loTechProfDone {
622 // let the vlan processing continue with next rule
623 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
624 } else {
625 // set to waiting for Techprofile
626 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
627 }
628 if fsmErr != nil {
629 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
630 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
631 }
mpagenko551a4d42020-12-08 18:09:20 +0000632 }
mpagenkobb47bc22021-04-20 13:29:09 +0000633 } else {
634 // if not in the appropriate state a new entry will be automatically considered later
635 // when the configDone state is reached
636 oFsm.mutexFlowParams.Unlock()
637 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000638 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000639 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000640 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000641 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000642 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
643 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000644 } else {
645 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000646 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000647 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000648 if oFsm.numUniFlows == oFsm.configuredUniFlow {
649 //all requested rules really have been configured
650 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000651 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000652 if oFsm.pDeviceHandler != nil {
653 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000654 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000655 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000656 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
657 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000658 }
659 } else {
660 // avoid device reason update as the rule config connected to this flow may still be in progress
661 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000662 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000663 log.Fields{"device-id": oFsm.deviceID,
664 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000665 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000666 }
667 }
mpagenko01e726e2020-10-23 09:45:29 +0000668
mpagenkof1fc3862021-02-16 10:09:52 +0000669 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000670 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000671 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000672 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
673 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000674 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000675 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000676 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000677 }
mpagenko15ff4a52021-03-02 10:09:20 +0000678 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000679 }
680 return nil
681}
682
mpagenkof1d21d12021-06-11 13:14:45 +0000683func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
684 oFsm.mutexFlowParams.Lock()
685 deleteChannel := apRemoveFlowParams.removeChannel
686 apRemoveFlowParams.isSuspendedOnAdd = true
687 oFsm.mutexFlowParams.Unlock()
688
689 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
690 select {
691 case success := <-deleteChannel:
692 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
693 if success {
694 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
695 "device-id": oFsm.deviceID})
696 return nil
697 }
698 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
699 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
700 oFsm.mutexFlowParams.Lock()
701 if apRemoveFlowParams != nil {
702 apRemoveFlowParams.isSuspendedOnAdd = false
703 }
704 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000705 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000706 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000707 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000708 }
mpagenkof1d21d12021-06-11 13:14:45 +0000709}
710
mpagenkof1fc3862021-02-16 10:09:52 +0000711// VOL-3828 flow config sequence workaround ########### start ##########
712func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
713 //assumes mutexFlowParams.Lock() protection from caller!
714 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
715 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000716 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000717 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
718 newCookie := aCookieSlice[0]
719 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
720 for _, cookie := range storedUniFlowParams.CookieSlice {
721 if cookie == newCookie {
722 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
723 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
724 oFsm.delayNewRuleCookie = newCookie
725 return newCookie //found new cookie in some existing rule
726 }
727 } // for all stored cookies of the actual inspected rule
728 } //for all rules
729 }
730 return 0 //no delay requested
731}
mpagenkobc4170a2021-08-17 16:42:10 +0000732func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000733 oFsm.mutexFlowParams.RLock()
734 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
735 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
736 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000737 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000738 select {
mpagenkobc4170a2021-08-17 16:42:10 +0000739 case cookieDeleted = <-oFsm.chCookieDeleted:
740 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
741 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000742 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000743 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
744 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
745 }
746 oFsm.mutexFlowParams.Lock()
747 oFsm.delayNewRuleCookie = 0
748 oFsm.mutexFlowParams.Unlock()
mpagenkobc4170a2021-08-17 16:42:10 +0000749 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000750}
mpagenkobc4170a2021-08-17 16:42:10 +0000751func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000752 oFsm.mutexFlowParams.Lock()
753 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
754 oFsm.mutexFlowParams.Unlock()
755
mpagenkobc4170a2021-08-17 16:42:10 +0000756 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000757 if delayedCookie != 0 {
mpagenkobc4170a2021-08-17 16:42:10 +0000758 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000759 }
mpagenkobc4170a2021-08-17 16:42:10 +0000760 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000761}
762
763//returns flowModified, RuleAppendRequest
764func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
765 flowEntryMatch := false
766 oFsm.mutexFlowParams.Lock()
767 defer oFsm.mutexFlowParams.Unlock()
768 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
769 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
770 flowEntryMatch = true
771 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
772 "device-id": oFsm.deviceID})
773 cookieMatch := false
774 for _, cookie := range storedUniFlowParams.CookieSlice {
775 if cookie == aCookie {
776 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
777 "device-id": oFsm.deviceID, "cookie": cookie})
778 cookieMatch = true
779 break //found new cookie - no further search for this requested cookie
780 }
781 }
782 if !cookieMatch {
783 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
784 "device-id": oFsm.deviceID, "cookie": aCookie})
785 //as range works with copies of the slice we have to write to the original slice!!
786 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
787 aCookie)
788 return true, false //flowModified, NoRuleAppend
789 }
790 break // found rule - no further rule search
791 }
792 }
793 if !flowEntryMatch { //it is a new rule
794 return true, true //flowModified, RuleAppend
795 }
796 return false, false //flowNotModified, NoRuleAppend
797}
798
799// VOL-3828 flow config sequence workaround ########### end ##########
800
mpagenko01e726e2020-10-23 09:45:29 +0000801//RemoveUniFlowParams verifies on existence of flow cookie,
802// if found removes cookie from flow cookie list and if this is empty
803// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000804func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000805 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000806 flowCookieMatch := false
807 //mutex protection is required for possible concurrent access to FSM members
808 oFsm.mutexFlowParams.Lock()
809 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000810remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000811 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
812 for i, cookie := range storedUniFlowParams.CookieSlice {
813 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000814 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000815 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000816 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000817 //remove the cookie from the cookie slice and verify it is getting empty
818 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000819 // had to shift content to function due to sca complexity
820 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenkodee02a62021-07-21 10:56:10 +0000821 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000822 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000823 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000824 //cut off the requested cookie by slicing out this element
825 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
826 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
827 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000828 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
829 // state transition notification is checked in deviceHandler
830 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000831 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
832 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000833 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000834 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000835 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000836 if deletedCookie == oFsm.delayNewRuleCookie {
837 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
838 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
839 //simply use the first one
840 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
841 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
842 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
843 }
mpagenkodee02a62021-07-21 10:56:10 +0000844 //permanently store the modified flow config for reconcile case and immediately write to KvStore
845 if oFsm.pDeviceHandler != nil {
846 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
847 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
848 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
849 return err
850 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000851 }
mpagenko01e726e2020-10-23 09:45:29 +0000852 }
mpagenkof1fc3862021-02-16 10:09:52 +0000853 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000854 }
855 }
mpagenko01e726e2020-10-23 09:45:29 +0000856 } //search all flows
857 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000858 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000859 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
860 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000861 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
862 // state transition notification is checked in deviceHandler
863 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000864 // success indication without the need to write to kvStore (no change)
865 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000866 }
mpagenko01e726e2020-10-23 09:45:29 +0000867 return nil
868 } //unknown cookie
869
870 return nil
871}
872
mpagenkof582d6a2021-06-18 15:58:10 +0000873// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenkodee02a62021-07-21 10:56:10 +0000874// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000875func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
876 aUniFlowParams uniVlanFlowParams, aCookie uint64) bool {
877 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
878 var cancelPendingConfig bool = false
879 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
880 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
881 "device-id": oFsm.deviceID})
882 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
883 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
884 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
885 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
886 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
887 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
888 log.Fields{"device-id": oFsm.deviceID})
889 cancelPendingConfig = true
890 } else {
891 //create a new element for the removeVlanFlow slice
892 loRemoveParams = uniRemoveVlanFlowParams{
893 vlanRuleParams: aUniFlowParams.VlanRuleParams,
894 cookie: aCookie,
895 }
896 loRemoveParams.removeChannel = make(chan bool)
897 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
898 }
899
900 usedTpID := aUniFlowParams.VlanRuleParams.TpID
901 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
902 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
903 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
904 if !cancelPendingConfig {
mpagenko3ce9fa02021-07-28 13:26:54 +0000905 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
906 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000907 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
908 "device-id": oFsm.deviceID})
909 if oFsm.pUniTechProf != nil {
910 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
911 }
mpagenko3ce9fa02021-07-28 13:26:54 +0000912 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000913 }
914 } else {
915 if !cancelPendingConfig {
916 oFsm.updateTechProfileToDelete(ctx, usedTpID)
917 }
918 }
919 //trigger the FSM to remove the relevant rule
920 if cancelPendingConfig {
921 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
922 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
923 //call from 'non-configured' state of the rules
924 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
925 //something quite inconsistent detected, perhaps just try to recover with FSM reset
926 oFsm.mutexFlowParams.Unlock()
927 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvReset); fsmErr != nil {
928 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
929 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
930 }
931 return false //data base update could not be done, return like cookie not found
932 }
933
934 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
935 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
936 // synchronous FSM 'event/state' functions may rely on this mutex
937 oFsm.mutexFlowParams.Unlock()
938 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
939 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
940 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
941 }
942 oFsm.mutexFlowParams.Lock()
943 return true
944 }
945 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
946 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
947 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
948 "tp-id": loRemoveParams.vlanRuleParams.TpID,
949 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
950 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
951 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
952 // synchronous FSM 'event/state' functions may rely on this mutex
953 oFsm.mutexFlowParams.Unlock()
954 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
955 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
956 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
957 }
958 oFsm.mutexFlowParams.Lock()
959 } // if not in the appropriate state a new entry will be automatically considered later
960 // when the configDone state is reached
961 return true
962}
963
mpagenkof1d21d12021-06-11 13:14:45 +0000964//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
965// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
966// from the start of the deletion request to avoid to much interference
967// so when called, there can only be one cookie active for this flow
968// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000969func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000970 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
971 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000972 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000973removeFromSlice_loop:
974 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000975 // if UniFlowParams exists, cookieSlice should always have at least one element
976 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
977 if cookieSliceLen == 1 {
978 if storedUniFlowParams.CookieSlice[0] == aCookie {
979 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +0000980 }
mpagenkof582d6a2021-06-18 15:58:10 +0000981 } else if cookieSliceLen == 0 {
982 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
983 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
984 return errors.New(errStr)
985 } else {
986 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
987 logger.Errorw(ctx, errStr, log.Fields{
988 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
989 for _, cookie := range storedUniFlowParams.CookieSlice {
990 if cookie == aCookie {
991 cookieFound = true
992 break
993 }
994 }
995 }
996 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +0000997 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
998 "device-id": oFsm.deviceID, "cookie": aCookie})
999 //remove the actual element from the addVlanFlow slice
1000 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1001 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
1002 oFsm.numUniFlows = 0 //no more flows
1003 oFsm.configuredUniFlow = 0 //no more flows configured
1004 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1005 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1006 //request that this profile gets deleted before a new flow add is allowed
1007 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1008 "device-id": oFsm.deviceID})
1009 } else {
1010 oFsm.numUniFlows--
1011 if aWasConfigured && oFsm.configuredUniFlow > 0 {
1012 oFsm.configuredUniFlow--
1013 }
1014 //cut off the requested flow by slicing out this element
1015 oFsm.uniVlanFlowParamsSlice = append(
1016 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1017 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1018 "device-id": oFsm.deviceID})
1019 }
1020 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1021 }
1022 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001023 if !cookieFound {
1024 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1025 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1026 return errors.New(errStr)
1027 }
mpagenkodee02a62021-07-21 10:56:10 +00001028 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1029 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
1030 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
1031 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1032 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1033 return err
1034 }
mpagenkof582d6a2021-06-18 15:58:10 +00001035 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001036}
1037
1038// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001039func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1040 //here we have to check, if there are still other flows referencing to the actual ProfileId
1041 // before we can request that this profile gets deleted before a new flow add is allowed
1042 tpIDInOtherFlows := false
1043 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1044 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1045 tpIDInOtherFlows = true
1046 break // search loop can be left
1047 }
1048 }
1049 if tpIDInOtherFlows {
1050 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1051 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1052 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001053 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 +00001054 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko3ce9fa02021-07-28 13:26:54 +00001055 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1056 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001057 if oFsm.pUniTechProf != nil {
1058 //request that this profile gets deleted before a new flow add is allowed
1059 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
1060 }
mpagenko3ce9fa02021-07-28 13:26:54 +00001061 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001062 }
1063}
1064
mpagenkof1d21d12021-06-11 13:14:45 +00001065func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1066 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001067
1068 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001069 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001070 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001071 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001072 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001073 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001074 //let the state machine run forward from here directly
1075 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1076 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001077 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1078 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
1079 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001080 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001081 go func(a_pAFsm *AdapterFsm) {
1082 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
1083 }(pConfigVlanStateAFsm)
1084 return
1085 }
mpagenkof1d21d12021-06-11 13:14:45 +00001086 // Can't call FSM Event directly, decoupling it
1087 go func(a_pAFsm *AdapterFsm) {
1088 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
1089 }(pConfigVlanStateAFsm)
1090 return
1091 }
1092 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1093 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1094 //should never happen, else: recovery would be needed from outside the FSM
1095}
1096
1097func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1098 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1099 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1100 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001101 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001102 //possibly the entry is not valid anymore based on intermediate delete requests
1103 //just a basic protection ...
1104 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1105 oFsm.mutexFlowParams.Unlock()
1106 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1107 "device-id": oFsm.deviceID})
1108 // Can't call FSM Event directly, decoupling it
1109 go func(a_pAFsm *AdapterFsm) {
1110 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1111 }(pConfigVlanStateAFsm)
1112 return
1113 }
mpagenko9a304ea2020-12-16 15:54:01 +00001114 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1115 //store the actual rule that shall be worked upon in the following transient states
1116 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001117 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
mpagenko9a304ea2020-12-16 15:54:01 +00001118 tpID := oFsm.actualUniVlanConfigRule.TpID
1119 oFsm.TpIDWaitingFor = tpID
Girish Gowdra24dd1132021-07-06 15:25:40 -07001120 //cmp also usage in EVTOCDE create in omci_cc
1121 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko45cc6a32021-07-23 10:06:57 +00001122 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1123 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1124 // synchronous FSM 'event/state' functions may rely on this mutex
1125 // but it must be released already before calling getTechProfileDone() as it may already be locked
1126 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001127 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001128 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001129 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1130 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001131 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001132
mpagenko9a304ea2020-12-16 15:54:01 +00001133 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001134 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1135 if aPAFsm != nil && aPAFsm.pFsm != nil {
1136 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001137 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001138 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001139 } else {
1140 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001141 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001142 }
1143 }
mpagenko551a4d42020-12-08 18:09:20 +00001144 }(pConfigVlanStateAFsm, loTechProfDone)
1145 } else {
1146 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1147 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1148 //should never happen, else: recovery would be needed from outside the FSM
1149 return
mpagenkodff5dda2020-08-28 11:52:01 +00001150 }
1151}
1152
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001154 //mutex protection is required for possible concurrent access to FSM members
1155 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001156 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001157 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001158 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001159 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001160 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001161 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001162 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001163 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001164 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001165 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301166 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001167 }(pConfigVlanStateAFsm)
1168 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001169 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1170 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001171 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001173 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001174 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1175 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001176 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001177 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001178 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001179 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001180 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1181 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001182 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001183 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001184 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001185 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1186 "ForwardOperation": uint8(0x10), //VID investigation
1187 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001188 },
1189 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001190 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001191 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001192 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001193 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001194 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001195 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001196 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001197 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1198 log.Fields{"device-id": oFsm.deviceID})
1199 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1200 if pConfigVlanStateAFsm != nil {
1201 go func(a_pAFsm *AdapterFsm) {
1202 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1203 }(pConfigVlanStateAFsm)
1204 }
1205 return
1206 }
mpagenkodff5dda2020-08-28 11:52:01 +00001207 //accept also nil as (error) return value for writing to LastTx
1208 // - this avoids misinterpretation of new received OMCI messages
1209 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1210 // send shall return (dual format) error code that can be used here for immediate error treatment
1211 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001212 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001213 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001214 }
1215}
1216
dbainbri4d3a0dc2020-12-02 00:33:42 +00001217func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1218 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001219 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001220 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001221 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001222 //using the first element in the slice because it's the first flow per definition here
1223 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001224 //This is correct passing scenario
1225 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001226 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001227 tpID := oFsm.actualUniVlanConfigRule.TpID
1228 vlanID := oFsm.actualUniVlanConfigRule.SetVid
mpagenko3ce9fa02021-07-28 13:26:54 +00001229 configuredUniFlows := oFsm.configuredUniFlow
1230 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1231 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001232 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1233 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
mpagenko3ce9fa02021-07-28 13:26:54 +00001234 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001236 vlanID)
1237 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001239 log.Fields{"device-id": oFsm.deviceID})
1240 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1241 }
1242 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001243 //If this first flow contains a meter, then create TD for related gems.
1244 if oFsm.actualUniVlanConfigMeter != nil {
1245 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter})
1246 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1247 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1248 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1249 oFsm.pOnuUniPort.uniID, gemPort)
1250 if errCreateTrafficDescriptor != nil {
1251 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1252 log.Fields{"device-id": oFsm.deviceID})
1253 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1254 }
1255 }
1256 }
1257
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001258 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1259 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1260 }
1261 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001262}
1263
dbainbri4d3a0dc2020-12-02 00:33:42 +00001264func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001265
mpagenkof1d21d12021-06-11 13:14:45 +00001266 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001267
mpagenkof1fc3862021-02-16 10:09:52 +00001268 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001269 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001270 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1271 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1272 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001273 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001274 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1275 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1276 //should never happen, else: recovery would be needed from outside the FSM
1277 return
1278 }
1279 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001280 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1281 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001282 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1283 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1284 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1285 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001286 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001287 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001288 go func(a_pBaseFsm *fsm.FSM) {
1289 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1290 }(pConfigVlanStateBaseFsm)
1291 return
1292 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001293 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1294 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001295 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001296 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001297 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001298 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1299 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001300 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1301 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001302 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001303 return
1304 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001305 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001306 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001307 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001308 // this is a restart with a complete new flow, we can re-use the initial flow config control
1309 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001310 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001311 go func(a_pBaseFsm *fsm.FSM) {
1312 _ = a_pBaseFsm.Event(vlanEvRenew)
1313 }(pConfigVlanStateBaseFsm)
1314 return
1315 }
1316
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001317 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001318 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001319 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1320 //check introduced after having observed some panic in this processing
1321 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1322 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1323 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1324 oFsm.mutexFlowParams.Unlock()
1325 go func(a_pAFsm *AdapterFsm) {
1326 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1327 }(pConfigVlanStateAFsm)
1328 return
1329 }
mpagenko9a304ea2020-12-16 15:54:01 +00001330 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001331 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +00001332 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001333 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001334 oFsm.TpIDWaitingFor = tpID
mpagenko45cc6a32021-07-23 10:06:57 +00001335 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1336 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1337 // synchronous FSM 'event/state' functions may rely on this mutex
1338 // but it must be released already before calling getTechProfileDone() as it may already be locked
1339 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1340 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001341 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001342 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1343 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko45cc6a32021-07-23 10:06:57 +00001344 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1345
mpagenko9a304ea2020-12-16 15:54:01 +00001346 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001347 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1348 if aTechProfDone {
1349 // let the vlan processing continue with next rule
1350 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1351 } else {
1352 // set to waiting for Techprofile
1353 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1354 }
1355 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001356 return
1357 }
mpagenkof1d21d12021-06-11 13:14:45 +00001358 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001359 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001360 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001361 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1362 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001363 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001364 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001365 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001366 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001367 }
1368}
1369
dbainbri4d3a0dc2020-12-02 00:33:42 +00001370func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001371
1372 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1373 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1374 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1375 go func(a_pBaseFsm *fsm.FSM) {
1376 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1377 }(oFsm.pAdaptFsm.pFsm)
1378 return
1379 }
mpagenko15ff4a52021-03-02 10:09:20 +00001380 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001382 "recent flow-number": oFsm.configuredUniFlow,
1383 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001384 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001385
mpagenko9a304ea2020-12-16 15:54:01 +00001386 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001387 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001388 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001389 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001390 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001391 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1392 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1393 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1394 // 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 +00001395 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001396 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1397 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001398 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001399 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001400 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001401 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001402 "device-id": oFsm.deviceID,
1403 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001404 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001405 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001406
mpagenko01e726e2020-10-23 09:45:29 +00001407 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001408 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1409 oFsm.numVlanFilterEntries = 1
1410 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001411 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001412 Attributes: me.AttributeValueMap{
1413 "VlanFilterList": vtfdFilterList,
1414 "ForwardOperation": uint8(0x10), //VID investigation
1415 "NumberOfEntries": oFsm.numVlanFilterEntries,
1416 },
1417 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001418 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001419 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001420 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001421 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001422 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001423 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001424 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1425 log.Fields{"device-id": oFsm.deviceID})
1426 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1427 if pConfigVlanStateAFsm != nil {
1428 go func(a_pAFsm *AdapterFsm) {
1429 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1430 }(pConfigVlanStateAFsm)
1431 }
1432 return
1433 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001434 //accept also nil as (error) return value for writing to LastTx
1435 // - this avoids misinterpretation of new received OMCI messages
1436 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1437 // send shall return (dual format) error code that can be used here for immediate error treatment
1438 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001439 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001440 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001441 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001442 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1443 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001444 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001445
dbainbri4d3a0dc2020-12-02 00:33:42 +00001446 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001447 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001448 "device-id": oFsm.deviceID,
1449 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001450 // setVid is assumed to be masked already by the caller to 12 bit
1451 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001452 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001453 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001454
1455 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1456 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1457 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001458 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001459
1460 oFsm.numVlanFilterEntries++
1461 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001462 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001463 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001464 "VlanFilterList": vtfdFilterList,
1465 "ForwardOperation": uint8(0x10), //VID investigation
1466 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001467 },
1468 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001469 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001470 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001471 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001472 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001473 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001474 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001475 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1476 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1477 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1478 return
1479 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001480 //accept also nil as (error) return value for writing to LastTx
1481 // - this avoids misinterpretation of new received OMCI messages
1482 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1483 // send shall return (dual format) error code that can be used here for immediate error treatment
1484 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001485 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001486 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001487 }
1488 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001489 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001490 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001491 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001492 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001493 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001494 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001495 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001496 go func(a_pBaseFsm *fsm.FSM) {
1497 _ = a_pBaseFsm.Event(vlanEvReset)
1498 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001499 return
1500 }
1501 }
mpagenkof1d21d12021-06-11 13:14:45 +00001502
mpagenkof1fc3862021-02-16 10:09:52 +00001503 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001504 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001505 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001506 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001507 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001508 configuredUniFlow := oFsm.configuredUniFlow
mpagenko3ce9fa02021-07-28 13:26:54 +00001509 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001510 oFsm.mutexFlowParams.RUnlock()
1511 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001512 //This is correct passing scenario
1513 if errEvto == nil {
1514 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001516 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001517 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001519 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001520 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001521 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001522 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001523 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001524 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001525 log.Fields{"device-id": oFsm.deviceID})
1526 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1527 }
1528 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001529 //If this incremental flow contains a meter, then create TD for related gems.
1530 if oFsm.actualUniVlanConfigMeter != nil {
1531 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1532 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1533 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1534 oFsm.pOnuUniPort.uniID, gemPort)
1535 if errCreateTrafficDescriptor != nil {
1536 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1537 log.Fields{"device-id": oFsm.deviceID})
1538 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1539 }
1540 }
1541 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001542 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1543 }
1544 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001545}
1546
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001548 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001549 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001550 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1551 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001552
mpagenkofc4f56e2020-11-04 17:17:49 +00001553 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001554 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001555 loVlanEntryClear := uint8(0)
1556 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1557 //shallow copy is sufficient as no reference variables are used within struct
1558 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001559 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001561 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1562 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1563 "device-id": oFsm.deviceID})
1564
1565 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1566 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001567 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001568 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1569 } else {
1570 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1571 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001572 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001573 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1574 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001576 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001577 "device-id": oFsm.deviceID,
1578 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001579 loVlanEntryClear = 1 //full VlanFilter clear request
1580 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001581 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001582 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001583 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001584 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001585 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001586 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1587 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1588 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1589 return
1590 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001591 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001592 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001593 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001594 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001595 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001596 }
mpagenko01e726e2020-10-23 09:45:29 +00001597 } else {
1598 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1599 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001600 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001601 log.Fields{"current vlan list": oFsm.vlanFilterList,
1602 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1603 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1604 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1605 loVlanEntryRmPos = i
1606 break //abort search
1607 }
1608 }
1609 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001610 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001611 //valid entry was found - to be eclipsed
1612 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1613 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1614 if i < loVlanEntryRmPos {
1615 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1616 } else if i < (cVtfdTableSize - 1) {
1617 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1618 } else {
1619 vtfdFilterList[i] = 0 //set last byte if needed
1620 }
1621 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001622 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001623 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001624 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1625 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001626
mpagenkofc4f56e2020-11-04 17:17:49 +00001627 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001628 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001629 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001630 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001631 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001632 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001633 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001634 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1635 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1636 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1637 return
1638 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001639 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001640 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001641 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001642 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001643 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001644 }
mpagenko01e726e2020-10-23 09:45:29 +00001645 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001647 log.Fields{"device-id": oFsm.deviceID})
1648 }
1649 }
1650 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001651 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1652 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001653 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001654 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001655 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001656 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001657 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001658 go func(a_pBaseFsm *fsm.FSM) {
1659 _ = a_pBaseFsm.Event(vlanEvReset)
1660 }(pConfigVlanStateBaseFsm)
1661 return
1662 }
mpagenko01e726e2020-10-23 09:45:29 +00001663 }
1664
mpagenko15ff4a52021-03-02 10:09:20 +00001665 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001666 if loVlanEntryClear == 1 {
1667 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1668 oFsm.numVlanFilterEntries = 0
1669 } else if loVlanEntryClear == 2 {
1670 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1671 // this loop now includes the 0 element on previous last valid entry
1672 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1673 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1674 }
1675 oFsm.numVlanFilterEntries--
1676 }
mpagenko15ff4a52021-03-02 10:09:20 +00001677 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001678 }
1679 }
1680
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001682 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001683 } else {
1684 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001685 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001686 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001687 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001688 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001689 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001690 }(pConfigVlanStateBaseFsm)
1691 }
mpagenkodff5dda2020-08-28 11:52:01 +00001692}
1693
dbainbri4d3a0dc2020-12-02 00:33:42 +00001694func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001695 var tpID uint8
1696 // Extract the tpID
1697 if len(e.Args) > 0 {
1698 tpID = e.Args[0].(uint8)
1699 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1700 } else {
1701 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1702 }
mpagenko01e726e2020-10-23 09:45:29 +00001703 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001704 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001705
mpagenkof582d6a2021-06-18 15:58:10 +00001706 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1707 if pConfigVlanStateAFsm == nil {
1708 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1709 log.Fields{"device-id": oFsm.deviceID})
1710 //would have to be fixed from outside somehow
1711 return
1712 }
1713
mpagenkof1d21d12021-06-11 13:14:45 +00001714 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1715 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001716 //call from 'configured' state of the rule
1717 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1718 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1719 oFsm.mutexFlowParams.Unlock()
1720 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
1721 go func(a_pAFsm *AdapterFsm) {
1722 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1723 }(pConfigVlanStateAFsm)
1724 return
1725 }
mpagenkof1d21d12021-06-11 13:14:45 +00001726 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1727 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1728 oFsm.mutexFlowParams.Unlock()
1729 removeChannel <- true
1730 oFsm.mutexFlowParams.Lock()
1731 }
1732
mpagenkof1fc3862021-02-16 10:09:52 +00001733 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1734 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1735 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1736
mpagenko01e726e2020-10-23 09:45:29 +00001737 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1738 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001739 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001740 "device-id": oFsm.deviceID})
1741 } else {
1742 //cut off the actual flow by slicing out the first element
1743 oFsm.uniRemoveFlowsSlice = append(
1744 oFsm.uniRemoveFlowsSlice[:0],
1745 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001747 "device-id": oFsm.deviceID})
1748 }
1749 oFsm.mutexFlowParams.Unlock()
1750
mpagenkof1fc3862021-02-16 10:09:52 +00001751 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001752 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001753 // Can't call FSM Event directly, decoupling it
1754 go func(a_pAFsm *AdapterFsm) {
1755 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
1756 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001757
mpagenkobb47bc22021-04-20 13:29:09 +00001758 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001759 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001760 if deletedCookie == oFsm.delayNewRuleCookie {
1761 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1762 select {
1763 case <-oFsm.chCookieDeleted:
1764 logger.Debug(ctx, "flushed CookieDeleted")
1765 default:
1766 }
1767 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1768 }
mpagenkobb47bc22021-04-20 13:29:09 +00001769 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1770 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1771 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 -08001772 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001773 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1774 oFsm.flowDeleteChannel <- true
1775 oFsm.signalOnFlowDelete = false
1776 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001777 }
mpagenkobb47bc22021-04-20 13:29:09 +00001778 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001779}
1780
dbainbri4d3a0dc2020-12-02 00:33:42 +00001781func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1782 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001783
1784 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1785 if pConfigVlanStateAFsm != nil {
1786 // abort running message processing
1787 fsmAbortMsg := Message{
1788 Type: TestMsg,
1789 Data: TestMessage{
1790 TestMessageVal: AbortMessageProcessing,
1791 },
1792 }
1793 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1794
mpagenko9a304ea2020-12-16 15:54:01 +00001795 //try to restart the FSM to 'disabled'
1796 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001797 go func(a_pAFsm *AdapterFsm) {
1798 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301799 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001800 }
1801 }(pConfigVlanStateAFsm)
1802 }
1803}
1804
dbainbri4d3a0dc2020-12-02 00:33:42 +00001805func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1806 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001807 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001808 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001809 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001810
1811 oFsm.mutexFlowParams.RLock()
1812 if oFsm.delayNewRuleCookie != 0 {
1813 // looks like the waiting AddFlow is stuck
1814 oFsm.mutexFlowParams.RUnlock()
mpagenkobc4170a2021-08-17 16:42:10 +00001815 oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
mpagenkof1d21d12021-06-11 13:14:45 +00001816 oFsm.mutexFlowParams.RLock()
1817 }
1818 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1819 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1820 if removeUniFlowParams.isSuspendedOnAdd {
1821 removeChannel := removeUniFlowParams.removeChannel
1822 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1823 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1824 oFsm.mutexFlowParams.RUnlock()
1825 removeChannel <- false
1826 oFsm.mutexFlowParams.RLock()
1827 }
1828 }
1829 }
1830
mpagenkodff5dda2020-08-28 11:52:01 +00001831 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001832 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1833 // current code removes the complete FSM including all flow/rule configuration done so far
1834 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1835 // maybe a more sophisticated approach is possible without clearing the data
1836 if oFsm.clearPersistency {
1837 //permanently remove possibly stored persistent data
1838 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1839 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001840 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001841 }
1842 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001844 }
mpagenko9a304ea2020-12-16 15:54:01 +00001845 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001846 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001847 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001848 return
mpagenkodff5dda2020-08-28 11:52:01 +00001849 }
mpagenkof1d21d12021-06-11 13:14:45 +00001850 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001851}
1852
dbainbri4d3a0dc2020-12-02 00:33:42 +00001853func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1854 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001855loop:
1856 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001857 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001858 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001859 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301860 message, ok := <-oFsm.pAdaptFsm.commChan
1861 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301863 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1864 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1865 break loop
1866 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001867 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301868
1869 switch message.Type {
1870 case TestMsg:
1871 msg, _ := message.Data.(TestMessage)
1872 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001873 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001874 break loop
1875 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301877 case OMCI:
1878 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301880 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301882 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001883 }
1884 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001886}
1887
dbainbri4d3a0dc2020-12-02 00:33:42 +00001888func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1889 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001890 "msgType": msg.OmciMsg.MessageType})
1891
1892 switch msg.OmciMsg.MessageType {
1893 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001894 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1896 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001897 return
1898 }
mpagenkodff5dda2020-08-28 11:52:01 +00001899 } //CreateResponseType
1900 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001901 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001902 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1903 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001905 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001906 return
1907 }
1908 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1909 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001910 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001911 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001912 return
1913 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001914 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001915 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001916 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001917 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001918 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1919 return
1920 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001921 oFsm.mutexPLastTxMeInstance.RLock()
1922 if oFsm.pLastTxMeInstance != nil {
1923 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1924 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1925 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001926 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001927 { // let the MultiEntity config proceed by stopping the wait function
1928 oFsm.mutexPLastTxMeInstance.RUnlock()
1929 oFsm.omciMIdsResponseReceived <- true
1930 return
1931 }
1932 default:
1933 {
1934 logger.Warnw(ctx, "Unsupported ME name received!",
1935 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1936 }
mpagenkodff5dda2020-08-28 11:52:01 +00001937 }
1938 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001939 } else {
1940 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001941 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001942 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001943 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001944 case omci.DeleteResponseType:
1945 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001946 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1947 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001948 return
1949 }
1950 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001951 default:
1952 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001953 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001954 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001955 return
1956 }
1957 }
1958}
1959
dbainbri4d3a0dc2020-12-02 00:33:42 +00001960func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001961 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1962 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001963 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001964 log.Fields{"device-id": oFsm.deviceID})
1965 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1966 oFsm.deviceID)
1967 }
1968 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1969 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001970 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001971 log.Fields{"device-id": oFsm.deviceID})
1972 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1973 oFsm.deviceID)
1974 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001975 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001976 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001977 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001978 "Error": msgObj.Result})
1979 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1980 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1981 oFsm.deviceID)
1982 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001983 oFsm.mutexPLastTxMeInstance.RLock()
1984 if oFsm.pLastTxMeInstance != nil {
1985 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1986 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1987 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1988 switch oFsm.pLastTxMeInstance.GetName() {
1989 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1990 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03001991 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001992 {
1993 oFsm.mutexPLastTxMeInstance.RUnlock()
1994 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1995 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1996 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1997 } else { // let the MultiEntity config proceed by stopping the wait function
1998 oFsm.omciMIdsResponseReceived <- true
1999 }
2000 return nil
2001 }
2002 default:
2003 {
2004 logger.Warnw(ctx, "Unsupported ME name received!",
2005 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002006 }
2007 }
2008 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002009 } else {
2010 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002011 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002012 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002013 return nil
2014}
2015
dbainbri4d3a0dc2020-12-02 00:33:42 +00002016func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002017 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2018 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002019 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002020 log.Fields{"device-id": oFsm.deviceID})
2021 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2022 oFsm.deviceID)
2023 }
2024 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2025 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002026 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002027 log.Fields{"device-id": oFsm.deviceID})
2028 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2029 oFsm.deviceID)
2030 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002031 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002032 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002033 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002034 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2035 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2036 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2037 oFsm.deviceID)
2038 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002039 oFsm.mutexPLastTxMeInstance.RLock()
2040 if oFsm.pLastTxMeInstance != nil {
2041 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2042 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2043 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002044 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002045 { // let the MultiEntity config proceed by stopping the wait function
2046 oFsm.mutexPLastTxMeInstance.RUnlock()
2047 oFsm.omciMIdsResponseReceived <- true
2048 return nil
2049 }
2050 default:
2051 {
2052 logger.Warnw(ctx, "Unsupported ME name received!",
2053 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2054 }
mpagenko01e726e2020-10-23 09:45:29 +00002055 }
2056 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002057 } else {
2058 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002059 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002060 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002061 return nil
2062}
2063
dbainbri4d3a0dc2020-12-02 00:33:42 +00002064func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002065 oFsm.mutexFlowParams.RLock()
2066 evtocdID := oFsm.evtocdID
2067 oFsm.mutexFlowParams.RUnlock()
2068
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002069 if aFlowEntryNo == 0 {
2070 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002071 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2072 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002073 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002074 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002075 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002076 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002077 associationType := 2 // default to uniPPTP
2078 if oFsm.pOnuUniPort.portType == uniVEIP {
2079 associationType = 10
2080 }
2081 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002082 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002083 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002084 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002085 "AssociationType": uint8(associationType),
2086 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002087 },
2088 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002089 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002090 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
2091 true, oFsm.pAdaptFsm.commChan, meParams)
2092 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002093 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002094 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2095 log.Fields{"device-id": oFsm.deviceID})
2096 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2097 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2098 }
mpagenkodff5dda2020-08-28 11:52:01 +00002099 //accept also nil as (error) return value for writing to LastTx
2100 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002101 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002102 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002103
2104 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002105 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002106 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002107 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002108 log.Fields{"device-id": oFsm.deviceID})
2109 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2110 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2111 }
2112
2113 // Set the EVTOCD ME default params
2114 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002115 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002116 Attributes: me.AttributeValueMap{
2117 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2118 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2119 "DownstreamMode": uint8(cDefaultDownstreamMode),
2120 },
2121 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002122 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002123 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2124 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002125 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002126 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002127 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002128 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2129 log.Fields{"device-id": oFsm.deviceID})
2130 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2131 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2132 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002133 //accept also nil as (error) return value for writing to LastTx
2134 // - this avoids misinterpretation of new received OMCI messages
2135 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002136 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002137
2138 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002139 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002140 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002141 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002142 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302143 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002144 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002145 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002146 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002147
mpagenko551a4d42020-12-08 18:09:20 +00002148 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002149 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002150 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002151 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002152 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002153 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002154 sliceEvtocdRule := make([]uint8, 16)
2155 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2156 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2157 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2158 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2159 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2160
2161 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2162 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2163 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2164 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2165 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2166
2167 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2168 0<<cTreatTTROffset| // Do not pop any tags
2169 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2170 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2171 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2172
2173 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2174 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2175 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2176 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2177
2178 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002179 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002180 Attributes: me.AttributeValueMap{
2181 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2182 },
2183 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002184 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002185 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2186 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002187 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002188 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002189 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002190 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2191 log.Fields{"device-id": oFsm.deviceID})
2192 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2193 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2194 }
mpagenkodff5dda2020-08-28 11:52:01 +00002195 //accept also nil as (error) return value for writing to LastTx
2196 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002197 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002198 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002199
2200 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002201 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002202 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002203 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002204 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302205 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002206 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2207
mpagenkodff5dda2020-08-28 11:52:01 +00002208 }
2209 } else {
2210 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2211 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002212 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2213 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2214 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2215 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002216 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002217 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002218 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002219 sliceEvtocdRule := make([]uint8, 16)
2220 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2221 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2222 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2223 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2224 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2225
2226 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002227 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2228 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002229 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2230 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2231
2232 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002233 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002234 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2235 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2236 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2237
2238 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002239 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2240 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002241 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002242 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002243
2244 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002245 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002246 Attributes: me.AttributeValueMap{
2247 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2248 },
2249 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002250 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002251 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2252 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002253 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002254 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002255 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002256 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2257 log.Fields{"device-id": oFsm.deviceID})
2258 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2259 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2260 }
mpagenkodff5dda2020-08-28 11:52:01 +00002261 //accept also nil as (error) return value for writing to LastTx
2262 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002263 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002264 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002265
2266 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002267 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002268 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002269 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002270 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302271 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002272 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002273 }
2274 } else {
2275 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2276 { // just for local var's
2277 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002278 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002279 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002280 sliceEvtocdRule := make([]uint8, 16)
2281 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2282 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2283 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2284 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2285 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2286
2287 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2288 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2289 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2290 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2291 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2292
2293 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2294 0<<cTreatTTROffset| // Do not pop any tags
2295 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2296 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2297 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2298
2299 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2300 0<<cTreatPrioOffset| // vlan prio set to 0
2301 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002302 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002303 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2304
mpagenko551a4d42020-12-08 18:09:20 +00002305 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002306 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002307 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002308 Attributes: me.AttributeValueMap{
2309 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2310 },
2311 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002312 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002313 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2314 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002315 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002316 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002317 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002318 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2319 log.Fields{"device-id": oFsm.deviceID})
2320 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2321 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2322 }
mpagenkodff5dda2020-08-28 11:52:01 +00002323 //accept also nil as (error) return value for writing to LastTx
2324 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002325 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002326 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002327
2328 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002329 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002330 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002331 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002332 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302333 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002334 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2335
mpagenkodff5dda2020-08-28 11:52:01 +00002336 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002337 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002338 { // just for local var's
2339 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002340 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002341 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002342 sliceEvtocdRule := make([]uint8, 16)
2343 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2344 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2345 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2346 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2347 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2348
2349 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2350 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2351 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2352 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2353 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2354
2355 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2356 1<<cTreatTTROffset| // pop the prio-tag
2357 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2358 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2359 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2360
mpagenko551a4d42020-12-08 18:09:20 +00002361 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002362 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2363 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2364 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002365 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002366 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002367 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002368
2369 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002370 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002371 Attributes: me.AttributeValueMap{
2372 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2373 },
2374 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002375 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002376 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2377 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002378 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002379 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002380 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002381 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2382 log.Fields{"device-id": oFsm.deviceID})
2383 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2384 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2385 }
mpagenkodff5dda2020-08-28 11:52:01 +00002386 //accept also nil as (error) return value for writing to LastTx
2387 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002388 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002389 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002390
2391 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002392 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002393 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002394 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002395 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302396 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002397 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2398
mpagenkodff5dda2020-08-28 11:52:01 +00002399 }
2400 } //just for local var's
2401 }
2402 }
2403
mpagenkofc4f56e2020-11-04 17:17:49 +00002404 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002405 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002406 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002407 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002408 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002409 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002410}
2411
dbainbri4d3a0dc2020-12-02 00:33:42 +00002412func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002413 oFsm.mutexFlowParams.RLock()
2414 evtocdID := oFsm.evtocdID
2415 oFsm.mutexFlowParams.RUnlock()
2416
mpagenko01e726e2020-10-23 09:45:29 +00002417 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2418 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2419 //transparent transmission was set
2420 //perhaps the config is not needed for removal,
2421 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002422 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002423 "device-id": oFsm.deviceID})
2424 sliceEvtocdRule := make([]uint8, 16)
2425 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2426 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2427 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2428 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2429 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2430
2431 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2432 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2433 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2434 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2435 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2436
2437 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2438 0<<cTreatTTROffset| // Do not pop any tags
2439 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2440 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2441 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2442
2443 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2444 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2445 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2446 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2447
2448 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002449 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002450 Attributes: me.AttributeValueMap{
2451 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2452 },
2453 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002454 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002455 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2456 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002457 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002458 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002459 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002460 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2461 log.Fields{"device-id": oFsm.deviceID})
2462 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2463 return
2464 }
mpagenko01e726e2020-10-23 09:45:29 +00002465 //accept also nil as (error) return value for writing to LastTx
2466 // - this avoids misinterpretation of new received OMCI messages
2467 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002468 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002469
2470 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002471 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002472 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002473 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002474 log.Fields{"device-id": oFsm.deviceID})
2475 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2476 return
2477 }
2478 } else {
2479 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002480 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002481 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002482 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002483 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002484 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002485 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2486 sliceEvtocdRule := make([]uint8, 16)
2487 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2488 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2489 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2490 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2491 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2492
2493 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2494 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2495 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2496 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2497 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2498
2499 // delete indication for the indicated Filter
2500 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2501 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2502
2503 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002504 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002505 Attributes: me.AttributeValueMap{
2506 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2507 },
2508 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002509 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002510 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2511 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002512 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002513 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002514 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002515 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2516 log.Fields{"device-id": oFsm.deviceID})
2517 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2518 return
2519 }
mpagenko01e726e2020-10-23 09:45:29 +00002520 //accept also nil as (error) return value for writing to LastTx
2521 // - this avoids misinterpretation of new received OMCI messages
2522 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002523 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002524
2525 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002526 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002527 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002528 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002529 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2530 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2531 return
2532 }
2533 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002534 // VOL-3685
2535 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2536 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2537 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2538 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2539 // later when the flow is being re-installed.
2540 // Of course this is applicable to case only where single service (or single tcont) is in use and
2541 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2542 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2543 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002544 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2545 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002546 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002547 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2548 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002549 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002550 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002551 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002552 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002553 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2554 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002555 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002556 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002557 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002558 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2559 log.Fields{"device-id": oFsm.deviceID})
2560 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2561 return
2562 }
mpagenko01e726e2020-10-23 09:45:29 +00002563 //accept also nil as (error) return value for writing to LastTx
2564 // - this avoids misinterpretation of new received OMCI messages
2565 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002566 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002567
2568 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002569 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002570 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002571 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002572 log.Fields{"device-id": oFsm.deviceID})
2573 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2574 return
2575 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002576 } else {
2577 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2578 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002579 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002580 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002581 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002582 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2583 { // just for local var's
2584 // this defines stacking scenario: untagged->singletagged
2585 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2586 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2587 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2588 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002589 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002590 "device-id": oFsm.deviceID})
2591 sliceEvtocdRule := make([]uint8, 16)
2592 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2593 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2594 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2595 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2596 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002597
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002598 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2599 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2600 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2601 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2602 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002603
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002604 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2605 0<<cTreatTTROffset| // Do not pop any tags
2606 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2607 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2608 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002609
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002610 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2611 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2612 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2613 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002614
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002615 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002616 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617 Attributes: me.AttributeValueMap{
2618 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2619 },
2620 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002621 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002622 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2623 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002624 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002625 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002626 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002627 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2628 log.Fields{"device-id": oFsm.deviceID})
2629 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2630 return
2631 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002632 //accept also nil as (error) return value for writing to LastTx
2633 // - this avoids misinterpretation of new received OMCI messages
2634 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002635 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002636
2637 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002638 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002639 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002640 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002641 log.Fields{"device-id": oFsm.deviceID})
2642 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2643 return
2644 }
2645 } // just for local var's
2646 { // just for local var's
2647 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002648 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002649 "device-id": oFsm.deviceID})
2650 sliceEvtocdRule := make([]uint8, 16)
2651 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2652 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2653 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2654 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2655 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2656
2657 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2658 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2659 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2660 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2661 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2662
2663 // delete indication for the indicated Filter
2664 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2665 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2666
2667 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002668 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002669 Attributes: me.AttributeValueMap{
2670 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2671 },
2672 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002673 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002674 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2675 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002676 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002677 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002678 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002679 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2680 log.Fields{"device-id": oFsm.deviceID})
2681 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2682 return
2683 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002684 //accept also nil as (error) return value for writing to LastTx
2685 // - this avoids misinterpretation of new received OMCI messages
2686 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002687 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002688
2689 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002690 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002691 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002692 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002693 log.Fields{"device-id": oFsm.deviceID})
2694 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2695 return
2696 }
mpagenko01e726e2020-10-23 09:45:29 +00002697 }
2698 } //just for local var's
2699 }
2700 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002701 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002702 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002703 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002704}
2705
dbainbri4d3a0dc2020-12-02 00:33:42 +00002706func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002707 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002708 if oFsm.isCanceled {
2709 // FSM already canceled before entering wait
2710 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2711 oFsm.mutexIsAwaitingResponse.Unlock()
2712 return fmt.Errorf(cErrWaitAborted)
2713 }
mpagenko7d6bb022021-03-11 15:07:55 +00002714 oFsm.isAwaitingResponse = true
2715 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002716 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302717 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002718 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002719 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002720 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002721 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002722 oFsm.mutexIsAwaitingResponse.Lock()
2723 oFsm.isAwaitingResponse = false
2724 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002725 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002726 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302727 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002728 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002729 oFsm.mutexIsAwaitingResponse.Lock()
2730 oFsm.isAwaitingResponse = false
2731 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002732 return nil
2733 }
mpagenko7d6bb022021-03-11 15:07:55 +00002734 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002735 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002736 oFsm.mutexIsAwaitingResponse.Lock()
2737 oFsm.isAwaitingResponse = false
2738 oFsm.mutexIsAwaitingResponse.Unlock()
2739 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002740 }
2741}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002742
mpagenko551a4d42020-12-08 18:09:20 +00002743func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002745 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002746 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002747 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002748 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002749 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002750 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002751 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2752 }
2753
dbainbri4d3a0dc2020-12-02 00:33:42 +00002754 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002755 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002756 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002757 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002758 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002759 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2760 }
2761
dbainbri4d3a0dc2020-12-02 00:33:42 +00002762 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002763 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002764 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002765 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002766 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002767 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2768 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002769 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2770 if errMacBpCdEID != nil {
2771 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2772 log.Fields{"device-id": oFsm.deviceID})
2773 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2774 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002775
Mahir Gunyel6781f962021-05-16 23:30:08 -07002776 }
2777 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2778 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2779 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002780 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002781 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002782 Attributes: me.AttributeValueMap{
2783 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2784 "PortNum": 0xf0, //fixed unique ANI side indication
2785 "TpType": 6, //MCGemIWTP
2786 "TpPointer": multicastGemPortID,
2787 },
2788 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002789 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002790 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2791 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2792 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002793 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002794 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2795 log.Fields{"device-id": oFsm.deviceID})
2796 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2797 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2798 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002799 //accept also nil as (error) return value for writing to LastTx
2800 // - this avoids misinterpretation of new received OMCI messages
2801 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002802 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002803 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002804 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002805 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002806 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002807 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002808 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2809 }
2810
2811 // ==> Start creating VTFD for mcast vlan
2812
2813 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2814 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002815 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002816
dbainbri4d3a0dc2020-12-02 00:33:42 +00002817 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002818 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2819 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2820 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2821
2822 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2823 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2824 // new vlan associated with a different TP.
2825 vtfdFilterList[0] = uint16(vlanID)
2826
2827 meParams = me.ParamData{
2828 EntityID: mcastVtfdID,
2829 Attributes: me.AttributeValueMap{
2830 "VlanFilterList": vtfdFilterList,
2831 "ForwardOperation": uint8(0x10), //VID investigation
2832 "NumberOfEntries": oFsm.numVlanFilterEntries,
2833 },
2834 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002835 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002836 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2837 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2838 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002839 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002840 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2841 log.Fields{"device-id": oFsm.deviceID})
2842 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2843 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2844 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002845 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002846 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002847 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002849 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002850 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002851 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002852 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2853 }
2854
2855 return nil
2856}
2857
dbainbri4d3a0dc2020-12-02 00:33:42 +00002858func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002859 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002861 logger.Errorw(ctx, "error generrating me instance id",
2862 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002863 return err
2864 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002865 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2866 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002867 meParams := me.ParamData{
2868 EntityID: instID,
2869 Attributes: me.AttributeValueMap{
2870 "MeType": 0,
2871 //Direct reference to the Operation profile
2872 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002873 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002874 },
2875 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002876 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002877 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2878 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002879 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002880 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002881 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002882 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2883 log.Fields{"device-id": oFsm.deviceID})
2884 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2885 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2886 oFsm.deviceID, err)
2887 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002888 //accept also nil as (error) return value for writing to LastTx
2889 // - this avoids misinterpretation of new received OMCI messages
2890 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002891 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002892 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002893 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002894 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002895 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002896 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2897 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2898 }
2899 return nil
2900}
2901
dbainbri4d3a0dc2020-12-02 00:33:42 +00002902func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002903 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002904 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002905 logger.Errorw(ctx, "error generating me instance id",
2906 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002907 return err
2908 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002909 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2910 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002911 meParams := me.ParamData{
2912 EntityID: instID,
2913 Attributes: me.AttributeValueMap{
2914 "IgmpVersion": 2,
2915 "IgmpFunction": 0,
2916 //0 means false
2917 "ImmediateLeave": 0,
2918 "Robustness": 2,
2919 "QuerierIp": 0,
2920 "QueryInterval": 125,
2921 "QuerierMaxResponseTime": 100,
2922 "LastMemberResponseTime": 10,
2923 //0 means false
2924 "UnauthorizedJoinBehaviour": 0,
2925 },
2926 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002927 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002928 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2929 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002930 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002931 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002932 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002933 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2934 log.Fields{"device-id": oFsm.deviceID})
2935 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2936 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2937 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002938 //accept also nil as (error) return value for writing to LastTx
2939 // - this avoids misinterpretation of new received OMCI messages
2940 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002941 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002942 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002943 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002944 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002945 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002946 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002947 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002948 }
2949 return nil
2950}
2951
dbainbri4d3a0dc2020-12-02 00:33:42 +00002952func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002953 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002954 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002955 logger.Errorw(ctx, "error generating me instance id",
2956 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002957 return err
2958 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002959 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2960 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002961 //TODO check that this is correct
2962 // Table control
2963 //setCtrl = 1
2964 //rowPartId = 0
2965 //test = 0
2966 //rowKey = 0
2967 tableCtrlStr := "0100000000000000"
2968 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002969 dynamicAccessCL := make([]uint8, 24)
2970 copy(dynamicAccessCL, tableCtrl)
2971 //Multicast GemPortId
2972 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2973 // python version waits for installation of flows, see line 723 onward of
2974 // brcm_openomci_onu_handler.py
2975 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2976 //Source IP all to 0
2977 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2978 //TODO start and end are hardcoded, get from TP
2979 // Destination IP address start of range
2980 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2981 // Destination IP address end of range
2982 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2983 //imputed group bandwidth
2984 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2985
2986 meParams := me.ParamData{
2987 EntityID: instID,
2988 Attributes: me.AttributeValueMap{
2989 "DynamicAccessControlListTable": dynamicAccessCL,
2990 },
2991 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002992 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002993 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2994 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002995 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002996 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002997 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002998 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2999 log.Fields{"device-id": oFsm.deviceID})
3000 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
3001 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3002 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003003 //accept also nil as (error) return value for writing to LastTx
3004 // - this avoids misinterpretation of new received OMCI messages
3005 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003006 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003007 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003008 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003009 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003010 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003011 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003012 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003013 }
3014 return nil
3015}
Girish Gowdra26a40922021-01-29 17:14:34 -08003016
ozgecanetsia82b91a62021-05-21 18:54:49 +03003017func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3018 tpID uint8, uniID uint8, gemPortID uint16) error {
3019 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3020 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3021 // I created unique TD ID by flow direction.
3022 // TODO! Traffic descriptor ME ID will check
3023 trafficDescriptorID := gemPortID
3024 if aMeter == nil {
3025 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3026 }
3027 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3028 if err != nil {
3029 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3030 return err
3031 }
3032 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3033 cbs := trafficShapingInfo.Cbs
3034 pir := trafficShapingInfo.Pir
3035 pbs := trafficShapingInfo.Pbs
3036
3037 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3038 meParams := me.ParamData{
3039 EntityID: trafficDescriptorID,
3040 Attributes: me.AttributeValueMap{
3041 "Cir": cir,
3042 "Pir": pir,
3043 "Cbs": cbs,
3044 "Pbs": pbs,
3045 "ColourMode": 1,
3046 "IngressColourMarking": 3,
3047 "EgressColourMarking": 3,
3048 "MeterType": 1,
3049 },
3050 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003051 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003052 meInstance, errCreateTD := oFsm.pOmciCC.sendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
3053 true, oFsm.pAdaptFsm.commChan, meParams)
3054 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003055 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003056 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3057 return err
3058 }
3059 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003060 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003061 err = oFsm.waitforOmciResponse(ctx)
3062 if err != nil {
3063 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3064 return err
3065 }
3066
3067 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID)
3068 if err != nil {
3069 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3070 return err
3071 }
3072 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3073
3074 return nil
3075}
3076
3077func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortID uint16) error {
3078 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID})
3079 meParams := me.ParamData{
3080 EntityID: gemPortID,
3081 Attributes: me.AttributeValueMap{
3082 "TrafficManagementPointerForUpstream": gemPortID,
3083 },
3084 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003085 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003086 meInstance, err := oFsm.pOmciCC.sendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3087 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
3088 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003089 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003090 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3091 return err
3092 }
3093 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003094 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003095 err = oFsm.waitforOmciResponse(ctx)
3096 if err != nil {
3097 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3098 return err
3099 }
3100 return nil
3101}
3102
Girish Gowdra26a40922021-01-29 17:14:34 -08003103// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00003104func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
3105 oFsm.mutexFlowParams.Lock()
3106 defer oFsm.mutexFlowParams.Unlock()
3107 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3108 //flow removal is still ongoing/pending
3109 oFsm.signalOnFlowDelete = true
3110 oFsm.flowDeleteChannel = aFlowDeleteChannel
3111 return true
3112 }
3113 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003114}
Holger Hildebrandt968eb8f2021-09-17 07:41:12 +00003115
3116func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3117 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3118 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3119 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3120 log.Fields{"device-id": oFsm.deviceID})
3121 } else {
3122 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3123 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3124 "index": oFsm.numVlanFilterEntries,
3125 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3126 "device-id": oFsm.deviceID})
3127 oFsm.numVlanFilterEntries++
3128 }
3129}