blob: c7e80131dd944eae92fc01158f09367ebea24045 [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/binary"
mpagenkof582d6a2021-06-18 15:58:10 +000023 "errors"
Andrea Campanella6515c582020-10-05 11:25:00 +020024 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030025 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000026 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000027 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000028 "time"
29
ozgecanetsia82b91a62021-05-21 18:54:49 +030030 meters "github.com/opencord/voltha-lib-go/v5/pkg/meters"
31 "github.com/opencord/voltha-protos/v4/go/voltha"
32
mpagenko01e726e2020-10-23 09:45:29 +000033 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000034 "github.com/looplab/fsm"
35 "github.com/opencord/omci-lib-go"
36 me "github.com/opencord/omci-lib-go/generated"
Girish Gowdra50e56422021-06-01 16:46:04 -070037 "github.com/opencord/voltha-lib-go/v5/pkg/log"
dbainbri4d3a0dc2020-12-02 00:33:42 +000038 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000039)
40
41const (
42 // internal predefined values
43 cDefaultDownstreamMode = 0
44 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000045 cVtfdTableSize = 12 //as per G.988
46 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000047)
48
49const (
mpagenkof1fc3862021-02-16 10:09:52 +000050 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
51 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
52 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
53 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
54 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
55)
56
57const (
mpagenkodff5dda2020-08-28 11:52:01 +000058 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
59 cFilterPrioOffset = 28
60 cFilterVidOffset = 15
61 cFilterTpidOffset = 12
62 cFilterEtherTypeOffset = 0
63 cTreatTTROffset = 30
64 cTreatPrioOffset = 16
65 cTreatVidOffset = 3
66 cTreatTpidOffset = 0
67)
68const (
69 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
70 cFilterOuterOffset = 0
71 cFilterInnerOffset = 4
72 cTreatOuterOffset = 8
73 cTreatInnerOffset = 12
74)
75const (
76 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
77 cPrioIgnoreTag uint32 = 15
78 cPrioDefaultFilter uint32 = 14
79 cPrioDoNotFilter uint32 = 8
80 cDoNotFilterVid uint32 = 4096
81 cDoNotFilterTPID uint32 = 0
82 cDoNotFilterEtherType uint32 = 0
83 cDoNotAddPrio uint32 = 15
84 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053085 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000086 cDontCareVid uint32 = 0
87 cDontCareTpid uint32 = 0
88 cSetOutputTpidCopyDei uint32 = 4
89)
90
91const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000092 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000093 vlanEvStart = "vlanEvStart"
mpagenkof1d21d12021-06-11 13:14:45 +000094 vlanEvPrepareDone = "vlanEvPrepareDone"
mpagenko535d6ef2021-02-26 13:15:34 +000095 vlanEvWaitTechProf = "vlanEvWaitTechProf"
96 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
97 vlanEvContinueConfig = "vlanEvContinueConfig"
98 vlanEvStartConfig = "vlanEvStartConfig"
99 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
100 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
101 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
102 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
103 vlanEvRenew = "vlanEvRenew"
104 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
105 vlanEvRemFlowDone = "vlanEvRemFlowDone"
106 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000107 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
108 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000109 vlanEvReset = "vlanEvReset"
110 vlanEvRestart = "vlanEvRestart"
111 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
112 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000113)
mpagenko01e726e2020-10-23 09:45:29 +0000114
mpagenkodff5dda2020-08-28 11:52:01 +0000115const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000116 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000117 vlanStDisabled = "vlanStDisabled"
mpagenkof1d21d12021-06-11 13:14:45 +0000118 vlanStPreparing = "vlanStPreparing"
mpagenkodff5dda2020-08-28 11:52:01 +0000119 vlanStStarting = "vlanStStarting"
120 vlanStWaitingTechProf = "vlanStWaitingTechProf"
121 vlanStConfigVtfd = "vlanStConfigVtfd"
122 vlanStConfigEvtocd = "vlanStConfigEvtocd"
123 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000124 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000125 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000126 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000127 vlanStCleanupDone = "vlanStCleanupDone"
128 vlanStResetting = "vlanStResetting"
129)
mpagenkof1fc3862021-02-16 10:09:52 +0000130const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
131const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000132
mpagenko01e726e2020-10-23 09:45:29 +0000133type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000134 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000135 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
136 MatchPcp uint32 `json:"match_pcp"`
137 TagsToRemove uint32 `json:"tags_to_remove"`
138 SetVid uint32 `json:"set_vid"`
139 SetPcp uint32 `json:"set_pcp"`
140}
141
142type uniVlanFlowParams struct {
ozgecanetsia82b91a62021-05-21 18:54:49 +0300143 CookieSlice []uint64 `json:"cookie_slice"`
144 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
145 Meter *voltha.OfpMeterConfig `json:"flow_meter"`
mpagenko01e726e2020-10-23 09:45:29 +0000146}
147
148type uniRemoveVlanFlowParams struct {
mpagenkof1d21d12021-06-11 13:14:45 +0000149 isSuspendedOnAdd bool
150 removeChannel chan bool
151 cookie uint64 //just the last cookie valid for removal
152 vlanRuleParams uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000153}
154
mpagenkobb47bc22021-04-20 13:29:09 +0000155//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
156// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000157type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530158 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000159 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530160 pOmciCC *omciCC
161 pOnuUniPort *onuUniPort
162 pUniTechProf *onuUniTechProf
163 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000164 requestEvent OnuDeviceEvent
165 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
166 pAdaptFsm *AdapterFsm
167 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000168 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000169 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000170 isAwaitingResponse bool
171 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000172 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000173 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000174 actualUniVlanConfigRule uniVlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300175 actualUniVlanConfigMeter *voltha.OfpMeterConfig
mpagenko01e726e2020-10-23 09:45:29 +0000176 uniVlanFlowParamsSlice []uniVlanFlowParams
177 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000178 numUniFlows uint8 // expected number of flows should be less than 12
179 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000180 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000181 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000182 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000183 evtocdID uint16
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +0000184 mutexPLastTxMeInstance sync.RWMutex
mpagenko01e726e2020-10-23 09:45:29 +0000185 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000186 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000187 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000188 signalOnFlowDelete bool
189 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000190 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
191 delayNewRuleCookie uint64
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200192 // Used to indicate if the FSM is for a reconciling flow and if it's the last flow to be reconciled
193 // thus notification needs to be sent on chan.
194 lastFlowToReconcile bool
mpagenkodff5dda2020-08-28 11:52:01 +0000195}
196
mpagenko01e726e2020-10-23 09:45:29 +0000197//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
198// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000199func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000200 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000201 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300202 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToRec bool, aMeter *voltha.OfpMeterConfig) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000203 instFsm := &UniVlanConfigFsm{
204 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000205 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000206 pOmciCC: apDevOmciCC,
207 pOnuUniPort: apUniPort,
208 pUniTechProf: apUniTechProf,
209 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000210 requestEvent: aRequestEvent,
211 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000212 numUniFlows: 0,
213 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000214 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000215 clearPersistency: true,
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200216 lastFlowToReconcile: lastFlowToRec,
mpagenkodff5dda2020-08-28 11:52:01 +0000217 }
218
mpagenko01e726e2020-10-23 09:45:29 +0000219 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000220 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000221 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000222 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000223 return nil
224 }
mpagenkodff5dda2020-08-28 11:52:01 +0000225 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
226 vlanStDisabled,
227 fsm.Events{
mpagenkof1d21d12021-06-11 13:14:45 +0000228 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStPreparing},
229 {Name: vlanEvPrepareDone, Src: []string{vlanStPreparing}, Dst: vlanStStarting},
mpagenkodff5dda2020-08-28 11:52:01 +0000230 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000231 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000232 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
233 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
234 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000235 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
236 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000237 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
238 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
239 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
240 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000241 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
242 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
243 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000244 /*
245 {Name: vlanEvTimeoutSimple, Src: []string{
246 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
247 {Name: vlanEvTimeoutMids, Src: []string{
248 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
249 */
250 // exceptional treatment for all states except vlanStResetting
251 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000252 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000253 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000254 Dst: vlanStResetting},
255 // the only way to get to resource-cleared disabled state again is via "resseting"
256 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000257 // transitions for reconcile handling according to VOL-3834
mpagenkof1d21d12021-06-11 13:14:45 +0000258 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStPreparing}, Dst: vlanStConfigDone},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000259 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
260 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000261 },
mpagenkodff5dda2020-08-28 11:52:01 +0000262 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000263 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
mpagenkof1d21d12021-06-11 13:14:45 +0000264 "enter_" + vlanStPreparing: func(e *fsm.Event) { instFsm.enterPreparing(ctx, e) },
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
266 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
267 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
268 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
269 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
270 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
271 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
272 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
273 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000274 },
275 )
276 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000277 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000278 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000279 return nil
280 }
281
ozgecanetsia82b91a62021-05-21 18:54:49 +0300282 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp, aMeter)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000283
dbainbri4d3a0dc2020-12-02 00:33:42 +0000284 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000285 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000286 return instFsm
287}
288
mpagenko01e726e2020-10-23 09:45:29 +0000289//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000290func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300291 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000292 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000293 TpID: aTpID,
294 MatchVid: uint32(aMatchVlan),
295 SetVid: uint32(aSetVlan),
296 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 }
298 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000299 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
300 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301
mpagenko01e726e2020-10-23 09:45:29 +0000302 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000303 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000304 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000305 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
306 } else {
307 if !oFsm.acceptIncrementalEvtoOption {
308 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000309 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000310 }
311 }
312
mpagenko01e726e2020-10-23 09:45:29 +0000313 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000314 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000315 loRuleParams.TagsToRemove = 0 //no tag pop action
316 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
317 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000318 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
319 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
320 // might collide with NoMatchVid/CopyPrio(/setVid) setting
321 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000322 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000323 }
324 }
mpagenko01e726e2020-10-23 09:45:29 +0000325
326 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
327 loFlowParams.CookieSlice = make([]uint64, 0)
328 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300329 if aMeter != nil {
330 loFlowParams.Meter = aMeter
331 }
mpagenko01e726e2020-10-23 09:45:29 +0000332
333 //no mutex protection is required for initial access and adding the first flow is always possible
334 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
335 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000336 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000337 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
338 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
339 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
340 "SetPcp": loRuleParams.SetPcp,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300341 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
Holger Hildebrandtd3a251d2021-09-20 12:12:53 +0000342
343 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
344 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
345 }
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000346 //cmp also usage in EVTOCDE create in omci_cc
347 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko01e726e2020-10-23 09:45:29 +0000348 oFsm.numUniFlows = 1
349 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
350
351 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000352 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000353 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000354 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000355 return err
356 }
357
358 return nil
359}
360
mpagenko7d6bb022021-03-11 15:07:55 +0000361//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000362func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000363 if oFsm == nil {
364 logger.Error(ctx, "no valid UniVlanConfigFsm!")
365 return
366 }
mpagenko7d6bb022021-03-11 15:07:55 +0000367 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000368 oFsm.mutexIsAwaitingResponse.Lock()
369 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000370 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000371 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
372 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
373 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000374 //use channel to indicate that the response waiting shall be aborted
375 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000376 } else {
377 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000378 }
mpagenkocf48e452021-04-23 09:23:00 +0000379
mpagenko7d6bb022021-03-11 15:07:55 +0000380 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
381 pAdaptFsm := oFsm.pAdaptFsm
382 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000383 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000384 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000385 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000386 }
mpagenko7d6bb022021-03-11 15:07:55 +0000387 }
388}
389
mpagenko551a4d42020-12-08 18:09:20 +0000390//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000391func (oFsm *UniVlanConfigFsm) GetWaitingTpID(ctx context.Context) uint8 {
392 if oFsm == nil {
393 logger.Error(ctx, "no valid UniVlanConfigFsm!")
394 return 0
395 }
mpagenko551a4d42020-12-08 18:09:20 +0000396 //mutex protection is required for possible concurrent access to FSM members
397 oFsm.mutexFlowParams.RLock()
398 defer oFsm.mutexFlowParams.RUnlock()
399 return oFsm.TpIDWaitingFor
400}
401
mpagenko2418ab02020-11-12 12:58:06 +0000402//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000403func (oFsm *UniVlanConfigFsm) RequestClearPersistency(ctx context.Context, aClear bool) {
404 if oFsm == nil {
405 logger.Error(ctx, "no valid UniVlanConfigFsm!")
406 return
407 }
mpagenko2418ab02020-11-12 12:58:06 +0000408 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000409 oFsm.mutexFlowParams.Lock()
410 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000411 oFsm.clearPersistency = aClear
412}
413
mpagenko01e726e2020-10-23 09:45:29 +0000414//SetUniFlowParams verifies on existence of flow parameters to be configured,
415// optionally udates the cookie list or appends a new flow if there is space
416// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000417// ignore complexity by now
418// nolint: gocyclo
419func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300420 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000421 if oFsm == nil {
422 logger.Error(ctx, "no valid UniVlanConfigFsm!")
423 return fmt.Errorf("no-valid-UniVlanConfigFsm")
424 }
mpagenko01e726e2020-10-23 09:45:29 +0000425 loRuleParams := uniVlanRuleParams{
426 TpID: aTpID,
427 MatchVid: uint32(aMatchVlan),
428 SetVid: uint32(aSetVlan),
429 SetPcp: uint32(aSetPcp),
430 }
431 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
432 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
433 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000434 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
435 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
436 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
437 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
438 } else {
439 if !oFsm.acceptIncrementalEvtoOption {
440 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
441 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
442 }
443 }
444
445 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
446 // no prio/vid filtering requested
447 loRuleParams.TagsToRemove = 0 //no tag pop action
448 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
449 if loRuleParams.SetPcp == cCopyPrioFromInner {
450 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
451 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
452 // might collide with NoMatchVid/CopyPrio(/setVid) setting
453 // this was some precondition setting taken over from py adapter ..
454 loRuleParams.SetPcp = 0
455 }
456 }
457
mpagenkof1d21d12021-06-11 13:14:45 +0000458 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
459 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
460 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
461 oFsm.mutexFlowParams.RLock()
462 if len(oFsm.uniRemoveFlowsSlice) > 0 {
463 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
464 if removeUniFlowParams.vlanRuleParams == loRuleParams {
465 // the flow to add is the same as the one already in progress of deleting
466 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000467 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
468 if flow >= len(oFsm.uniRemoveFlowsSlice) {
469 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
470 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
471 oFsm.mutexFlowParams.RUnlock()
472 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
473 }
mpagenkof1d21d12021-06-11 13:14:45 +0000474 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
475 oFsm.mutexFlowParams.RUnlock()
476 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
477 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
478 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
479 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
480 }
481 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000482 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000483 }
484 }
485 }
486 oFsm.mutexFlowParams.RUnlock()
487
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000488 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000489 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000490 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200491 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000492 //mutex protection is required for possible concurrent access to FSM members
493 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000494 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
495 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
496 // countable run time optimization (perhaps with including the hash in kvStore storage?)
497 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000498 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000499 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300500 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
501 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
502 "SetPcp": loRuleParams.SetPcp,
503 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000504 var cookieMatch bool
505 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
506 cookieMatch = false
507 for _, cookie := range storedUniFlowParams.CookieSlice {
508 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000509 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000510 "device-id": oFsm.deviceID, "cookie": cookie})
511 cookieMatch = true
512 break //found new cookie - no further search for this requested cookie
513 }
514 }
515 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000516 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
517 if delayedCookie != 0 {
518 //a delay for adding the cookie to this rule is requested
519 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
520 oFsm.mutexFlowParams.Unlock()
mpagenko2f487262021-08-23 15:59:06 +0000521 if deleteSuccess := oFsm.suspendNewRule(ctx); !deleteSuccess {
522 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-cookie-to-rule aborted", log.Fields{
523 "device-id": oFsm.deviceID, "cookie": delayedCookie})
524 return fmt.Errorf(" UniVlanConfigFsm suspended add-cookie-to-rule aborted %s", oFsm.deviceID)
525 }
mpagenkof1fc3862021-02-16 10:09:52 +0000526 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
527 oFsm.mutexFlowParams.Lock()
528 } else {
529 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
530 "device-id": oFsm.deviceID, "cookie": newCookie})
531 //as range works with copies of the slice we have to write to the original slice!!
532 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
533 newCookie)
534 flowCookieModify = true
535 }
mpagenko01e726e2020-10-23 09:45:29 +0000536 }
537 } //for all new cookies
538 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000539 }
540 }
mpagenkof1fc3862021-02-16 10:09:52 +0000541 oFsm.mutexFlowParams.Unlock()
542
543 if !flowEntryMatch { //it is (was) a new rule
mpagenko2f487262021-08-23 15:59:06 +0000544 delayedCookie, deleteSuccess := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
545 if !deleteSuccess {
546 logger.Errorw(ctx, "UniVlanConfigFsm suspended add-new-rule aborted", log.Fields{
547 "device-id": oFsm.deviceID, "cookie": delayedCookie})
548 return fmt.Errorf(" UniVlanConfigFsm suspended add-new-rule aborted %s", oFsm.deviceID)
549 }
mpagenkof1fc3862021-02-16 10:09:52 +0000550 requestAppendRule = true //default assumption here is that rule is to be appended
551 flowCookieModify = true //and that the the flow data base is to be updated
552 if delayedCookie != 0 { //it was suspended
553 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
554 }
555 }
556 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
557 if requestAppendRule {
558 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000559 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000560 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
561 loFlowParams.CookieSlice = make([]uint64, 0)
562 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300563 if aMeter != nil {
564 loFlowParams.Meter = aMeter
565 }
mpagenko01e726e2020-10-23 09:45:29 +0000566 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000567 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000568 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
569 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
570 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800571 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300572 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000573
Holger Hildebrandtd3a251d2021-09-20 12:12:53 +0000574 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
575 oFsm.reconcileVlanFilterList(ctx, uint16(loRuleParams.SetVid))
576 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000577 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000578 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
579
580 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
581 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
582 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000583 //attention: take care to release the mutexFlowParams when calling the FSM directly -
584 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000585 oFsm.mutexFlowParams.Unlock()
586 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000587 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
588 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
589 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
590 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000591 }
592 return nil
593 }
mpagenko01e726e2020-10-23 09:45:29 +0000594 // note: theoretical it would be possible to clear the same rule from the remove slice
595 // (for entries that have not yet been started with removal)
596 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
597 // 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 +0000598
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000599 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
600 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000601 if oFsm.configuredUniFlow == 0 {
602 // this is a restart with a complete new flow, we can re-use the initial flow config control
603 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000604 //attention: take care to release the mutexFlowParams when calling the FSM directly -
605 // synchronous FSM 'event/state' functions may rely on this mutex
606 oFsm.mutexFlowParams.Unlock()
607 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
608 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
609 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
610 }
mpagenko551a4d42020-12-08 18:09:20 +0000611 } else {
612 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000613 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000614 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
615 //check introduced after having observed some panic here
616 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
617 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
618 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
619 oFsm.mutexFlowParams.Unlock()
620 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
621 }
mpagenko9a304ea2020-12-16 15:54:01 +0000622 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300623 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +0000624 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000625 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000626 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +0000627 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000628 //attention: take care to release the mutexFlowParams when calling the FSM directly -
629 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko18eca9c2021-07-26 11:03:45 +0000630 // but it must be released already before calling getTechProfileDone() as it may already be locked
631 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000632 oFsm.mutexFlowParams.Unlock()
mpagenko18eca9c2021-07-26 11:03:45 +0000633 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
634 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
635 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
636 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
637
mpagenkobb47bc22021-04-20 13:29:09 +0000638 var fsmErr error
639 if loTechProfDone {
640 // let the vlan processing continue with next rule
641 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
642 } else {
643 // set to waiting for Techprofile
644 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
645 }
646 if fsmErr != nil {
647 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
648 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
649 }
mpagenko551a4d42020-12-08 18:09:20 +0000650 }
mpagenkobb47bc22021-04-20 13:29:09 +0000651 } else {
652 // if not in the appropriate state a new entry will be automatically considered later
653 // when the configDone state is reached
654 oFsm.mutexFlowParams.Unlock()
655 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000656 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000657 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000658 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000659 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000660 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
661 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000662 } else {
663 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000664 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000665 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000666 if oFsm.numUniFlows == oFsm.configuredUniFlow {
667 //all requested rules really have been configured
668 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000669 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000670 if oFsm.pDeviceHandler != nil {
671 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000672 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000673 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000674 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
675 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000676 }
677 } else {
678 // avoid device reason update as the rule config connected to this flow may still be in progress
679 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000680 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000681 log.Fields{"device-id": oFsm.deviceID,
682 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000683 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000684 }
685 }
mpagenko01e726e2020-10-23 09:45:29 +0000686
mpagenkof1fc3862021-02-16 10:09:52 +0000687 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000688 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000689 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000690 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
691 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000692 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000693 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000694 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000695 }
mpagenko15ff4a52021-03-02 10:09:20 +0000696 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000697 }
698 return nil
699}
700
mpagenkof1d21d12021-06-11 13:14:45 +0000701func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
702 oFsm.mutexFlowParams.Lock()
703 deleteChannel := apRemoveFlowParams.removeChannel
704 apRemoveFlowParams.isSuspendedOnAdd = true
705 oFsm.mutexFlowParams.Unlock()
706
707 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
708 select {
709 case success := <-deleteChannel:
710 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
711 if success {
712 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
713 "device-id": oFsm.deviceID})
714 return nil
715 }
716 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
717 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
718 oFsm.mutexFlowParams.Lock()
719 if apRemoveFlowParams != nil {
720 apRemoveFlowParams.isSuspendedOnAdd = false
721 }
722 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000723 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000724 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000725 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000726 }
mpagenkof1d21d12021-06-11 13:14:45 +0000727}
728
mpagenkof1fc3862021-02-16 10:09:52 +0000729// VOL-3828 flow config sequence workaround ########### start ##########
730func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
731 //assumes mutexFlowParams.Lock() protection from caller!
732 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
733 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000734 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000735 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
736 newCookie := aCookieSlice[0]
737 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
738 for _, cookie := range storedUniFlowParams.CookieSlice {
739 if cookie == newCookie {
740 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
741 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
742 oFsm.delayNewRuleCookie = newCookie
743 return newCookie //found new cookie in some existing rule
744 }
745 } // for all stored cookies of the actual inspected rule
746 } //for all rules
747 }
748 return 0 //no delay requested
749}
mpagenko2f487262021-08-23 15:59:06 +0000750func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) bool {
mpagenkof1fc3862021-02-16 10:09:52 +0000751 oFsm.mutexFlowParams.RLock()
752 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
753 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
754 oFsm.mutexFlowParams.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +0000755 cookieDeleted := true //default assumption also for timeout (just try to continue as if removed)
mpagenkof1fc3862021-02-16 10:09:52 +0000756 select {
mpagenko2f487262021-08-23 15:59:06 +0000757 case cookieDeleted = <-oFsm.chCookieDeleted:
758 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule or abort", log.Fields{
759 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie, "deleted": cookieDeleted})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000760 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000761 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
762 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
763 }
764 oFsm.mutexFlowParams.Lock()
765 oFsm.delayNewRuleCookie = 0
766 oFsm.mutexFlowParams.Unlock()
mpagenko2f487262021-08-23 15:59:06 +0000767 return cookieDeleted
mpagenkof1fc3862021-02-16 10:09:52 +0000768}
mpagenko2f487262021-08-23 15:59:06 +0000769func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) (uint64, bool) {
mpagenkof1fc3862021-02-16 10:09:52 +0000770 oFsm.mutexFlowParams.Lock()
771 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
772 oFsm.mutexFlowParams.Unlock()
773
mpagenko2f487262021-08-23 15:59:06 +0000774 deleteSuccess := true
mpagenkof1fc3862021-02-16 10:09:52 +0000775 if delayedCookie != 0 {
mpagenko2f487262021-08-23 15:59:06 +0000776 deleteSuccess = oFsm.suspendNewRule(ctx)
mpagenkof1fc3862021-02-16 10:09:52 +0000777 }
mpagenko2f487262021-08-23 15:59:06 +0000778 return delayedCookie, deleteSuccess
mpagenkof1fc3862021-02-16 10:09:52 +0000779}
780
781//returns flowModified, RuleAppendRequest
782func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
783 flowEntryMatch := false
784 oFsm.mutexFlowParams.Lock()
785 defer oFsm.mutexFlowParams.Unlock()
786 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
787 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
788 flowEntryMatch = true
789 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
790 "device-id": oFsm.deviceID})
791 cookieMatch := false
792 for _, cookie := range storedUniFlowParams.CookieSlice {
793 if cookie == aCookie {
794 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
795 "device-id": oFsm.deviceID, "cookie": cookie})
796 cookieMatch = true
797 break //found new cookie - no further search for this requested cookie
798 }
799 }
800 if !cookieMatch {
801 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
802 "device-id": oFsm.deviceID, "cookie": aCookie})
803 //as range works with copies of the slice we have to write to the original slice!!
804 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
805 aCookie)
806 return true, false //flowModified, NoRuleAppend
807 }
808 break // found rule - no further rule search
809 }
810 }
811 if !flowEntryMatch { //it is a new rule
812 return true, true //flowModified, RuleAppend
813 }
814 return false, false //flowNotModified, NoRuleAppend
815}
816
817// VOL-3828 flow config sequence workaround ########### end ##########
818
mpagenko01e726e2020-10-23 09:45:29 +0000819//RemoveUniFlowParams verifies on existence of flow cookie,
820// if found removes cookie from flow cookie list and if this is empty
821// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000822func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
Holger Hildebrandt72eaab72021-11-05 08:54:59 +0000823 if oFsm == nil {
824 logger.Error(ctx, "no valid UniVlanConfigFsm!")
825 return fmt.Errorf("no-valid-UniVlanConfigFsm")
826 }
mpagenkof1fc3862021-02-16 10:09:52 +0000827 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000828 flowCookieMatch := false
829 //mutex protection is required for possible concurrent access to FSM members
830 oFsm.mutexFlowParams.Lock()
831 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000832remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000833 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
834 for i, cookie := range storedUniFlowParams.CookieSlice {
835 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000836 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000837 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000838 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000839 //remove the cookie from the cookie slice and verify it is getting empty
840 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000841 // had to shift content to function due to sca complexity
842 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenko333846a2021-07-21 12:38:07 +0000843 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000844 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000845 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000846 //cut off the requested cookie by slicing out this element
847 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
848 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
849 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000850 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
851 // state transition notification is checked in deviceHandler
852 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000853 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
854 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000855 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000856 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000857 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000858 if deletedCookie == oFsm.delayNewRuleCookie {
859 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
860 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
861 //simply use the first one
862 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
863 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
864 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
865 }
mpagenko333846a2021-07-21 12:38:07 +0000866 //permanently store the modified flow config for reconcile case and immediately write to KvStore
867 if oFsm.pDeviceHandler != nil {
868 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
869 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
870 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
871 return err
872 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000873 }
mpagenko01e726e2020-10-23 09:45:29 +0000874 }
mpagenkof1fc3862021-02-16 10:09:52 +0000875 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000876 }
877 }
mpagenko01e726e2020-10-23 09:45:29 +0000878 } //search all flows
879 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000880 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000881 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
882 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000883 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
884 // state transition notification is checked in deviceHandler
885 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000886 // success indication without the need to write to kvStore (no change)
887 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000888 }
mpagenko01e726e2020-10-23 09:45:29 +0000889 return nil
890 } //unknown cookie
891
892 return nil
893}
894
mpagenkof582d6a2021-06-18 15:58:10 +0000895// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenko333846a2021-07-21 12:38:07 +0000896// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000897func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
898 aUniFlowParams uniVlanFlowParams, aCookie uint64) bool {
899 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
900 var cancelPendingConfig bool = false
901 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
902 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
903 "device-id": oFsm.deviceID})
904 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
905 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
906 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
907 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
908 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
909 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
910 log.Fields{"device-id": oFsm.deviceID})
911 cancelPendingConfig = true
912 } else {
913 //create a new element for the removeVlanFlow slice
914 loRemoveParams = uniRemoveVlanFlowParams{
915 vlanRuleParams: aUniFlowParams.VlanRuleParams,
916 cookie: aCookie,
917 }
918 loRemoveParams.removeChannel = make(chan bool)
919 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
920 }
921
922 usedTpID := aUniFlowParams.VlanRuleParams.TpID
923 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
924 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
925 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
926 if !cancelPendingConfig {
mpagenko7a592192021-07-28 13:32:00 +0000927 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
928 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000929 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
930 "device-id": oFsm.deviceID})
931 if oFsm.pUniTechProf != nil {
932 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
933 }
mpagenko7a592192021-07-28 13:32:00 +0000934 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000935 }
936 } else {
937 if !cancelPendingConfig {
938 oFsm.updateTechProfileToDelete(ctx, usedTpID)
939 }
940 }
941 //trigger the FSM to remove the relevant rule
942 if cancelPendingConfig {
943 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
944 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
945 //call from 'non-configured' state of the rules
946 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
947 //something quite inconsistent detected, perhaps just try to recover with FSM reset
948 oFsm.mutexFlowParams.Unlock()
949 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvReset); fsmErr != nil {
950 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
951 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
952 }
953 return false //data base update could not be done, return like cookie not found
954 }
955
956 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
957 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
958 // synchronous FSM 'event/state' functions may rely on this mutex
959 oFsm.mutexFlowParams.Unlock()
960 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
961 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
962 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
963 }
964 oFsm.mutexFlowParams.Lock()
965 return true
966 }
967 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
968 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
969 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
970 "tp-id": loRemoveParams.vlanRuleParams.TpID,
971 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
972 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
973 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
974 // synchronous FSM 'event/state' functions may rely on this mutex
975 oFsm.mutexFlowParams.Unlock()
976 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
977 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
978 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
979 }
980 oFsm.mutexFlowParams.Lock()
981 } // if not in the appropriate state a new entry will be automatically considered later
982 // when the configDone state is reached
983 return true
984}
985
mpagenkof1d21d12021-06-11 13:14:45 +0000986//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
987// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
988// from the start of the deletion request to avoid to much interference
989// so when called, there can only be one cookie active for this flow
990// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000991func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000992 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
993 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000994 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000995removeFromSlice_loop:
996 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000997 // if UniFlowParams exists, cookieSlice should always have at least one element
998 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
999 if cookieSliceLen == 1 {
1000 if storedUniFlowParams.CookieSlice[0] == aCookie {
1001 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +00001002 }
mpagenkof582d6a2021-06-18 15:58:10 +00001003 } else if cookieSliceLen == 0 {
1004 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
1005 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1006 return errors.New(errStr)
1007 } else {
1008 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
1009 logger.Errorw(ctx, errStr, log.Fields{
1010 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1011 for _, cookie := range storedUniFlowParams.CookieSlice {
1012 if cookie == aCookie {
1013 cookieFound = true
1014 break
1015 }
1016 }
1017 }
1018 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +00001019 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
1020 "device-id": oFsm.deviceID, "cookie": aCookie})
1021 //remove the actual element from the addVlanFlow slice
1022 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
1023 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
1024 oFsm.numUniFlows = 0 //no more flows
1025 oFsm.configuredUniFlow = 0 //no more flows configured
1026 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
1027 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
1028 //request that this profile gets deleted before a new flow add is allowed
1029 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
1030 "device-id": oFsm.deviceID})
1031 } else {
1032 oFsm.numUniFlows--
1033 if aWasConfigured && oFsm.configuredUniFlow > 0 {
1034 oFsm.configuredUniFlow--
1035 }
1036 //cut off the requested flow by slicing out this element
1037 oFsm.uniVlanFlowParamsSlice = append(
1038 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
1039 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
1040 "device-id": oFsm.deviceID})
1041 }
1042 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1043 }
1044 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001045 if !cookieFound {
1046 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1047 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1048 return errors.New(errStr)
1049 }
mpagenko333846a2021-07-21 12:38:07 +00001050 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1051 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
1052 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
1053 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1054 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1055 return err
1056 }
mpagenkof582d6a2021-06-18 15:58:10 +00001057 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001058}
1059
1060// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001061func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1062 //here we have to check, if there are still other flows referencing to the actual ProfileId
1063 // before we can request that this profile gets deleted before a new flow add is allowed
1064 tpIDInOtherFlows := false
1065 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1066 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1067 tpIDInOtherFlows = true
1068 break // search loop can be left
1069 }
1070 }
1071 if tpIDInOtherFlows {
1072 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1073 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1074 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001075 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 +00001076 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko7a592192021-07-28 13:32:00 +00001077 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1078 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001079 if oFsm.pUniTechProf != nil {
1080 //request that this profile gets deleted before a new flow add is allowed
1081 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
1082 }
mpagenko7a592192021-07-28 13:32:00 +00001083 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001084 }
1085}
1086
mpagenkof1d21d12021-06-11 13:14:45 +00001087func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1088 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001089
1090 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001091 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001092 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001093 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001094 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001095 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001096 //let the state machine run forward from here directly
1097 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1098 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001099 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1100 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
1101 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001102 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001103 go func(a_pAFsm *AdapterFsm) {
1104 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
1105 }(pConfigVlanStateAFsm)
1106 return
1107 }
mpagenkof1d21d12021-06-11 13:14:45 +00001108 // Can't call FSM Event directly, decoupling it
1109 go func(a_pAFsm *AdapterFsm) {
1110 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
1111 }(pConfigVlanStateAFsm)
1112 return
1113 }
1114 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1115 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1116 //should never happen, else: recovery would be needed from outside the FSM
1117}
1118
1119func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1120 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1121 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1122 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001123 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001124 //possibly the entry is not valid anymore based on intermediate delete requests
1125 //just a basic protection ...
1126 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1127 oFsm.mutexFlowParams.Unlock()
1128 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1129 "device-id": oFsm.deviceID})
1130 // Can't call FSM Event directly, decoupling it
1131 go func(a_pAFsm *AdapterFsm) {
1132 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1133 }(pConfigVlanStateAFsm)
1134 return
1135 }
mpagenko9a304ea2020-12-16 15:54:01 +00001136 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1137 //store the actual rule that shall be worked upon in the following transient states
1138 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001139 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
mpagenko9a304ea2020-12-16 15:54:01 +00001140 tpID := oFsm.actualUniVlanConfigRule.TpID
1141 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +00001142 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1143 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1144 // synchronous FSM 'event/state' functions may rely on this mutex
1145 // but it must be released already before calling getTechProfileDone() as it may already be locked
1146 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001147 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001148 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001149 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1150 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001151 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001152
mpagenko9a304ea2020-12-16 15:54:01 +00001153 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001154 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1155 if aPAFsm != nil && aPAFsm.pFsm != nil {
1156 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001157 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001158 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001159 } else {
1160 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001161 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001162 }
1163 }
mpagenko551a4d42020-12-08 18:09:20 +00001164 }(pConfigVlanStateAFsm, loTechProfDone)
1165 } else {
1166 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1167 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1168 //should never happen, else: recovery would be needed from outside the FSM
1169 return
mpagenkodff5dda2020-08-28 11:52:01 +00001170 }
1171}
1172
dbainbri4d3a0dc2020-12-02 00:33:42 +00001173func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001174 //mutex protection is required for possible concurrent access to FSM members
1175 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001176 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001177 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001178 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001179 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001180 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001181 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001182 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001183 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001184 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001185 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301186 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001187 }(pConfigVlanStateAFsm)
1188 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001189 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1190 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001191 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001192 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001193 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001194 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1195 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001196 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001197 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001198 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001199 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001200 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1201 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001202 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001203 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001204 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001205 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1206 "ForwardOperation": uint8(0x10), //VID investigation
1207 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001208 },
1209 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001210 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001211 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001212 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001213 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001214 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001215 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001216 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001217 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1218 log.Fields{"device-id": oFsm.deviceID})
1219 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1220 if pConfigVlanStateAFsm != nil {
1221 go func(a_pAFsm *AdapterFsm) {
1222 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1223 }(pConfigVlanStateAFsm)
1224 }
1225 return
1226 }
mpagenkodff5dda2020-08-28 11:52:01 +00001227 //accept also nil as (error) return value for writing to LastTx
1228 // - this avoids misinterpretation of new received OMCI messages
1229 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1230 // send shall return (dual format) error code that can be used here for immediate error treatment
1231 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001232 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001233 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001234 }
1235}
1236
dbainbri4d3a0dc2020-12-02 00:33:42 +00001237func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1238 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001239 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001240 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001241 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001242 //using the first element in the slice because it's the first flow per definition here
1243 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001244 //This is correct passing scenario
1245 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001246 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001247 tpID := oFsm.actualUniVlanConfigRule.TpID
1248 vlanID := oFsm.actualUniVlanConfigRule.SetVid
mpagenko7a592192021-07-28 13:32:00 +00001249 configuredUniFlows := oFsm.configuredUniFlow
1250 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1251 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001252 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1253 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
mpagenko7a592192021-07-28 13:32:00 +00001254 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001255 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001256 vlanID)
1257 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001258 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001259 log.Fields{"device-id": oFsm.deviceID})
1260 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1261 }
1262 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001263 //If this first flow contains a meter, then create TD for related gems.
1264 if oFsm.actualUniVlanConfigMeter != nil {
1265 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter})
1266 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1267 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1268 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1269 oFsm.pOnuUniPort.uniID, gemPort)
1270 if errCreateTrafficDescriptor != nil {
1271 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1272 log.Fields{"device-id": oFsm.deviceID})
1273 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1274 }
1275 }
1276 }
1277
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001278 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1279 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1280 }
1281 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001282}
1283
dbainbri4d3a0dc2020-12-02 00:33:42 +00001284func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001285
mpagenkof1d21d12021-06-11 13:14:45 +00001286 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001287
mpagenkof1fc3862021-02-16 10:09:52 +00001288 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001289 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001290 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001291
mpagenko551a4d42020-12-08 18:09:20 +00001292 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1293 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001294 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001295 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1296 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1297 //should never happen, else: recovery would be needed from outside the FSM
1298 return
1299 }
1300 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001301 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1302 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001303 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1304 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1305 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1306 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001307 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001308 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001309 go func(a_pBaseFsm *fsm.FSM) {
1310 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1311 }(pConfigVlanStateBaseFsm)
1312 return
1313 }
Holger Hildebrandt779e8d62022-02-08 15:35:01 +00001314 if oFsm.lastFlowToReconcile {
1315 //note: lastFlowToReconcile does not mean that this block may run only once within reconcilement here,
1316 // due to asynchronous event processing from SetUniFlowParams() it may be executed multiple times
1317 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{
1318 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
1319 oFsm.pDeviceHandler.SendChUniVlanConfigFinished(ctx, uint16(oFsm.pOnuUniPort.uniID))
1320 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001321 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1322 oFsm.configuredUniFlow = oFsm.numUniFlows
1323 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1324 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001325 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001326 return
1327 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001328 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001329 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001330 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001331 // this is a restart with a complete new flow, we can re-use the initial flow config control
1332 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001333 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001334 go func(a_pBaseFsm *fsm.FSM) {
1335 _ = a_pBaseFsm.Event(vlanEvRenew)
1336 }(pConfigVlanStateBaseFsm)
1337 return
1338 }
1339
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001340 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001341 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001342 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1343 //check introduced after having observed some panic in this processing
1344 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1345 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1346 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1347 oFsm.mutexFlowParams.Unlock()
1348 go func(a_pAFsm *AdapterFsm) {
1349 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1350 }(pConfigVlanStateAFsm)
1351 return
1352 }
mpagenko9a304ea2020-12-16 15:54:01 +00001353 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001354 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +00001355 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001356 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001357 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +00001358 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1359 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1360 // synchronous FSM 'event/state' functions may rely on this mutex
1361 // but it must be released already before calling getTechProfileDone() as it may already be locked
1362 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1363 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001364 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001365 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1366 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001367 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1368
mpagenko9a304ea2020-12-16 15:54:01 +00001369 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001370 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1371 if aTechProfDone {
1372 // let the vlan processing continue with next rule
1373 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1374 } else {
1375 // set to waiting for Techprofile
1376 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1377 }
1378 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001379 return
1380 }
mpagenkof1d21d12021-06-11 13:14:45 +00001381 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001382 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001383 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001384 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1385 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001386 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001387 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001388 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001389 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001390 }
1391}
1392
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001394
1395 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1396 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1397 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1398 go func(a_pBaseFsm *fsm.FSM) {
1399 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1400 }(oFsm.pAdaptFsm.pFsm)
1401 return
1402 }
mpagenko15ff4a52021-03-02 10:09:20 +00001403 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001404 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001405 "recent flow-number": oFsm.configuredUniFlow,
1406 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001407 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001408
mpagenko9a304ea2020-12-16 15:54:01 +00001409 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001410 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001411 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001412 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001413 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001414 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1415 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1416 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1417 // 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 +00001418 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001419 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1420 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001421 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001422 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001423 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001424 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001425 "device-id": oFsm.deviceID,
1426 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001427 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001428 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001429
mpagenko01e726e2020-10-23 09:45:29 +00001430 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001431 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1432 oFsm.numVlanFilterEntries = 1
1433 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001434 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001435 Attributes: me.AttributeValueMap{
1436 "VlanFilterList": vtfdFilterList,
1437 "ForwardOperation": uint8(0x10), //VID investigation
1438 "NumberOfEntries": oFsm.numVlanFilterEntries,
1439 },
1440 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001441 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001442 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001443 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001444 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001445 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001446 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001447 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1448 log.Fields{"device-id": oFsm.deviceID})
1449 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1450 if pConfigVlanStateAFsm != nil {
1451 go func(a_pAFsm *AdapterFsm) {
1452 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1453 }(pConfigVlanStateAFsm)
1454 }
1455 return
1456 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001457 //accept also nil as (error) return value for writing to LastTx
1458 // - this avoids misinterpretation of new received OMCI messages
1459 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1460 // send shall return (dual format) error code that can be used here for immediate error treatment
1461 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001462 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001463 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001464 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001465 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1466 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001467 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001468
dbainbri4d3a0dc2020-12-02 00:33:42 +00001469 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001470 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001471 "device-id": oFsm.deviceID,
1472 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001473 // setVid is assumed to be masked already by the caller to 12 bit
1474 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001475 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001476 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001477
1478 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1479 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1480 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001481 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001482
1483 oFsm.numVlanFilterEntries++
1484 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001485 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001486 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001487 "VlanFilterList": vtfdFilterList,
1488 "ForwardOperation": uint8(0x10), //VID investigation
1489 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001490 },
1491 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001492 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001493 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001494 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001495 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001496 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001497 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001498 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1499 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1500 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1501 return
1502 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001503 //accept also nil as (error) return value for writing to LastTx
1504 // - this avoids misinterpretation of new received OMCI messages
1505 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1506 // send shall return (dual format) error code that can be used here for immediate error treatment
1507 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001508 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001509 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001510 }
1511 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001512 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001513 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001514 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001515 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001516 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001517 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001518 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001519 go func(a_pBaseFsm *fsm.FSM) {
1520 _ = a_pBaseFsm.Event(vlanEvReset)
1521 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001522 return
1523 }
1524 }
mpagenkof1d21d12021-06-11 13:14:45 +00001525
mpagenkof1fc3862021-02-16 10:09:52 +00001526 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001527 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001528 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001529 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001530 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001531 configuredUniFlow := oFsm.configuredUniFlow
mpagenko7a592192021-07-28 13:32:00 +00001532 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001533 oFsm.mutexFlowParams.RUnlock()
1534 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001535 //This is correct passing scenario
1536 if errEvto == nil {
1537 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001538 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001539 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001540 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001542 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001543 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001544 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001545 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001546 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001547 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001548 log.Fields{"device-id": oFsm.deviceID})
1549 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1550 }
1551 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001552 //If this incremental flow contains a meter, then create TD for related gems.
1553 if oFsm.actualUniVlanConfigMeter != nil {
1554 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1555 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1556 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1557 oFsm.pOnuUniPort.uniID, gemPort)
1558 if errCreateTrafficDescriptor != nil {
1559 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1560 log.Fields{"device-id": oFsm.deviceID})
1561 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1562 }
1563 }
1564 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001565 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1566 }
1567 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001568}
1569
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001571 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001573 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1574 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001575
mpagenkofc4f56e2020-11-04 17:17:49 +00001576 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001577 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001578 loVlanEntryClear := uint8(0)
1579 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1580 //shallow copy is sufficient as no reference variables are used within struct
1581 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001582 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001583 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001584 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1585 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1586 "device-id": oFsm.deviceID})
1587
1588 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1589 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001590 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001591 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1592 } else {
1593 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1594 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001595 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001596 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1597 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001598 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001599 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001600 "device-id": oFsm.deviceID,
1601 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001602 loVlanEntryClear = 1 //full VlanFilter clear request
1603 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001604 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001605 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001606 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001607 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001608 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001609 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1610 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1611 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1612 return
1613 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001614 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001615 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001616 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001617 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001618 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001619 }
mpagenko01e726e2020-10-23 09:45:29 +00001620 } else {
1621 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1622 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001624 log.Fields{"current vlan list": oFsm.vlanFilterList,
1625 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1626 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1627 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1628 loVlanEntryRmPos = i
1629 break //abort search
1630 }
1631 }
1632 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001633 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001634 //valid entry was found - to be eclipsed
1635 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1636 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1637 if i < loVlanEntryRmPos {
1638 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1639 } else if i < (cVtfdTableSize - 1) {
1640 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1641 } else {
1642 vtfdFilterList[i] = 0 //set last byte if needed
1643 }
1644 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001645 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001646 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001647 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1648 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001649
mpagenkofc4f56e2020-11-04 17:17:49 +00001650 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001651 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001652 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001653 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001654 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001655 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001656 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001657 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1658 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1659 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1660 return
1661 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001662 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001663 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001664 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001665 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001666 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001667 }
mpagenko01e726e2020-10-23 09:45:29 +00001668 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001669 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001670 log.Fields{"device-id": oFsm.deviceID})
1671 }
1672 }
1673 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001674 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1675 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001676 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001677 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001678 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001679 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001680 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001681 go func(a_pBaseFsm *fsm.FSM) {
1682 _ = a_pBaseFsm.Event(vlanEvReset)
1683 }(pConfigVlanStateBaseFsm)
1684 return
1685 }
mpagenko01e726e2020-10-23 09:45:29 +00001686 }
1687
mpagenko15ff4a52021-03-02 10:09:20 +00001688 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001689 if loVlanEntryClear == 1 {
1690 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1691 oFsm.numVlanFilterEntries = 0
1692 } else if loVlanEntryClear == 2 {
1693 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1694 // this loop now includes the 0 element on previous last valid entry
1695 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1696 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1697 }
1698 oFsm.numVlanFilterEntries--
1699 }
mpagenko15ff4a52021-03-02 10:09:20 +00001700 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001701 }
1702 }
1703
mpagenkofc4f56e2020-11-04 17:17:49 +00001704 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001705 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001706 } else {
1707 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001708 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001709 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001710 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001711 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001712 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001713 }(pConfigVlanStateBaseFsm)
1714 }
mpagenkodff5dda2020-08-28 11:52:01 +00001715}
1716
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001718 var tpID uint8
1719 // Extract the tpID
1720 if len(e.Args) > 0 {
1721 tpID = e.Args[0].(uint8)
1722 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1723 } else {
1724 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1725 }
mpagenko01e726e2020-10-23 09:45:29 +00001726 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001727 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001728
mpagenkof582d6a2021-06-18 15:58:10 +00001729 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1730 if pConfigVlanStateAFsm == nil {
1731 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1732 log.Fields{"device-id": oFsm.deviceID})
1733 //would have to be fixed from outside somehow
1734 return
1735 }
1736
mpagenkof1d21d12021-06-11 13:14:45 +00001737 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1738 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001739 //call from 'configured' state of the rule
1740 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1741 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1742 oFsm.mutexFlowParams.Unlock()
1743 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
1744 go func(a_pAFsm *AdapterFsm) {
1745 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1746 }(pConfigVlanStateAFsm)
1747 return
1748 }
mpagenkof1d21d12021-06-11 13:14:45 +00001749 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1750 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1751 oFsm.mutexFlowParams.Unlock()
1752 removeChannel <- true
1753 oFsm.mutexFlowParams.Lock()
1754 }
1755
mpagenkof1fc3862021-02-16 10:09:52 +00001756 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1757 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1758 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1759
mpagenko01e726e2020-10-23 09:45:29 +00001760 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1761 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001763 "device-id": oFsm.deviceID})
1764 } else {
1765 //cut off the actual flow by slicing out the first element
1766 oFsm.uniRemoveFlowsSlice = append(
1767 oFsm.uniRemoveFlowsSlice[:0],
1768 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001769 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001770 "device-id": oFsm.deviceID})
1771 }
1772 oFsm.mutexFlowParams.Unlock()
1773
mpagenkof1fc3862021-02-16 10:09:52 +00001774 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001775 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001776 // Can't call FSM Event directly, decoupling it
1777 go func(a_pAFsm *AdapterFsm) {
1778 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
1779 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001780
mpagenkobb47bc22021-04-20 13:29:09 +00001781 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001782 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001783 if deletedCookie == oFsm.delayNewRuleCookie {
1784 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1785 select {
1786 case <-oFsm.chCookieDeleted:
1787 logger.Debug(ctx, "flushed CookieDeleted")
1788 default:
1789 }
1790 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1791 }
mpagenkobb47bc22021-04-20 13:29:09 +00001792 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1793 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1794 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 -08001795 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001796 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1797 oFsm.flowDeleteChannel <- true
1798 oFsm.signalOnFlowDelete = false
1799 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001800 }
mpagenkobb47bc22021-04-20 13:29:09 +00001801 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001802}
1803
dbainbri4d3a0dc2020-12-02 00:33:42 +00001804func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1805 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001806
1807 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1808 if pConfigVlanStateAFsm != nil {
1809 // abort running message processing
1810 fsmAbortMsg := Message{
1811 Type: TestMsg,
1812 Data: TestMessage{
1813 TestMessageVal: AbortMessageProcessing,
1814 },
1815 }
1816 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1817
mpagenko9a304ea2020-12-16 15:54:01 +00001818 //try to restart the FSM to 'disabled'
1819 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001820 go func(a_pAFsm *AdapterFsm) {
1821 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301822 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001823 }
1824 }(pConfigVlanStateAFsm)
1825 }
1826}
1827
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1829 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001830 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001831 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001832 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001833
1834 oFsm.mutexFlowParams.RLock()
1835 if oFsm.delayNewRuleCookie != 0 {
1836 // looks like the waiting AddFlow is stuck
1837 oFsm.mutexFlowParams.RUnlock()
mpagenko2f487262021-08-23 15:59:06 +00001838 oFsm.chCookieDeleted <- false // let the waiting AddFlow thread terminate
mpagenkof1d21d12021-06-11 13:14:45 +00001839 oFsm.mutexFlowParams.RLock()
1840 }
1841 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1842 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1843 if removeUniFlowParams.isSuspendedOnAdd {
1844 removeChannel := removeUniFlowParams.removeChannel
1845 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1846 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1847 oFsm.mutexFlowParams.RUnlock()
1848 removeChannel <- false
1849 oFsm.mutexFlowParams.RLock()
1850 }
1851 }
1852 }
1853
mpagenkodff5dda2020-08-28 11:52:01 +00001854 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001855 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1856 // current code removes the complete FSM including all flow/rule configuration done so far
1857 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1858 // maybe a more sophisticated approach is possible without clearing the data
1859 if oFsm.clearPersistency {
1860 //permanently remove possibly stored persistent data
1861 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1862 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001863 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001864 }
1865 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001867 }
mpagenko9a304ea2020-12-16 15:54:01 +00001868 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001869 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001871 return
mpagenkodff5dda2020-08-28 11:52:01 +00001872 }
mpagenkof1d21d12021-06-11 13:14:45 +00001873 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001874}
1875
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1877 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001878loop:
1879 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001880 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001881 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001882 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301883 message, ok := <-oFsm.pAdaptFsm.commChan
1884 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301886 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1887 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1888 break loop
1889 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001890 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301891
1892 switch message.Type {
1893 case TestMsg:
1894 msg, _ := message.Data.(TestMessage)
1895 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001896 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001897 break loop
1898 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001899 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301900 case OMCI:
1901 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001902 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301903 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001904 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301905 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001906 }
1907 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001908 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001909}
1910
dbainbri4d3a0dc2020-12-02 00:33:42 +00001911func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1912 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001913 "msgType": msg.OmciMsg.MessageType})
1914
1915 switch msg.OmciMsg.MessageType {
1916 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001917 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001918 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1919 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001920 return
1921 }
mpagenkodff5dda2020-08-28 11:52:01 +00001922 } //CreateResponseType
1923 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001924 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001925 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1926 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001928 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001929 return
1930 }
1931 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1932 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001933 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001934 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001935 return
1936 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001937 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001938 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001939 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001940 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001941 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1942 return
1943 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001944 oFsm.mutexPLastTxMeInstance.RLock()
1945 if oFsm.pLastTxMeInstance != nil {
1946 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1947 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1948 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001949 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001950 { // let the MultiEntity config proceed by stopping the wait function
1951 oFsm.mutexPLastTxMeInstance.RUnlock()
1952 oFsm.omciMIdsResponseReceived <- true
1953 return
1954 }
1955 default:
1956 {
1957 logger.Warnw(ctx, "Unsupported ME name received!",
1958 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1959 }
mpagenkodff5dda2020-08-28 11:52:01 +00001960 }
1961 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001962 } else {
1963 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001964 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001965 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001966 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001967 case omci.DeleteResponseType:
1968 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001969 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1970 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001971 return
1972 }
1973 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001974 default:
1975 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001976 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001977 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001978 return
1979 }
1980 }
1981}
1982
dbainbri4d3a0dc2020-12-02 00:33:42 +00001983func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001984 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1985 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001986 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001987 log.Fields{"device-id": oFsm.deviceID})
1988 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1989 oFsm.deviceID)
1990 }
1991 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1992 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001993 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001994 log.Fields{"device-id": oFsm.deviceID})
1995 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1996 oFsm.deviceID)
1997 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001998 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001999 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00002001 "Error": msgObj.Result})
2002 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2003 return fmt.Errorf("omci CreateResponse Error for device-id %x",
2004 oFsm.deviceID)
2005 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002006 oFsm.mutexPLastTxMeInstance.RLock()
2007 if oFsm.pLastTxMeInstance != nil {
2008 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2009 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2010 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
2011 switch oFsm.pLastTxMeInstance.GetName() {
2012 case "VlanTaggingFilterData", "MulticastOperationsProfile",
2013 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03002014 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002015 {
2016 oFsm.mutexPLastTxMeInstance.RUnlock()
2017 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
2018 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
2019 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
2020 } else { // let the MultiEntity config proceed by stopping the wait function
2021 oFsm.omciMIdsResponseReceived <- true
2022 }
2023 return nil
2024 }
2025 default:
2026 {
2027 logger.Warnw(ctx, "Unsupported ME name received!",
2028 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002029 }
2030 }
2031 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002032 } else {
2033 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002034 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002035 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002036 return nil
2037}
2038
dbainbri4d3a0dc2020-12-02 00:33:42 +00002039func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00002040 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
2041 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002042 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002043 log.Fields{"device-id": oFsm.deviceID})
2044 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2045 oFsm.deviceID)
2046 }
2047 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2048 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002049 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002050 log.Fields{"device-id": oFsm.deviceID})
2051 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2052 oFsm.deviceID)
2053 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002055 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002056 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002057 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2058 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2059 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2060 oFsm.deviceID)
2061 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002062 oFsm.mutexPLastTxMeInstance.RLock()
2063 if oFsm.pLastTxMeInstance != nil {
2064 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2065 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2066 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002067 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002068 { // let the MultiEntity config proceed by stopping the wait function
2069 oFsm.mutexPLastTxMeInstance.RUnlock()
2070 oFsm.omciMIdsResponseReceived <- true
2071 return nil
2072 }
2073 default:
2074 {
2075 logger.Warnw(ctx, "Unsupported ME name received!",
2076 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2077 }
mpagenko01e726e2020-10-23 09:45:29 +00002078 }
2079 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002080 } else {
2081 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002082 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002083 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002084 return nil
2085}
2086
dbainbri4d3a0dc2020-12-02 00:33:42 +00002087func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002088 oFsm.mutexFlowParams.RLock()
2089 evtocdID := oFsm.evtocdID
2090 oFsm.mutexFlowParams.RUnlock()
2091
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002092 if aFlowEntryNo == 0 {
2093 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002094 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2095 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002096 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002097 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002098 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002099 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002100 associationType := 2 // default to uniPPTP
2101 if oFsm.pOnuUniPort.portType == uniVEIP {
2102 associationType = 10
2103 }
2104 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002105 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002106 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002107 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002108 "AssociationType": uint8(associationType),
2109 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002110 },
2111 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002112 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002113 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
2114 true, oFsm.pAdaptFsm.commChan, meParams)
2115 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002116 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002117 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2118 log.Fields{"device-id": oFsm.deviceID})
2119 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2120 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2121 }
mpagenkodff5dda2020-08-28 11:52:01 +00002122 //accept also nil as (error) return value for writing to LastTx
2123 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002124 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002125 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002126
2127 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002128 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002129 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002130 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002131 log.Fields{"device-id": oFsm.deviceID})
2132 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2133 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2134 }
2135
2136 // Set the EVTOCD ME default params
2137 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002138 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002139 Attributes: me.AttributeValueMap{
2140 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2141 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2142 "DownstreamMode": uint8(cDefaultDownstreamMode),
2143 },
2144 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002145 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002146 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2147 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002148 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002149 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002150 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002151 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2152 log.Fields{"device-id": oFsm.deviceID})
2153 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2154 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2155 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002156 //accept also nil as (error) return value for writing to LastTx
2157 // - this avoids misinterpretation of new received OMCI messages
2158 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002159 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002160
2161 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002162 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002163 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002164 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002165 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302166 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002167 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002168 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002169 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002170
mpagenko551a4d42020-12-08 18:09:20 +00002171 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002172 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002173 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002174 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002175 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002176 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002177 sliceEvtocdRule := make([]uint8, 16)
2178 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2179 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2180 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2181 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2182 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2183
2184 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2185 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2186 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2187 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2188 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2189
2190 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2191 0<<cTreatTTROffset| // Do not pop any tags
2192 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2193 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2194 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2195
2196 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2197 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2198 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2199 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2200
2201 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002202 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002203 Attributes: me.AttributeValueMap{
2204 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2205 },
2206 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002207 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002208 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2209 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002210 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002211 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002212 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002213 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2214 log.Fields{"device-id": oFsm.deviceID})
2215 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2216 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2217 }
mpagenkodff5dda2020-08-28 11:52:01 +00002218 //accept also nil as (error) return value for writing to LastTx
2219 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002220 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002221 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002222
2223 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002224 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002225 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002226 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002227 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302228 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002229 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2230
mpagenkodff5dda2020-08-28 11:52:01 +00002231 }
2232 } else {
2233 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2234 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002235 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2236 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2237 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2238 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002239 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002240 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002241 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002242 sliceEvtocdRule := make([]uint8, 16)
2243 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2244 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2245 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2246 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2247 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2248
2249 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002250 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2251 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002252 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2253 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2254
2255 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002256 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002257 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2258 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2259 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2260
2261 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002262 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2263 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002264 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002265 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002266
2267 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002268 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002269 Attributes: me.AttributeValueMap{
2270 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2271 },
2272 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002273 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002274 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2275 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002276 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002277 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002278 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002279 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2280 log.Fields{"device-id": oFsm.deviceID})
2281 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2282 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2283 }
mpagenkodff5dda2020-08-28 11:52:01 +00002284 //accept also nil as (error) return value for writing to LastTx
2285 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002286 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002287 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002288
2289 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002290 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002291 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002293 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302294 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002295 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002296 }
2297 } else {
2298 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2299 { // just for local var's
2300 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002301 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002302 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002303 sliceEvtocdRule := make([]uint8, 16)
2304 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2305 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2306 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2307 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2308 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2309
2310 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2311 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2312 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2313 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2314 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2315
2316 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2317 0<<cTreatTTROffset| // Do not pop any tags
2318 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2319 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2320 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2321
2322 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2323 0<<cTreatPrioOffset| // vlan prio set to 0
2324 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002325 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002326 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2327
mpagenko551a4d42020-12-08 18:09:20 +00002328 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002329 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002330 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002331 Attributes: me.AttributeValueMap{
2332 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2333 },
2334 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002335 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002336 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2337 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002338 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002339 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002340 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002341 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2342 log.Fields{"device-id": oFsm.deviceID})
2343 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2344 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2345 }
mpagenkodff5dda2020-08-28 11:52:01 +00002346 //accept also nil as (error) return value for writing to LastTx
2347 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002348 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002349 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002350
2351 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002352 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002353 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002354 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002355 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302356 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002357 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2358
mpagenkodff5dda2020-08-28 11:52:01 +00002359 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002360 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002361 { // just for local var's
2362 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002364 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002365 sliceEvtocdRule := make([]uint8, 16)
2366 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2367 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2368 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2369 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2370 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2371
2372 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2373 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2374 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2375 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2376 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2377
2378 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2379 1<<cTreatTTROffset| // pop the prio-tag
2380 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2381 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2382 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2383
mpagenko551a4d42020-12-08 18:09:20 +00002384 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002385 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2386 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2387 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002388 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002389 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002390 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002391
2392 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002393 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002394 Attributes: me.AttributeValueMap{
2395 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2396 },
2397 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002398 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002399 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2400 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002401 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002402 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002403 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002404 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2405 log.Fields{"device-id": oFsm.deviceID})
2406 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2407 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2408 }
mpagenkodff5dda2020-08-28 11:52:01 +00002409 //accept also nil as (error) return value for writing to LastTx
2410 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002411 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002412 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002413
2414 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002415 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002416 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002417 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002418 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302419 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002420 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2421
mpagenkodff5dda2020-08-28 11:52:01 +00002422 }
2423 } //just for local var's
2424 }
2425 }
2426
mpagenkofc4f56e2020-11-04 17:17:49 +00002427 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002428 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002429 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002430 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002431 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002432 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002433}
2434
dbainbri4d3a0dc2020-12-02 00:33:42 +00002435func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002436 oFsm.mutexFlowParams.RLock()
2437 evtocdID := oFsm.evtocdID
2438 oFsm.mutexFlowParams.RUnlock()
2439
mpagenko01e726e2020-10-23 09:45:29 +00002440 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2441 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2442 //transparent transmission was set
2443 //perhaps the config is not needed for removal,
2444 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002445 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002446 "device-id": oFsm.deviceID})
2447 sliceEvtocdRule := make([]uint8, 16)
2448 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2449 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2450 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2451 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2452 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2453
2454 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2455 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2456 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2457 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2458 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2459
2460 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2461 0<<cTreatTTROffset| // Do not pop any tags
2462 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2463 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2464 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2465
2466 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2467 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2468 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2469 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2470
2471 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002472 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002473 Attributes: me.AttributeValueMap{
2474 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2475 },
2476 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002477 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002478 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2479 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002480 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002481 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002482 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002483 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2484 log.Fields{"device-id": oFsm.deviceID})
2485 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2486 return
2487 }
mpagenko01e726e2020-10-23 09:45:29 +00002488 //accept also nil as (error) return value for writing to LastTx
2489 // - this avoids misinterpretation of new received OMCI messages
2490 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002491 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002492
2493 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002494 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002495 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002496 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002497 log.Fields{"device-id": oFsm.deviceID})
2498 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2499 return
2500 }
2501 } else {
2502 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002503 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002504 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002505 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002506 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002507 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002508 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2509 sliceEvtocdRule := make([]uint8, 16)
2510 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2511 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2512 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2513 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2514 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2515
2516 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2517 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2518 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2519 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2520 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2521
2522 // delete indication for the indicated Filter
2523 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2524 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2525
2526 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002527 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002528 Attributes: me.AttributeValueMap{
2529 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2530 },
2531 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002532 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002533 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2534 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002535 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002536 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002537 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002538 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2539 log.Fields{"device-id": oFsm.deviceID})
2540 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2541 return
2542 }
mpagenko01e726e2020-10-23 09:45:29 +00002543 //accept also nil as (error) return value for writing to LastTx
2544 // - this avoids misinterpretation of new received OMCI messages
2545 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002546 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002547
2548 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002549 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002550 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002551 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002552 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2553 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2554 return
2555 }
2556 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002557 // VOL-3685
2558 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2559 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2560 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2561 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2562 // later when the flow is being re-installed.
2563 // Of course this is applicable to case only where single service (or single tcont) is in use and
2564 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2565 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2566 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002567 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2568 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002569 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002570 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2571 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002572 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002573 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002574 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002575 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002576 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2577 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002578 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002579 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002580 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002581 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2582 log.Fields{"device-id": oFsm.deviceID})
2583 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2584 return
2585 }
mpagenko01e726e2020-10-23 09:45:29 +00002586 //accept also nil as (error) return value for writing to LastTx
2587 // - this avoids misinterpretation of new received OMCI messages
2588 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002589 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002590
2591 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002592 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002593 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002594 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002595 log.Fields{"device-id": oFsm.deviceID})
2596 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2597 return
2598 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002599 } else {
2600 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2601 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002602 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002603 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002604 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002605 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2606 { // just for local var's
2607 // this defines stacking scenario: untagged->singletagged
2608 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2609 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2610 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2611 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002612 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002613 "device-id": oFsm.deviceID})
2614 sliceEvtocdRule := make([]uint8, 16)
2615 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2616 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2617 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2618 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2619 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002620
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002621 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2622 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2623 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2624 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2625 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002626
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002627 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2628 0<<cTreatTTROffset| // Do not pop any tags
2629 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2630 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2631 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002632
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002633 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2634 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2635 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2636 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002637
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002638 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002639 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002640 Attributes: me.AttributeValueMap{
2641 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2642 },
2643 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002644 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002645 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2646 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002647 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002648 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002649 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002650 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2651 log.Fields{"device-id": oFsm.deviceID})
2652 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2653 return
2654 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002655 //accept also nil as (error) return value for writing to LastTx
2656 // - this avoids misinterpretation of new received OMCI messages
2657 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002658 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002659
2660 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002661 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002662 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002663 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002664 log.Fields{"device-id": oFsm.deviceID})
2665 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2666 return
2667 }
2668 } // just for local var's
2669 { // just for local var's
2670 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002671 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002672 "device-id": oFsm.deviceID})
2673 sliceEvtocdRule := make([]uint8, 16)
2674 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2675 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2676 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2677 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2678 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2679
2680 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2681 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2682 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2683 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2684 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2685
2686 // delete indication for the indicated Filter
2687 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2688 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2689
2690 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002691 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002692 Attributes: me.AttributeValueMap{
2693 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2694 },
2695 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002696 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002697 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2698 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002699 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002700 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002701 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002702 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2703 log.Fields{"device-id": oFsm.deviceID})
2704 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2705 return
2706 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002707 //accept also nil as (error) return value for writing to LastTx
2708 // - this avoids misinterpretation of new received OMCI messages
2709 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002710 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002711
2712 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002713 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002714 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002715 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002716 log.Fields{"device-id": oFsm.deviceID})
2717 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2718 return
2719 }
mpagenko01e726e2020-10-23 09:45:29 +00002720 }
2721 } //just for local var's
2722 }
2723 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002724 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002725 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002726 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002727}
2728
dbainbri4d3a0dc2020-12-02 00:33:42 +00002729func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002730 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002731 if oFsm.isCanceled {
2732 // FSM already canceled before entering wait
2733 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2734 oFsm.mutexIsAwaitingResponse.Unlock()
2735 return fmt.Errorf(cErrWaitAborted)
2736 }
mpagenko7d6bb022021-03-11 15:07:55 +00002737 oFsm.isAwaitingResponse = true
2738 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002739 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302740 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002741 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002742 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002743 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002744 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002745 oFsm.mutexIsAwaitingResponse.Lock()
2746 oFsm.isAwaitingResponse = false
2747 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002748 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002749 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302750 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002751 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002752 oFsm.mutexIsAwaitingResponse.Lock()
2753 oFsm.isAwaitingResponse = false
2754 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002755 return nil
2756 }
mpagenko7d6bb022021-03-11 15:07:55 +00002757 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002758 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002759 oFsm.mutexIsAwaitingResponse.Lock()
2760 oFsm.isAwaitingResponse = false
2761 oFsm.mutexIsAwaitingResponse.Unlock()
2762 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002763 }
2764}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002765
mpagenko551a4d42020-12-08 18:09:20 +00002766func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002767 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002768 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002769 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002770 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002771 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002772 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002773 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002774 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2775 }
2776
dbainbri4d3a0dc2020-12-02 00:33:42 +00002777 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002778 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002779 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002780 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002781 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002782 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2783 }
2784
dbainbri4d3a0dc2020-12-02 00:33:42 +00002785 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002786 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002787 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002788 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002789 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002790 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2791 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002792 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2793 if errMacBpCdEID != nil {
2794 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2795 log.Fields{"device-id": oFsm.deviceID})
2796 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2797 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002798
Mahir Gunyel6781f962021-05-16 23:30:08 -07002799 }
2800 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2801 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2802 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002803 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002804 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002805 Attributes: me.AttributeValueMap{
2806 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2807 "PortNum": 0xf0, //fixed unique ANI side indication
2808 "TpType": 6, //MCGemIWTP
2809 "TpPointer": multicastGemPortID,
2810 },
2811 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002812 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002813 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2814 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2815 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002816 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002817 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2818 log.Fields{"device-id": oFsm.deviceID})
2819 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2820 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2821 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002822 //accept also nil as (error) return value for writing to LastTx
2823 // - this avoids misinterpretation of new received OMCI messages
2824 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002825 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002826 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002827 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002828 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002829 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002830 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002831 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2832 }
2833
2834 // ==> Start creating VTFD for mcast vlan
2835
2836 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2837 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002838 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002839
dbainbri4d3a0dc2020-12-02 00:33:42 +00002840 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002841 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2842 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2843 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2844
2845 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2846 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2847 // new vlan associated with a different TP.
2848 vtfdFilterList[0] = uint16(vlanID)
2849
2850 meParams = me.ParamData{
2851 EntityID: mcastVtfdID,
2852 Attributes: me.AttributeValueMap{
2853 "VlanFilterList": vtfdFilterList,
2854 "ForwardOperation": uint8(0x10), //VID investigation
2855 "NumberOfEntries": oFsm.numVlanFilterEntries,
2856 },
2857 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002858 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002859 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2860 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2861 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002862 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002863 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2864 log.Fields{"device-id": oFsm.deviceID})
2865 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2866 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2867 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002868 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002869 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002870 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002871 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002872 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002873 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002874 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002875 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2876 }
2877
2878 return nil
2879}
2880
dbainbri4d3a0dc2020-12-02 00:33:42 +00002881func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002882 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002883 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002884 logger.Errorw(ctx, "error generrating me instance id",
2885 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002886 return err
2887 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002888 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2889 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002890 meParams := me.ParamData{
2891 EntityID: instID,
2892 Attributes: me.AttributeValueMap{
2893 "MeType": 0,
2894 //Direct reference to the Operation profile
2895 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002896 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002897 },
2898 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002899 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002900 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2901 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002902 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002903 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002904 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002905 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2906 log.Fields{"device-id": oFsm.deviceID})
2907 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2908 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2909 oFsm.deviceID, err)
2910 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002911 //accept also nil as (error) return value for writing to LastTx
2912 // - this avoids misinterpretation of new received OMCI messages
2913 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002914 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002915 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002916 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002917 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002918 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002919 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2920 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2921 }
2922 return nil
2923}
2924
dbainbri4d3a0dc2020-12-02 00:33:42 +00002925func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002926 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002927 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002928 logger.Errorw(ctx, "error generating me instance id",
2929 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002930 return err
2931 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002932 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2933 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002934 meParams := me.ParamData{
2935 EntityID: instID,
2936 Attributes: me.AttributeValueMap{
2937 "IgmpVersion": 2,
2938 "IgmpFunction": 0,
2939 //0 means false
2940 "ImmediateLeave": 0,
2941 "Robustness": 2,
2942 "QuerierIp": 0,
2943 "QueryInterval": 125,
2944 "QuerierMaxResponseTime": 100,
2945 "LastMemberResponseTime": 10,
2946 //0 means false
2947 "UnauthorizedJoinBehaviour": 0,
2948 },
2949 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002950 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002951 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2952 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002953 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002954 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002955 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002956 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2957 log.Fields{"device-id": oFsm.deviceID})
2958 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2959 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2960 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002961 //accept also nil as (error) return value for writing to LastTx
2962 // - this avoids misinterpretation of new received OMCI messages
2963 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002964 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002965 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002966 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002967 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002968 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002969 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002970 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002971 }
2972 return nil
2973}
2974
dbainbri4d3a0dc2020-12-02 00:33:42 +00002975func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002976 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002977 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002978 logger.Errorw(ctx, "error generating me instance id",
2979 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002980 return err
2981 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002982 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2983 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002984 //TODO check that this is correct
2985 // Table control
2986 //setCtrl = 1
2987 //rowPartId = 0
2988 //test = 0
2989 //rowKey = 0
2990 tableCtrlStr := "0100000000000000"
2991 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002992 dynamicAccessCL := make([]uint8, 24)
2993 copy(dynamicAccessCL, tableCtrl)
2994 //Multicast GemPortId
2995 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2996 // python version waits for installation of flows, see line 723 onward of
2997 // brcm_openomci_onu_handler.py
2998 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2999 //Source IP all to 0
3000 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
3001 //TODO start and end are hardcoded, get from TP
3002 // Destination IP address start of range
3003 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
3004 // Destination IP address end of range
3005 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
3006 //imputed group bandwidth
3007 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
3008
3009 meParams := me.ParamData{
3010 EntityID: instID,
3011 Attributes: me.AttributeValueMap{
3012 "DynamicAccessControlListTable": dynamicAccessCL,
3013 },
3014 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003015 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003016 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
3017 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003018 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03003019 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003020 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03003021 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
3022 log.Fields{"device-id": oFsm.deviceID})
3023 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
3024 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
3025 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003026 //accept also nil as (error) return value for writing to LastTx
3027 // - this avoids misinterpretation of new received OMCI messages
3028 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00003029 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003030 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03003031 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003032 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00003033 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003034 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03003035 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03003036 }
3037 return nil
3038}
Girish Gowdra26a40922021-01-29 17:14:34 -08003039
ozgecanetsia82b91a62021-05-21 18:54:49 +03003040func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
3041 tpID uint8, uniID uint8, gemPortID uint16) error {
3042 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3043 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3044 // I created unique TD ID by flow direction.
3045 // TODO! Traffic descriptor ME ID will check
3046 trafficDescriptorID := gemPortID
3047 if aMeter == nil {
3048 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3049 }
3050 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3051 if err != nil {
3052 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3053 return err
3054 }
3055 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3056 cbs := trafficShapingInfo.Cbs
3057 pir := trafficShapingInfo.Pir
3058 pbs := trafficShapingInfo.Pbs
3059
3060 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3061 meParams := me.ParamData{
3062 EntityID: trafficDescriptorID,
3063 Attributes: me.AttributeValueMap{
3064 "Cir": cir,
3065 "Pir": pir,
3066 "Cbs": cbs,
3067 "Pbs": pbs,
3068 "ColourMode": 1,
3069 "IngressColourMarking": 3,
3070 "EgressColourMarking": 3,
3071 "MeterType": 1,
3072 },
3073 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003074 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003075 meInstance, errCreateTD := oFsm.pOmciCC.sendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
3076 true, oFsm.pAdaptFsm.commChan, meParams)
3077 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003078 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003079 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3080 return err
3081 }
3082 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003083 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003084 err = oFsm.waitforOmciResponse(ctx)
3085 if err != nil {
3086 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3087 return err
3088 }
3089
3090 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID)
3091 if err != nil {
3092 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3093 return err
3094 }
3095 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3096
3097 return nil
3098}
3099
3100func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortID uint16) error {
3101 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID})
3102 meParams := me.ParamData{
3103 EntityID: gemPortID,
3104 Attributes: me.AttributeValueMap{
3105 "TrafficManagementPointerForUpstream": gemPortID,
3106 },
3107 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003108 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003109 meInstance, err := oFsm.pOmciCC.sendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3110 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
3111 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003112 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003113 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3114 return err
3115 }
3116 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003117 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003118 err = oFsm.waitforOmciResponse(ctx)
3119 if err != nil {
3120 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3121 return err
3122 }
3123 return nil
3124}
3125
Girish Gowdra26a40922021-01-29 17:14:34 -08003126// IsFlowRemovePending returns true if there are pending flows to remove, else false.
Holger Hildebrandt72eaab72021-11-05 08:54:59 +00003127func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(ctx context.Context, aFlowDeleteChannel chan<- bool) bool {
3128 if oFsm == nil {
3129 logger.Error(ctx, "no valid UniVlanConfigFsm!")
3130 return false
3131 }
mpagenkobb47bc22021-04-20 13:29:09 +00003132 oFsm.mutexFlowParams.Lock()
3133 defer oFsm.mutexFlowParams.Unlock()
3134 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3135 //flow removal is still ongoing/pending
3136 oFsm.signalOnFlowDelete = true
3137 oFsm.flowDeleteChannel = aFlowDeleteChannel
3138 return true
3139 }
3140 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003141}
Holger Hildebrandtd3a251d2021-09-20 12:12:53 +00003142
3143func (oFsm *UniVlanConfigFsm) reconcileVlanFilterList(ctx context.Context, aSetVid uint16) {
3144 // VOL-4342 - reconcile vlanFilterList[] for possible later flow removal
3145 if aSetVid == uint16(of.OfpVlanId_OFPVID_PRESENT) {
3146 logger.Debugw(ctx, "reconciling - transparent setup: no VTFD config was required",
3147 log.Fields{"device-id": oFsm.deviceID})
3148 } else {
3149 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] = aSetVid
3150 logger.Debugw(ctx, "reconciling - Vid of VTFD stored in list", log.Fields{
3151 "index": oFsm.numVlanFilterEntries,
3152 "vid": strconv.FormatInt(int64(oFsm.vlanFilterList[oFsm.numVlanFilterEntries]), 16),
3153 "device-id": oFsm.deviceID})
3154 oFsm.numVlanFilterEntries++
3155 }
3156}
Holger Hildebrandtddc4fbd2022-02-04 14:10:36 +00003157
3158// PrepareForGarbageCollection - remove references to prepare for garbage collection
3159func (oFsm *UniVlanConfigFsm) PrepareForGarbageCollection(ctx context.Context, aDeviceID string) {
3160 logger.Debugw(ctx, "prepare for garbage collection", log.Fields{"device-id": aDeviceID})
3161 oFsm.pDeviceHandler = nil
3162 oFsm.pOmciCC = nil
3163}