blob: 26ecac0543f79503a565b3cc4c721d652b72d6c5 [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})
mpagenko01e726e2020-10-23 09:45:29 +0000342 oFsm.numUniFlows = 1
343 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
344
345 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000346 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000347 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000348 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000349 return err
350 }
351
352 return nil
353}
354
mpagenko7d6bb022021-03-11 15:07:55 +0000355//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000356func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000357 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000358 oFsm.mutexIsAwaitingResponse.Lock()
359 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000360 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000361 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
362 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
363 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000364 //use channel to indicate that the response waiting shall be aborted
365 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000366 } else {
367 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000368 }
mpagenkocf48e452021-04-23 09:23:00 +0000369
mpagenko7d6bb022021-03-11 15:07:55 +0000370 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
371 pAdaptFsm := oFsm.pAdaptFsm
372 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000373 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000374 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000375 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000376 }
mpagenko7d6bb022021-03-11 15:07:55 +0000377 }
378}
379
mpagenko551a4d42020-12-08 18:09:20 +0000380//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
381func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
382 //mutex protection is required for possible concurrent access to FSM members
383 oFsm.mutexFlowParams.RLock()
384 defer oFsm.mutexFlowParams.RUnlock()
385 return oFsm.TpIDWaitingFor
386}
387
mpagenko2418ab02020-11-12 12:58:06 +0000388//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
389func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
390 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000391 oFsm.mutexFlowParams.Lock()
392 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000393 oFsm.clearPersistency = aClear
394}
395
mpagenko01e726e2020-10-23 09:45:29 +0000396//SetUniFlowParams verifies on existence of flow parameters to be configured,
397// optionally udates the cookie list or appends a new flow if there is space
398// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000399// ignore complexity by now
400// nolint: gocyclo
401func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300402 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8, lastFlowToReconcile bool, aMeter *voltha.OfpMeterConfig) error {
mpagenko01e726e2020-10-23 09:45:29 +0000403 loRuleParams := uniVlanRuleParams{
404 TpID: aTpID,
405 MatchVid: uint32(aMatchVlan),
406 SetVid: uint32(aSetVlan),
407 SetPcp: uint32(aSetPcp),
408 }
409 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
410 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
411 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
mpagenko01e726e2020-10-23 09:45:29 +0000412 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
413 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
414 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
415 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
416 } else {
417 if !oFsm.acceptIncrementalEvtoOption {
418 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
419 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
420 }
421 }
422
423 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
424 // no prio/vid filtering requested
425 loRuleParams.TagsToRemove = 0 //no tag pop action
426 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
427 if loRuleParams.SetPcp == cCopyPrioFromInner {
428 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
429 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
430 // might collide with NoMatchVid/CopyPrio(/setVid) setting
431 // this was some precondition setting taken over from py adapter ..
432 loRuleParams.SetPcp = 0
433 }
434 }
435
mpagenkof1d21d12021-06-11 13:14:45 +0000436 //check if there is some ongoing delete-request running for this flow. If so, block here until this is finished.
437 // might be accordingly rwCore processing runs into timeout in specific situations - needs to be observed ...
438 // this is to protect uniVlanFlowParams from adding new or re-writing the same cookie to the rule currently under deletion
439 oFsm.mutexFlowParams.RLock()
440 if len(oFsm.uniRemoveFlowsSlice) > 0 {
441 for flow, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
442 if removeUniFlowParams.vlanRuleParams == loRuleParams {
443 // the flow to add is the same as the one already in progress of deleting
444 logger.Infow(ctx, "UniVlanConfigFsm flow setting - suspending rule-add due to ongoing removal", log.Fields{
mpagenkof582d6a2021-06-18 15:58:10 +0000445 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie, "remove-index": flow})
446 if flow >= len(oFsm.uniRemoveFlowsSlice) {
447 logger.Errorw(ctx, "abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice", log.Fields{
448 "device-id": oFsm.deviceID, "slice length": len(oFsm.uniRemoveFlowsSlice)})
449 oFsm.mutexFlowParams.RUnlock()
450 return fmt.Errorf("abort UniVlanConfigFsm flow add - inconsistent RemoveFlowsSlice %s", oFsm.deviceID)
451 }
mpagenkof1d21d12021-06-11 13:14:45 +0000452 pRemoveParams := &oFsm.uniRemoveFlowsSlice[flow] //wants to modify the uniRemoveFlowsSlice element directly!
453 oFsm.mutexFlowParams.RUnlock()
454 if err := oFsm.suspendAddRule(ctx, pRemoveParams); err != nil {
455 logger.Errorw(ctx, "UniVlanConfigFsm suspension on add aborted - abort complete add-request", log.Fields{
456 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
457 return fmt.Errorf("abort UniVlanConfigFsm suspension on add %s", oFsm.deviceID)
458 }
459 oFsm.mutexFlowParams.RLock()
mpagenkof582d6a2021-06-18 15:58:10 +0000460 break //this specific rule should only exist once per uniRemoveFlowsSlice
mpagenkof1d21d12021-06-11 13:14:45 +0000461 }
462 }
463 }
464 oFsm.mutexFlowParams.RUnlock()
465
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000466 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000467 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000468 requestAppendRule := false
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +0200469 oFsm.lastFlowToReconcile = lastFlowToReconcile
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000470 //mutex protection is required for possible concurrent access to FSM members
471 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000472 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
473 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
474 // countable run time optimization (perhaps with including the hash in kvStore storage?)
475 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000476 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000477 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
ozgecanetsia82b91a62021-05-21 18:54:49 +0300478 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
479 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
480 "SetPcp": loRuleParams.SetPcp,
481 "device-id": oFsm.deviceID, " uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000482 var cookieMatch bool
483 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
484 cookieMatch = false
485 for _, cookie := range storedUniFlowParams.CookieSlice {
486 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000487 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000488 "device-id": oFsm.deviceID, "cookie": cookie})
489 cookieMatch = true
490 break //found new cookie - no further search for this requested cookie
491 }
492 }
493 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000494 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
495 if delayedCookie != 0 {
496 //a delay for adding the cookie to this rule is requested
497 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
498 oFsm.mutexFlowParams.Unlock()
499 oFsm.suspendNewRule(ctx)
500 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
501 oFsm.mutexFlowParams.Lock()
502 } else {
503 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
504 "device-id": oFsm.deviceID, "cookie": newCookie})
505 //as range works with copies of the slice we have to write to the original slice!!
506 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
507 newCookie)
508 flowCookieModify = true
509 }
mpagenko01e726e2020-10-23 09:45:29 +0000510 }
511 } //for all new cookies
512 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000513 }
514 }
mpagenkof1fc3862021-02-16 10:09:52 +0000515 oFsm.mutexFlowParams.Unlock()
516
517 if !flowEntryMatch { //it is (was) a new rule
518 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
519 requestAppendRule = true //default assumption here is that rule is to be appended
520 flowCookieModify = true //and that the the flow data base is to be updated
521 if delayedCookie != 0 { //it was suspended
522 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
523 }
524 }
525 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
526 if requestAppendRule {
527 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000528 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000529 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
530 loFlowParams.CookieSlice = make([]uint64, 0)
531 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
ozgecanetsia82b91a62021-05-21 18:54:49 +0300532 if aMeter != nil {
533 loFlowParams.Meter = aMeter
534 }
mpagenko01e726e2020-10-23 09:45:29 +0000535 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000536 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000537 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
538 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
539 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800540 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
ozgecanetsia82b91a62021-05-21 18:54:49 +0300541 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID})
mpagenko01e726e2020-10-23 09:45:29 +0000542
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000543 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000544 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
545
546 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
547 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
548 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000549 //attention: take care to release the mutexFlowParams when calling the FSM directly -
550 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000551 oFsm.mutexFlowParams.Unlock()
552 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000553 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
554 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
555 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
556 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000557 }
558 return nil
559 }
mpagenko01e726e2020-10-23 09:45:29 +0000560 // note: theoretical it would be possible to clear the same rule from the remove slice
561 // (for entries that have not yet been started with removal)
562 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
563 // 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 +0000564
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000565 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
566 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000567 if oFsm.configuredUniFlow == 0 {
568 // this is a restart with a complete new flow, we can re-use the initial flow config control
569 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000570 //attention: take care to release the mutexFlowParams when calling the FSM directly -
571 // synchronous FSM 'event/state' functions may rely on this mutex
572 oFsm.mutexFlowParams.Unlock()
573 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
574 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
575 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
576 }
mpagenko551a4d42020-12-08 18:09:20 +0000577 } else {
578 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000579 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +0000580 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
581 //check introduced after having observed some panic here
582 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm - inconsistent counter",
583 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
584 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
585 oFsm.mutexFlowParams.Unlock()
586 return fmt.Errorf("abort UniVlanConfigFsm on add due to internal counter mismatch %s", oFsm.deviceID)
587 }
mpagenko9a304ea2020-12-16 15:54:01 +0000588 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +0300589 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +0000590 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000591 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000592 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +0000593 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
mpagenkobb47bc22021-04-20 13:29:09 +0000594 //attention: take care to release the mutexFlowParams when calling the FSM directly -
595 // synchronous FSM 'event/state' functions may rely on this mutex
mpagenko18eca9c2021-07-26 11:03:45 +0000596 // but it must be released already before calling getTechProfileDone() as it may already be locked
597 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
mpagenkobb47bc22021-04-20 13:29:09 +0000598 oFsm.mutexFlowParams.Unlock()
mpagenko18eca9c2021-07-26 11:03:45 +0000599 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
600 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
601 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
602 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
603
mpagenkobb47bc22021-04-20 13:29:09 +0000604 var fsmErr error
605 if loTechProfDone {
606 // let the vlan processing continue with next rule
607 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
608 } else {
609 // set to waiting for Techprofile
610 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
611 }
612 if fsmErr != nil {
613 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
614 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
615 }
mpagenko551a4d42020-12-08 18:09:20 +0000616 }
mpagenkobb47bc22021-04-20 13:29:09 +0000617 } else {
618 // if not in the appropriate state a new entry will be automatically considered later
619 // when the configDone state is reached
620 oFsm.mutexFlowParams.Unlock()
621 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000623 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000624 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000625 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000626 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
627 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000628 } else {
629 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000630 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000631 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000632 if oFsm.numUniFlows == oFsm.configuredUniFlow {
633 //all requested rules really have been configured
634 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000635 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000636 if oFsm.pDeviceHandler != nil {
637 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000638 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000639 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000640 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
641 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000642 }
643 } else {
644 // avoid device reason update as the rule config connected to this flow may still be in progress
645 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000646 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000647 log.Fields{"device-id": oFsm.deviceID,
648 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000649 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000650 }
651 }
mpagenko01e726e2020-10-23 09:45:29 +0000652
mpagenkof1fc3862021-02-16 10:09:52 +0000653 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000654 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000655 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000656 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
657 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000658 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000659 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000660 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000661 }
mpagenko15ff4a52021-03-02 10:09:20 +0000662 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000663 }
664 return nil
665}
666
mpagenkof1d21d12021-06-11 13:14:45 +0000667func (oFsm *UniVlanConfigFsm) suspendAddRule(ctx context.Context, apRemoveFlowParams *uniRemoveVlanFlowParams) error {
668 oFsm.mutexFlowParams.Lock()
669 deleteChannel := apRemoveFlowParams.removeChannel
670 apRemoveFlowParams.isSuspendedOnAdd = true
671 oFsm.mutexFlowParams.Unlock()
672
673 // isSuspendedOnAdd is not reset here-after as the assumption is, that after
674 select {
675 case success := <-deleteChannel:
676 //no need to reset isSuspendedOnAdd as in this case the removeElement will be deleted completely
677 if success {
678 logger.Infow(ctx, "resume adding this rule after having completed deletion", log.Fields{
679 "device-id": oFsm.deviceID})
680 return nil
681 }
682 return fmt.Errorf("suspend aborted, also aborting add-activity: %s", oFsm.deviceID)
683 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
684 oFsm.mutexFlowParams.Lock()
685 if apRemoveFlowParams != nil {
686 apRemoveFlowParams.isSuspendedOnAdd = false
687 }
688 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000689 logger.Errorw(ctx, "timeout waiting for deletion of rule, also aborting add-activity", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +0000690 "device-id": oFsm.deviceID})
mpagenkof582d6a2021-06-18 15:58:10 +0000691 return fmt.Errorf("suspend aborted on timeout, also aborting add-activity: %s", oFsm.deviceID)
mpagenkof1d21d12021-06-11 13:14:45 +0000692 }
mpagenkof1d21d12021-06-11 13:14:45 +0000693}
694
mpagenkof1fc3862021-02-16 10:09:52 +0000695// VOL-3828 flow config sequence workaround ########### start ##########
696func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
697 //assumes mutexFlowParams.Lock() protection from caller!
698 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
699 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
mpagenkof1d21d12021-06-11 13:14:45 +0000700 // suspend check is done only if there is only one cookie in the request
mpagenkof1fc3862021-02-16 10:09:52 +0000701 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
702 newCookie := aCookieSlice[0]
703 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
704 for _, cookie := range storedUniFlowParams.CookieSlice {
705 if cookie == newCookie {
706 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
707 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
708 oFsm.delayNewRuleCookie = newCookie
709 return newCookie //found new cookie in some existing rule
710 }
711 } // for all stored cookies of the actual inspected rule
712 } //for all rules
713 }
714 return 0 //no delay requested
715}
716func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
717 oFsm.mutexFlowParams.RLock()
718 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
719 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
720 oFsm.mutexFlowParams.RUnlock()
721 select {
722 case <-oFsm.chCookieDeleted:
723 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
724 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000725 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000726 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
727 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
728 }
729 oFsm.mutexFlowParams.Lock()
730 oFsm.delayNewRuleCookie = 0
731 oFsm.mutexFlowParams.Unlock()
732}
733func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
734 oFsm.mutexFlowParams.Lock()
735 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
736 oFsm.mutexFlowParams.Unlock()
737
738 if delayedCookie != 0 {
739 oFsm.suspendNewRule(ctx)
740 }
741 return delayedCookie
742}
743
744//returns flowModified, RuleAppendRequest
745func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
746 flowEntryMatch := false
747 oFsm.mutexFlowParams.Lock()
748 defer oFsm.mutexFlowParams.Unlock()
749 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
750 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
751 flowEntryMatch = true
752 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
753 "device-id": oFsm.deviceID})
754 cookieMatch := false
755 for _, cookie := range storedUniFlowParams.CookieSlice {
756 if cookie == aCookie {
757 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
758 "device-id": oFsm.deviceID, "cookie": cookie})
759 cookieMatch = true
760 break //found new cookie - no further search for this requested cookie
761 }
762 }
763 if !cookieMatch {
764 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
765 "device-id": oFsm.deviceID, "cookie": aCookie})
766 //as range works with copies of the slice we have to write to the original slice!!
767 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
768 aCookie)
769 return true, false //flowModified, NoRuleAppend
770 }
771 break // found rule - no further rule search
772 }
773 }
774 if !flowEntryMatch { //it is a new rule
775 return true, true //flowModified, RuleAppend
776 }
777 return false, false //flowNotModified, NoRuleAppend
778}
779
780// VOL-3828 flow config sequence workaround ########### end ##########
781
mpagenko01e726e2020-10-23 09:45:29 +0000782//RemoveUniFlowParams verifies on existence of flow cookie,
783// if found removes cookie from flow cookie list and if this is empty
784// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000785func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000786 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000787 flowCookieMatch := false
788 //mutex protection is required for possible concurrent access to FSM members
789 oFsm.mutexFlowParams.Lock()
790 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000791remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000792 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
793 for i, cookie := range storedUniFlowParams.CookieSlice {
794 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000795 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000796 "device-id": oFsm.deviceID, "cookie": cookie})
mpagenkof1fc3862021-02-16 10:09:52 +0000797 deletedCookie = aCookie
mpagenko01e726e2020-10-23 09:45:29 +0000798 //remove the cookie from the cookie slice and verify it is getting empty
799 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenkof582d6a2021-06-18 15:58:10 +0000800 // had to shift content to function due to sca complexity
801 flowCookieMatch = oFsm.removeRuleComplete(ctx, storedUniFlowParams, aCookie)
mpagenko333846a2021-07-21 12:38:07 +0000802 //persistencyData write is now part of removeRuleComplete() (on success)
mpagenko01e726e2020-10-23 09:45:29 +0000803 } else {
mpagenkof582d6a2021-06-18 15:58:10 +0000804 flowCookieMatch = true
mpagenko01e726e2020-10-23 09:45:29 +0000805 //cut off the requested cookie by slicing out this element
806 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
807 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
808 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000809 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
810 // state transition notification is checked in deviceHandler
811 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000812 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
813 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000814 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000815 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000816 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000817 if deletedCookie == oFsm.delayNewRuleCookie {
818 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
819 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
820 //simply use the first one
821 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
822 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
823 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
824 }
mpagenko333846a2021-07-21 12:38:07 +0000825 //permanently store the modified flow config for reconcile case and immediately write to KvStore
826 if oFsm.pDeviceHandler != nil {
827 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
828 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
829 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
830 return err
831 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000832 }
mpagenko01e726e2020-10-23 09:45:29 +0000833 }
mpagenkof1fc3862021-02-16 10:09:52 +0000834 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000835 }
836 }
mpagenko01e726e2020-10-23 09:45:29 +0000837 } //search all flows
838 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000839 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000840 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
841 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000842 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
843 // state transition notification is checked in deviceHandler
844 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000845 // success indication without the need to write to kvStore (no change)
846 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000847 }
mpagenko01e726e2020-10-23 09:45:29 +0000848 return nil
849 } //unknown cookie
850
851 return nil
852}
853
mpagenkof582d6a2021-06-18 15:58:10 +0000854// removeRuleComplete initiates the complete removal of a VLAN rule (from single cookie element)
mpagenko333846a2021-07-21 12:38:07 +0000855// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000856func (oFsm *UniVlanConfigFsm) removeRuleComplete(ctx context.Context,
857 aUniFlowParams uniVlanFlowParams, aCookie uint64) bool {
858 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
859 var cancelPendingConfig bool = false
860 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
861 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
862 "device-id": oFsm.deviceID})
863 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
864 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
865 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
866 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
867 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
868 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with add-request, just aborting the outstanding add",
869 log.Fields{"device-id": oFsm.deviceID})
870 cancelPendingConfig = true
871 } else {
872 //create a new element for the removeVlanFlow slice
873 loRemoveParams = uniRemoveVlanFlowParams{
874 vlanRuleParams: aUniFlowParams.VlanRuleParams,
875 cookie: aCookie,
876 }
877 loRemoveParams.removeChannel = make(chan bool)
878 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
879 }
880
881 usedTpID := aUniFlowParams.VlanRuleParams.TpID
882 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
883 //at this point it is evident that no flow anymore will refer to a still possibly active Techprofile
884 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
885 if !cancelPendingConfig {
mpagenko7a592192021-07-28 13:32:00 +0000886 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
887 oFsm.mutexFlowParams.Unlock()
mpagenkof582d6a2021-06-18 15:58:10 +0000888 logger.Debugw(ctx, "UniVlanConfigFsm flow removal requested - set TechProfile to-delete", log.Fields{
889 "device-id": oFsm.deviceID})
890 if oFsm.pUniTechProf != nil {
891 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
892 }
mpagenko7a592192021-07-28 13:32:00 +0000893 oFsm.mutexFlowParams.Lock()
mpagenkof582d6a2021-06-18 15:58:10 +0000894 }
895 } else {
896 if !cancelPendingConfig {
897 oFsm.updateTechProfileToDelete(ctx, usedTpID)
898 }
899 }
900 //trigger the FSM to remove the relevant rule
901 if cancelPendingConfig {
902 //as the uniFlow parameters are already stored (for add) but no explicit removal is done anymore
903 // the paramSlice has to be updated with rule-removal, which also then updates numUniFlows
904 //call from 'non-configured' state of the rules
905 if err := oFsm.removeFlowFromParamsSlice(ctx, aCookie, false); err != nil {
906 //something quite inconsistent detected, perhaps just try to recover with FSM reset
907 oFsm.mutexFlowParams.Unlock()
908 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvReset); fsmErr != nil {
909 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
910 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
911 }
912 return false //data base update could not be done, return like cookie not found
913 }
914
915 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
916 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
917 // synchronous FSM 'event/state' functions may rely on this mutex
918 oFsm.mutexFlowParams.Unlock()
919 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
920 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
921 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
922 }
923 oFsm.mutexFlowParams.Lock()
924 return true
925 }
926 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
927 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
928 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
929 "tp-id": loRemoveParams.vlanRuleParams.TpID,
930 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
931 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
932 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
933 // synchronous FSM 'event/state' functions may rely on this mutex
934 oFsm.mutexFlowParams.Unlock()
935 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
936 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
937 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
938 }
939 oFsm.mutexFlowParams.Lock()
940 } // if not in the appropriate state a new entry will be automatically considered later
941 // when the configDone state is reached
942 return true
943}
944
mpagenkof1d21d12021-06-11 13:14:45 +0000945//removeFlowFromParamsSlice removes a flow from stored uniVlanFlowParamsSlice based on the cookie
946// it assumes that adding cookies for this flow (including the actual one to delete) was prevented
947// from the start of the deletion request to avoid to much interference
948// so when called, there can only be one cookie active for this flow
949// requires mutexFlowParams to be locked at call
mpagenkof582d6a2021-06-18 15:58:10 +0000950func (oFsm *UniVlanConfigFsm) removeFlowFromParamsSlice(ctx context.Context, aCookie uint64, aWasConfigured bool) error {
mpagenkof1d21d12021-06-11 13:14:45 +0000951 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice", log.Fields{
952 "device-id": oFsm.deviceID, "cookie": aCookie})
mpagenkof582d6a2021-06-18 15:58:10 +0000953 cookieFound := false
mpagenkof1d21d12021-06-11 13:14:45 +0000954removeFromSlice_loop:
955 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
mpagenkof582d6a2021-06-18 15:58:10 +0000956 // if UniFlowParams exists, cookieSlice should always have at least one element
957 cookieSliceLen := len(storedUniFlowParams.CookieSlice)
958 if cookieSliceLen == 1 {
959 if storedUniFlowParams.CookieSlice[0] == aCookie {
960 cookieFound = true
mpagenkof1d21d12021-06-11 13:14:45 +0000961 }
mpagenkof582d6a2021-06-18 15:58:10 +0000962 } else if cookieSliceLen == 0 {
963 errStr := "UniVlanConfigFsm unexpected cookie slice length 0 - removal in uniVlanFlowParamsSlice aborted"
964 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
965 return errors.New(errStr)
966 } else {
967 errStr := "UniVlanConfigFsm flow removal unexpected cookie slice length, but rule removal continued"
968 logger.Errorw(ctx, errStr, log.Fields{
969 "cookieSliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
970 for _, cookie := range storedUniFlowParams.CookieSlice {
971 if cookie == aCookie {
972 cookieFound = true
973 break
974 }
975 }
976 }
977 if cookieFound {
mpagenkof1d21d12021-06-11 13:14:45 +0000978 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - cookie found", log.Fields{
979 "device-id": oFsm.deviceID, "cookie": aCookie})
980 //remove the actual element from the addVlanFlow slice
981 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
982 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
983 oFsm.numUniFlows = 0 //no more flows
984 oFsm.configuredUniFlow = 0 //no more flows configured
985 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
986 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
987 //request that this profile gets deleted before a new flow add is allowed
988 logger.Debugw(ctx, "UniVlanConfigFsm flow removal from ParamsSlice - no more flows", log.Fields{
989 "device-id": oFsm.deviceID})
990 } else {
991 oFsm.numUniFlows--
992 if aWasConfigured && oFsm.configuredUniFlow > 0 {
993 oFsm.configuredUniFlow--
994 }
995 //cut off the requested flow by slicing out this element
996 oFsm.uniVlanFlowParamsSlice = append(
997 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
998 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
999 "device-id": oFsm.deviceID})
1000 }
1001 break removeFromSlice_loop //found the cookie - no further search for this requested cookie
1002 }
1003 } //search all flows
mpagenkof582d6a2021-06-18 15:58:10 +00001004 if !cookieFound {
1005 errStr := "UniVlanConfigFsm cookie for removal not found, internal counter not updated"
1006 logger.Errorw(ctx, errStr, log.Fields{"device-id": oFsm.deviceID})
1007 return errors.New(errStr)
1008 }
mpagenko333846a2021-07-21 12:38:07 +00001009 //if the cookie was found and removed from uniVlanFlowParamsSlice above now write the modified persistency data
1010 // KVStore update will be done after reaching the requested FSM end state (not immediately here)
1011 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
1012 &oFsm.uniVlanFlowParamsSlice, false); err != nil {
1013 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
1014 return err
1015 }
mpagenkof582d6a2021-06-18 15:58:10 +00001016 return nil
mpagenkof1d21d12021-06-11 13:14:45 +00001017}
1018
1019// requires mutexFlowParams to be locked at call
mpagenkof1fc3862021-02-16 10:09:52 +00001020func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
1021 //here we have to check, if there are still other flows referencing to the actual ProfileId
1022 // before we can request that this profile gets deleted before a new flow add is allowed
1023 tpIDInOtherFlows := false
1024 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
1025 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
1026 tpIDInOtherFlows = true
1027 break // search loop can be left
1028 }
1029 }
1030 if tpIDInOtherFlows {
1031 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
1032 "device-id": oFsm.deviceID, "tp-id": usedTpID})
1033 } else {
mpagenkof1d21d12021-06-11 13:14:45 +00001034 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 +00001035 "device-id": oFsm.deviceID, "tp-id": usedTpID})
mpagenko7a592192021-07-28 13:32:00 +00001036 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1037 oFsm.mutexFlowParams.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001038 if oFsm.pUniTechProf != nil {
1039 //request that this profile gets deleted before a new flow add is allowed
1040 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
1041 }
mpagenko7a592192021-07-28 13:32:00 +00001042 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001043 }
1044}
1045
mpagenkof1d21d12021-06-11 13:14:45 +00001046func (oFsm *UniVlanConfigFsm) enterPreparing(ctx context.Context, e *fsm.Event) {
1047 logger.Debugw(ctx, "UniVlanConfigFsm preparing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001048
1049 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +00001050 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +00001051 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +00001052 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +00001053 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +00001054 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001055 //let the state machine run forward from here directly
1056 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1057 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001058 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1059 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
1060 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001061 // Can't call FSM Event directly, decoupling it
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001062 go func(a_pAFsm *AdapterFsm) {
1063 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
1064 }(pConfigVlanStateAFsm)
1065 return
1066 }
mpagenkof1d21d12021-06-11 13:14:45 +00001067 // Can't call FSM Event directly, decoupling it
1068 go func(a_pAFsm *AdapterFsm) {
1069 _ = a_pAFsm.pFsm.Event(vlanEvPrepareDone)
1070 }(pConfigVlanStateAFsm)
1071 return
1072 }
1073 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1074 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1075 //should never happen, else: recovery would be needed from outside the FSM
1076}
1077
1078func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
1079 logger.Debugw(ctx, "UniVlanConfigFsm start vlan configuration", log.Fields{"device-id": oFsm.deviceID})
1080 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1081 if pConfigVlanStateAFsm != nil {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001082 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001083 //possibly the entry is not valid anymore based on intermediate delete requests
1084 //just a basic protection ...
1085 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
1086 oFsm.mutexFlowParams.Unlock()
1087 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
1088 "device-id": oFsm.deviceID})
1089 // Can't call FSM Event directly, decoupling it
1090 go func(a_pAFsm *AdapterFsm) {
1091 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1092 }(pConfigVlanStateAFsm)
1093 return
1094 }
mpagenko9a304ea2020-12-16 15:54:01 +00001095 //access to uniVlanFlowParamsSlice is done on first element only here per definition
1096 //store the actual rule that shall be worked upon in the following transient states
1097 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001098 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[0].Meter
mpagenko9a304ea2020-12-16 15:54:01 +00001099 tpID := oFsm.actualUniVlanConfigRule.TpID
1100 oFsm.TpIDWaitingFor = tpID
Girish Gowdra24dd1132021-07-06 15:25:40 -07001101 //cmp also usage in EVTOCDE create in omci_cc
1102 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko18eca9c2021-07-26 11:03:45 +00001103 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1104 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1105 // synchronous FSM 'event/state' functions may rely on this mutex
1106 // but it must be released already before calling getTechProfileDone() as it may already be locked
1107 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
Girish Gowdra24dd1132021-07-06 15:25:40 -07001108 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001109 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +00001110 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
1111 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001112 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
Girish Gowdra24dd1132021-07-06 15:25:40 -07001113
mpagenko9a304ea2020-12-16 15:54:01 +00001114 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001115 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
1116 if aPAFsm != nil && aPAFsm.pFsm != nil {
1117 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +00001118 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +00001119 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +00001120 } else {
1121 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +00001122 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +00001123 }
1124 }
mpagenko551a4d42020-12-08 18:09:20 +00001125 }(pConfigVlanStateAFsm, loTechProfDone)
1126 } else {
1127 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1128 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1129 //should never happen, else: recovery would be needed from outside the FSM
1130 return
mpagenkodff5dda2020-08-28 11:52:01 +00001131 }
1132}
1133
dbainbri4d3a0dc2020-12-02 00:33:42 +00001134func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001135 //mutex protection is required for possible concurrent access to FSM members
1136 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +00001137 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +00001138 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001139 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001140 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001141 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001142 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001143 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +00001144 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001145 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001146 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +05301147 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +00001148 }(pConfigVlanStateAFsm)
1149 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001150 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1151 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001152 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
dbainbri4d3a0dc2020-12-02 00:33:42 +00001153 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001154 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001155 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1156 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001157 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001158 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001159 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001160 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001161 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1162 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +00001163 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001164 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +00001165 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001166 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
1167 "ForwardOperation": uint8(0x10), //VID investigation
1168 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +00001169 },
1170 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001171 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001172 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001173 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001174 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001175 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001176 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001177 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001178 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1179 log.Fields{"device-id": oFsm.deviceID})
1180 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1181 if pConfigVlanStateAFsm != nil {
1182 go func(a_pAFsm *AdapterFsm) {
1183 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1184 }(pConfigVlanStateAFsm)
1185 }
1186 return
1187 }
mpagenkodff5dda2020-08-28 11:52:01 +00001188 //accept also nil as (error) return value for writing to LastTx
1189 // - this avoids misinterpretation of new received OMCI messages
1190 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1191 // send shall return (dual format) error code that can be used here for immediate error treatment
1192 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001193 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001194 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001195 }
1196}
1197
dbainbri4d3a0dc2020-12-02 00:33:42 +00001198func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
1199 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001200 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +00001201 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001202 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +00001203 //using the first element in the slice because it's the first flow per definition here
1204 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001205 //This is correct passing scenario
1206 if errEvto == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001207 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001208 tpID := oFsm.actualUniVlanConfigRule.TpID
1209 vlanID := oFsm.actualUniVlanConfigRule.SetVid
mpagenko7a592192021-07-28 13:32:00 +00001210 configuredUniFlows := oFsm.configuredUniFlow
1211 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
1212 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1214 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
mpagenko7a592192021-07-28 13:32:00 +00001215 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": configuredUniFlows})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001216 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001217 vlanID)
1218 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001219 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001220 log.Fields{"device-id": oFsm.deviceID})
1221 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1222 }
1223 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001224 //If this first flow contains a meter, then create TD for related gems.
1225 if oFsm.actualUniVlanConfigMeter != nil {
1226 logger.Debugw(ctx, "Creating Traffic Descriptor", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter})
1227 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1228 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1229 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1230 oFsm.pOnuUniPort.uniID, gemPort)
1231 if errCreateTrafficDescriptor != nil {
1232 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1233 log.Fields{"device-id": oFsm.deviceID})
1234 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1235 }
1236 }
1237 }
1238
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001239 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1240 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1241 }
1242 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001243}
1244
dbainbri4d3a0dc2020-12-02 00:33:42 +00001245func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001246
mpagenkof1d21d12021-06-11 13:14:45 +00001247 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +00001248
mpagenkof1fc3862021-02-16 10:09:52 +00001249 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001250 "device-id": oFsm.deviceID,
mpagenko551a4d42020-12-08 18:09:20 +00001251 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1252 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1253 if pConfigVlanStateAFsm == nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001254 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001255 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1256 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1257 //should never happen, else: recovery would be needed from outside the FSM
1258 return
1259 }
1260 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001261 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1262 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001263 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1264 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1265 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1266 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
mpagenkof1d21d12021-06-11 13:14:45 +00001267 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +00001268 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001269 go func(a_pBaseFsm *fsm.FSM) {
1270 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1271 }(pConfigVlanStateBaseFsm)
1272 return
1273 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001274 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1275 oFsm.configuredUniFlow = oFsm.numUniFlows
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001276 if oFsm.lastFlowToReconcile {
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001277 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
Andrea Campanellaf66ac6e2021-05-24 17:09:20 +02001278 oFsm.pDeviceHandler.setReconcilingFlows(false)
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001279 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1280 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001281 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1282 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00001283 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001284 return
1285 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001286 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001287 if oFsm.configuredUniFlow == 0 {
mpagenkof1d21d12021-06-11 13:14:45 +00001288 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001289 // this is a restart with a complete new flow, we can re-use the initial flow config control
1290 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001291 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001292 go func(a_pBaseFsm *fsm.FSM) {
1293 _ = a_pBaseFsm.Event(vlanEvRenew)
1294 }(pConfigVlanStateBaseFsm)
1295 return
1296 }
1297
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001298 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001299 //store the actual rule that shall be worked upon in the following transient states
mpagenkof1d21d12021-06-11 13:14:45 +00001300 if len(oFsm.uniVlanFlowParamsSlice) < int(oFsm.configuredUniFlow) {
1301 //check introduced after having observed some panic in this processing
1302 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm in ConfigDone - inconsistent counter",
1303 log.Fields{"configuredUniFlow": oFsm.configuredUniFlow,
1304 "sliceLen": len(oFsm.uniVlanFlowParamsSlice), "device-id": oFsm.deviceID})
1305 oFsm.mutexFlowParams.Unlock()
1306 go func(a_pAFsm *AdapterFsm) {
1307 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1308 }(pConfigVlanStateAFsm)
1309 return
1310 }
mpagenko9a304ea2020-12-16 15:54:01 +00001311 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
ozgecanetsia82b91a62021-05-21 18:54:49 +03001312 oFsm.actualUniVlanConfigMeter = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].Meter
mpagenko551a4d42020-12-08 18:09:20 +00001313 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001314 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001315 oFsm.TpIDWaitingFor = tpID
mpagenko18eca9c2021-07-26 11:03:45 +00001316 loSetVlan := oFsm.actualUniVlanConfigRule.SetVid
1317 //attention: take care to release the mutexFlowParams when calling the FSM directly -
1318 // synchronous FSM 'event/state' functions may rely on this mutex
1319 // but it must be released already before calling getTechProfileDone() as it may already be locked
1320 // by the techProfile processing call to VlanFsm.IsFlowRemovePending() (see VOL-4207)
1321 oFsm.mutexFlowParams.Unlock()
mpagenko551a4d42020-12-08 18:09:20 +00001322 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001323 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1324 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
mpagenko18eca9c2021-07-26 11:03:45 +00001325 "set-Vlan": loSetVlan, "tp-id": tpID, "ProfDone": loTechProfDone})
1326
mpagenko9a304ea2020-12-16 15:54:01 +00001327 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001328 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1329 if aTechProfDone {
1330 // let the vlan processing continue with next rule
1331 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1332 } else {
1333 // set to waiting for Techprofile
1334 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1335 }
1336 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001337 return
1338 }
mpagenkof1d21d12021-06-11 13:14:45 +00001339 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001340 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001341 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001342 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1343 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001344 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001345 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001346 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001347 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001348 }
1349}
1350
dbainbri4d3a0dc2020-12-02 00:33:42 +00001351func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001352
1353 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1354 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1355 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1356 go func(a_pBaseFsm *fsm.FSM) {
1357 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1358 }(oFsm.pAdaptFsm.pFsm)
1359 return
1360 }
mpagenko15ff4a52021-03-02 10:09:20 +00001361 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001362 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001363 "recent flow-number": oFsm.configuredUniFlow,
1364 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001365 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001366
mpagenko9a304ea2020-12-16 15:54:01 +00001367 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001368 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001369 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001370 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001371 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001372 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1373 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1374 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1375 // 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 +00001376 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001377 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1378 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001379 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001380 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001382 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001383 "device-id": oFsm.deviceID,
1384 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001385 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001386 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001387
mpagenko01e726e2020-10-23 09:45:29 +00001388 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001389 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1390 oFsm.numVlanFilterEntries = 1
1391 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001392 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001393 Attributes: me.AttributeValueMap{
1394 "VlanFilterList": vtfdFilterList,
1395 "ForwardOperation": uint8(0x10), //VID investigation
1396 "NumberOfEntries": oFsm.numVlanFilterEntries,
1397 },
1398 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001399 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001400 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001401 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001402 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001403 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001404 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001405 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1406 log.Fields{"device-id": oFsm.deviceID})
1407 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1408 if pConfigVlanStateAFsm != nil {
1409 go func(a_pAFsm *AdapterFsm) {
1410 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1411 }(pConfigVlanStateAFsm)
1412 }
1413 return
1414 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001415 //accept also nil as (error) return value for writing to LastTx
1416 // - this avoids misinterpretation of new received OMCI messages
1417 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1418 // send shall return (dual format) error code that can be used here for immediate error treatment
1419 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001420 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001421 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001422 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001423 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1424 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07001425 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(oFsm.actualUniVlanConfigRule.TpID))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001426
dbainbri4d3a0dc2020-12-02 00:33:42 +00001427 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001428 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001429 "device-id": oFsm.deviceID,
1430 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": oFsm.actualUniVlanConfigRule.TpID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001431 // setVid is assumed to be masked already by the caller to 12 bit
1432 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001433 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001434 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001435
1436 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1437 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1438 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001439 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001440
1441 oFsm.numVlanFilterEntries++
1442 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001443 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001444 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001445 "VlanFilterList": vtfdFilterList,
1446 "ForwardOperation": uint8(0x10), //VID investigation
1447 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001448 },
1449 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001450 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001451 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001452 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001453 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001454 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001455 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001456 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1457 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1458 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1459 return
1460 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001461 //accept also nil as (error) return value for writing to LastTx
1462 // - this avoids misinterpretation of new received OMCI messages
1463 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1464 // send shall return (dual format) error code that can be used here for immediate error treatment
1465 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001466 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001467 oFsm.mutexPLastTxMeInstance.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001468 }
1469 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001470 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001471 if err != nil {
mpagenkof1d21d12021-06-11 13:14:45 +00001472 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001473 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001474 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001475 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001476 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001477 go func(a_pBaseFsm *fsm.FSM) {
1478 _ = a_pBaseFsm.Event(vlanEvReset)
1479 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001480 return
1481 }
1482 }
mpagenkof1d21d12021-06-11 13:14:45 +00001483
mpagenkof1fc3862021-02-16 10:09:52 +00001484 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001485 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001486 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001487 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001488 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001489 configuredUniFlow := oFsm.configuredUniFlow
mpagenko7a592192021-07-28 13:32:00 +00001490 // ensure mutexFlowParams not locked before calling some TPProcessing activity (that might already be pending on it)
mpagenko15ff4a52021-03-02 10:09:20 +00001491 oFsm.mutexFlowParams.RUnlock()
1492 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001493 //This is correct passing scenario
1494 if errEvto == nil {
1495 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001496 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001497 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001498 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001499 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001500 "techProfile": tpID, "gemPort": gemPort,
mpagenkof1d21d12021-06-11 13:14:45 +00001501 "vlanID": vlanID, "configuredUniFlow": configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001502 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001503 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001504 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001506 log.Fields{"device-id": oFsm.deviceID})
1507 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1508 }
1509 }
ozgecanetsia82b91a62021-05-21 18:54:49 +03001510 //If this incremental flow contains a meter, then create TD for related gems.
1511 if oFsm.actualUniVlanConfigMeter != nil {
1512 for _, gemPort := range oFsm.pUniTechProf.getBidirectionalGemPortIDsForTP(ctx, oFsm.pOnuUniPort.uniID, tpID) {
1513 logger.Debugw(ctx, "Creating Traffic Descriptor for gem", log.Fields{"device-id": oFsm.deviceID, "meter": oFsm.actualUniVlanConfigMeter, "gem": gemPort})
1514 errCreateTrafficDescriptor := oFsm.createTrafficDescriptor(ctx, oFsm.actualUniVlanConfigMeter, tpID,
1515 oFsm.pOnuUniPort.uniID, gemPort)
1516 if errCreateTrafficDescriptor != nil {
1517 logger.Errorw(ctx, "Create Traffic Descriptor create failed, aborting Ani Config FSM!",
1518 log.Fields{"device-id": oFsm.deviceID})
1519 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1520 }
1521 }
1522 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001523 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1524 }
1525 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001526}
1527
dbainbri4d3a0dc2020-12-02 00:33:42 +00001528func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001529 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001530 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00001531 "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1532 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001533
mpagenkofc4f56e2020-11-04 17:17:49 +00001534 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001535 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.isReadyForOmciConfig()
mpagenko01e726e2020-10-23 09:45:29 +00001536 loVlanEntryClear := uint8(0)
1537 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1538 //shallow copy is sufficient as no reference variables are used within struct
1539 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001540 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001542 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1543 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1544 "device-id": oFsm.deviceID})
1545
1546 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1547 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001548 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001549 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1550 } else {
1551 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1552 if oFsm.numVlanFilterEntries == 1 {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001553 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001554 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1555 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001556 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
Mahir Gunyel6781f962021-05-16 23:30:08 -07001557 log.Fields{"current vlan list": oFsm.vlanFilterList, "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenkof1d21d12021-06-11 13:14:45 +00001558 "device-id": oFsm.deviceID,
1559 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001560 loVlanEntryClear = 1 //full VlanFilter clear request
1561 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001562 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001563 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001564 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001565 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001566 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001567 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1568 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1569 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1570 return
1571 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001572 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001573 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001574 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001575 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001576 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001577 }
mpagenko01e726e2020-10-23 09:45:29 +00001578 } else {
1579 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1580 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001581 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001582 log.Fields{"current vlan list": oFsm.vlanFilterList,
1583 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1584 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1585 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1586 loVlanEntryRmPos = i
1587 break //abort search
1588 }
1589 }
1590 if loVlanEntryRmPos < cVtfdTableSize {
Mahir Gunyel6781f962021-05-16 23:30:08 -07001591 vtfdID, _ := generateANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo), uint16(loRuleParams.TpID))
mpagenko01e726e2020-10-23 09:45:29 +00001592 //valid entry was found - to be eclipsed
1593 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1594 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1595 if i < loVlanEntryRmPos {
1596 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1597 } else if i < (cVtfdTableSize - 1) {
1598 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1599 } else {
1600 vtfdFilterList[i] = 0 //set last byte if needed
1601 }
1602 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001604 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
Mahir Gunyel6781f962021-05-16 23:30:08 -07001605 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID,
1606 "macBpNo": oFsm.pOnuUniPort.macBpNo, "TpID": loRuleParams.TpID})
mpagenko01e726e2020-10-23 09:45:29 +00001607
mpagenkofc4f56e2020-11-04 17:17:49 +00001608 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001609 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001610 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001611 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001612 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001613 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001614 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03001615 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1616 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1617 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1618 return
1619 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001620 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001621 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkofc4f56e2020-11-04 17:17:49 +00001622 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001623 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001624 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001625 }
mpagenko01e726e2020-10-23 09:45:29 +00001626 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001627 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001628 log.Fields{"device-id": oFsm.deviceID})
1629 }
1630 }
1631 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001632 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1633 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001634 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001635 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001636 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001637 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001638 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001639 go func(a_pBaseFsm *fsm.FSM) {
1640 _ = a_pBaseFsm.Event(vlanEvReset)
1641 }(pConfigVlanStateBaseFsm)
1642 return
1643 }
mpagenko01e726e2020-10-23 09:45:29 +00001644 }
1645
mpagenko15ff4a52021-03-02 10:09:20 +00001646 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001647 if loVlanEntryClear == 1 {
1648 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1649 oFsm.numVlanFilterEntries = 0
1650 } else if loVlanEntryClear == 2 {
1651 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1652 // this loop now includes the 0 element on previous last valid entry
1653 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1654 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1655 }
1656 oFsm.numVlanFilterEntries--
1657 }
mpagenko15ff4a52021-03-02 10:09:20 +00001658 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001659 }
1660 }
1661
mpagenkofc4f56e2020-11-04 17:17:49 +00001662 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001664 } else {
1665 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001666 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001667 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001668 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001669 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001670 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001671 }(pConfigVlanStateBaseFsm)
1672 }
mpagenkodff5dda2020-08-28 11:52:01 +00001673}
1674
dbainbri4d3a0dc2020-12-02 00:33:42 +00001675func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001676 var tpID uint8
1677 // Extract the tpID
1678 if len(e.Args) > 0 {
1679 tpID = e.Args[0].(uint8)
1680 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1681 } else {
1682 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1683 }
mpagenko01e726e2020-10-23 09:45:29 +00001684 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001685 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
mpagenkof1d21d12021-06-11 13:14:45 +00001686
mpagenkof582d6a2021-06-18 15:58:10 +00001687 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1688 if pConfigVlanStateAFsm == nil {
1689 logger.Errorw(ctx, "invalid Fsm pointer - unresolvable - abort",
1690 log.Fields{"device-id": oFsm.deviceID})
1691 //would have to be fixed from outside somehow
1692 return
1693 }
1694
mpagenkof1d21d12021-06-11 13:14:45 +00001695 // here we need o finally remove the removed data also from uniVlanFlowParamsSlice and possibly have to
1696 // stop the suspension of a add-activity waiting for the end of removal
mpagenkof582d6a2021-06-18 15:58:10 +00001697 //call from 'configured' state of the rule
1698 if err := oFsm.removeFlowFromParamsSlice(ctx, deletedCookie, true); err != nil {
1699 //something quite inconsistent detected, perhaps just try to recover with FSM reset
1700 oFsm.mutexFlowParams.Unlock()
1701 logger.Errorw(ctx, "UniVlanConfigFsm - could not clear database - abort", log.Fields{"device-id": oFsm.deviceID})
1702 go func(a_pAFsm *AdapterFsm) {
1703 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1704 }(pConfigVlanStateAFsm)
1705 return
1706 }
mpagenkof1d21d12021-06-11 13:14:45 +00001707 if oFsm.uniRemoveFlowsSlice[0].isSuspendedOnAdd {
1708 removeChannel := oFsm.uniRemoveFlowsSlice[0].removeChannel
1709 oFsm.mutexFlowParams.Unlock()
1710 removeChannel <- true
1711 oFsm.mutexFlowParams.Lock()
1712 }
1713
mpagenkof1fc3862021-02-16 10:09:52 +00001714 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1715 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1716 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1717
mpagenko01e726e2020-10-23 09:45:29 +00001718 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1719 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001720 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001721 "device-id": oFsm.deviceID})
1722 } else {
1723 //cut off the actual flow by slicing out the first element
1724 oFsm.uniRemoveFlowsSlice = append(
1725 oFsm.uniRemoveFlowsSlice[:0],
1726 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001727 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001728 "device-id": oFsm.deviceID})
1729 }
1730 oFsm.mutexFlowParams.Unlock()
1731
mpagenkof1fc3862021-02-16 10:09:52 +00001732 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001733 //return to the basic config verification state
mpagenkof582d6a2021-06-18 15:58:10 +00001734 // Can't call FSM Event directly, decoupling it
1735 go func(a_pAFsm *AdapterFsm) {
1736 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
1737 }(pConfigVlanStateAFsm)
Girish Gowdra26a40922021-01-29 17:14:34 -08001738
mpagenkobb47bc22021-04-20 13:29:09 +00001739 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001740 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001741 if deletedCookie == oFsm.delayNewRuleCookie {
1742 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1743 select {
1744 case <-oFsm.chCookieDeleted:
1745 logger.Debug(ctx, "flushed CookieDeleted")
1746 default:
1747 }
1748 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1749 }
mpagenkobb47bc22021-04-20 13:29:09 +00001750 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1751 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1752 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 -08001753 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001754 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1755 oFsm.flowDeleteChannel <- true
1756 oFsm.signalOnFlowDelete = false
1757 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001758 }
mpagenkobb47bc22021-04-20 13:29:09 +00001759 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001760}
1761
dbainbri4d3a0dc2020-12-02 00:33:42 +00001762func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1763 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001764
1765 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1766 if pConfigVlanStateAFsm != nil {
1767 // abort running message processing
1768 fsmAbortMsg := Message{
1769 Type: TestMsg,
1770 Data: TestMessage{
1771 TestMessageVal: AbortMessageProcessing,
1772 },
1773 }
1774 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1775
mpagenko9a304ea2020-12-16 15:54:01 +00001776 //try to restart the FSM to 'disabled'
1777 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001778 go func(a_pAFsm *AdapterFsm) {
1779 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301780 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001781 }
1782 }(pConfigVlanStateAFsm)
1783 }
1784}
1785
dbainbri4d3a0dc2020-12-02 00:33:42 +00001786func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1787 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001788 oFsm.mutexPLastTxMeInstance.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001789 oFsm.pLastTxMeInstance = nil
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001790 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkof1d21d12021-06-11 13:14:45 +00001791
1792 oFsm.mutexFlowParams.RLock()
1793 if oFsm.delayNewRuleCookie != 0 {
1794 // looks like the waiting AddFlow is stuck
1795 oFsm.mutexFlowParams.RUnlock()
1796 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/terminate
1797 oFsm.mutexFlowParams.RLock()
1798 }
1799 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1800 for _, removeUniFlowParams := range oFsm.uniRemoveFlowsSlice {
1801 if removeUniFlowParams.isSuspendedOnAdd {
1802 removeChannel := removeUniFlowParams.removeChannel
1803 logger.Debugw(ctx, "UniVlanConfigFsm flow clear-up - abort suspended rule-add", log.Fields{
1804 "device-id": oFsm.deviceID, "cookie": removeUniFlowParams.cookie})
1805 oFsm.mutexFlowParams.RUnlock()
1806 removeChannel <- false
1807 oFsm.mutexFlowParams.RLock()
1808 }
1809 }
1810 }
1811
mpagenkodff5dda2020-08-28 11:52:01 +00001812 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001813 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1814 // current code removes the complete FSM including all flow/rule configuration done so far
1815 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1816 // maybe a more sophisticated approach is possible without clearing the data
1817 if oFsm.clearPersistency {
1818 //permanently remove possibly stored persistent data
1819 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1820 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001821 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001822 }
1823 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001824 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001825 }
mpagenko9a304ea2020-12-16 15:54:01 +00001826 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001827 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001828 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkof1d21d12021-06-11 13:14:45 +00001829 return
mpagenkodff5dda2020-08-28 11:52:01 +00001830 }
mpagenkof1d21d12021-06-11 13:14:45 +00001831 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001832}
1833
dbainbri4d3a0dc2020-12-02 00:33:42 +00001834func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1835 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001836loop:
1837 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001838 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001839 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001840 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301841 message, ok := <-oFsm.pAdaptFsm.commChan
1842 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001843 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301844 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1845 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1846 break loop
1847 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001848 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301849
1850 switch message.Type {
1851 case TestMsg:
1852 msg, _ := message.Data.(TestMessage)
1853 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001854 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001855 break loop
1856 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001857 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301858 case OMCI:
1859 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001860 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301861 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001862 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301863 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001864 }
1865 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001866 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001867}
1868
dbainbri4d3a0dc2020-12-02 00:33:42 +00001869func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1870 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001871 "msgType": msg.OmciMsg.MessageType})
1872
1873 switch msg.OmciMsg.MessageType {
1874 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001875 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001876 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1877 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001878 return
1879 }
mpagenkodff5dda2020-08-28 11:52:01 +00001880 } //CreateResponseType
1881 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001882 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001883 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1884 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001885 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001886 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001887 return
1888 }
1889 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1890 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001891 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001892 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001893 return
1894 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001895 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001896 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001897 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001898 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001899 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1900 return
1901 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001902 oFsm.mutexPLastTxMeInstance.RLock()
1903 if oFsm.pLastTxMeInstance != nil {
1904 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1905 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1906 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03001907 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile", "GemPortNetworkCtp":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001908 { // let the MultiEntity config proceed by stopping the wait function
1909 oFsm.mutexPLastTxMeInstance.RUnlock()
1910 oFsm.omciMIdsResponseReceived <- true
1911 return
1912 }
1913 default:
1914 {
1915 logger.Warnw(ctx, "Unsupported ME name received!",
1916 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
1917 }
mpagenkodff5dda2020-08-28 11:52:01 +00001918 }
1919 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001920 } else {
1921 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001922 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001923 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001924 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001925 case omci.DeleteResponseType:
1926 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001927 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1928 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001929 return
1930 }
1931 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001932 default:
1933 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001934 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001935 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001936 return
1937 }
1938 }
1939}
1940
dbainbri4d3a0dc2020-12-02 00:33:42 +00001941func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001942 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1943 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001944 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001945 log.Fields{"device-id": oFsm.deviceID})
1946 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1947 oFsm.deviceID)
1948 }
1949 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1950 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001951 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001952 log.Fields{"device-id": oFsm.deviceID})
1953 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1954 oFsm.deviceID)
1955 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001956 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001957 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001958 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001959 "Error": msgObj.Result})
1960 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1961 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1962 oFsm.deviceID)
1963 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001964 oFsm.mutexPLastTxMeInstance.RLock()
1965 if oFsm.pLastTxMeInstance != nil {
1966 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1967 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1968 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1969 switch oFsm.pLastTxMeInstance.GetName() {
1970 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1971 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
ozgecanetsia82b91a62021-05-21 18:54:49 +03001972 "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001973 {
1974 oFsm.mutexPLastTxMeInstance.RUnlock()
1975 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1976 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1977 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1978 } else { // let the MultiEntity config proceed by stopping the wait function
1979 oFsm.omciMIdsResponseReceived <- true
1980 }
1981 return nil
1982 }
1983 default:
1984 {
1985 logger.Warnw(ctx, "Unsupported ME name received!",
1986 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001987 }
1988 }
1989 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001990 } else {
1991 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001992 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00001993 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00001994 return nil
1995}
1996
dbainbri4d3a0dc2020-12-02 00:33:42 +00001997func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001998 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1999 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002001 log.Fields{"device-id": oFsm.deviceID})
2002 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
2003 oFsm.deviceID)
2004 }
2005 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
2006 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002007 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00002008 log.Fields{"device-id": oFsm.deviceID})
2009 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
2010 oFsm.deviceID)
2011 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00002012 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00002013 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002014 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00002015 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
2016 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
2017 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
2018 oFsm.deviceID)
2019 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002020 oFsm.mutexPLastTxMeInstance.RLock()
2021 if oFsm.pLastTxMeInstance != nil {
2022 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
2023 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
2024 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsia82b91a62021-05-21 18:54:49 +03002025 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "TrafficDescriptor":
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002026 { // let the MultiEntity config proceed by stopping the wait function
2027 oFsm.mutexPLastTxMeInstance.RUnlock()
2028 oFsm.omciMIdsResponseReceived <- true
2029 return nil
2030 }
2031 default:
2032 {
2033 logger.Warnw(ctx, "Unsupported ME name received!",
2034 log.Fields{"ME name": oFsm.pLastTxMeInstance.GetName(), "device-id": oFsm.deviceID})
2035 }
mpagenko01e726e2020-10-23 09:45:29 +00002036 }
2037 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002038 } else {
2039 logger.Warnw(ctx, "Pointer to last Tx MeInstance is nil!", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002040 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002041 oFsm.mutexPLastTxMeInstance.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002042 return nil
2043}
2044
dbainbri4d3a0dc2020-12-02 00:33:42 +00002045func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
mpagenkof1d21d12021-06-11 13:14:45 +00002046 oFsm.mutexFlowParams.RLock()
2047 evtocdID := oFsm.evtocdID
2048 oFsm.mutexFlowParams.RUnlock()
2049
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002050 if aFlowEntryNo == 0 {
2051 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002052 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
2053 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00002054 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkof1d21d12021-06-11 13:14:45 +00002055 "EntitytId": strconv.FormatInt(int64(evtocdID), 16),
mpagenkodff5dda2020-08-28 11:52:01 +00002056 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00002057 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002058 associationType := 2 // default to uniPPTP
2059 if oFsm.pOnuUniPort.portType == uniVEIP {
2060 associationType = 10
2061 }
2062 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00002063 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002064 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002065 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002066 "AssociationType": uint8(associationType),
2067 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00002068 },
2069 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002070 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002071 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
2072 true, oFsm.pAdaptFsm.commChan, meParams)
2073 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002074 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002075 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
2076 log.Fields{"device-id": oFsm.deviceID})
2077 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2078 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
2079 }
mpagenkodff5dda2020-08-28 11:52:01 +00002080 //accept also nil as (error) return value for writing to LastTx
2081 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002082 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002083 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002084
2085 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002086 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002087 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002088 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002089 log.Fields{"device-id": oFsm.deviceID})
2090 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2091 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
2092 }
2093
2094 // Set the EVTOCD ME default params
2095 meParams = me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002096 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002097 Attributes: me.AttributeValueMap{
2098 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2099 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
2100 "DownstreamMode": uint8(cDefaultDownstreamMode),
2101 },
2102 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002103 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002104 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2105 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002106 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002107 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002108 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002109 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2110 log.Fields{"device-id": oFsm.deviceID})
2111 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2112 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2113 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002114 //accept also nil as (error) return value for writing to LastTx
2115 // - this avoids misinterpretation of new received OMCI messages
2116 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002117 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002118
2119 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002120 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002121 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002122 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002123 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302124 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002125 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002126 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002127 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00002128
mpagenko551a4d42020-12-08 18:09:20 +00002129 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00002130 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00002131 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00002132 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002133 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002134 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002135 sliceEvtocdRule := make([]uint8, 16)
2136 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2137 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2138 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2139 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2140 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2141
2142 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2143 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2144 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2145 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2146 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2147
2148 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2149 0<<cTreatTTROffset| // Do not pop any tags
2150 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2151 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2152 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2153
2154 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2155 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2156 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2157 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2158
2159 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002160 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002161 Attributes: me.AttributeValueMap{
2162 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2163 },
2164 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002165 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002166 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2167 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002168 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002169 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002170 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002171 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2172 log.Fields{"device-id": oFsm.deviceID})
2173 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2174 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2175 }
mpagenkodff5dda2020-08-28 11:52:01 +00002176 //accept also nil as (error) return value for writing to LastTx
2177 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002178 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002179 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002180
2181 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002182 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002183 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002184 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002185 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302186 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002187 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
2188
mpagenkodff5dda2020-08-28 11:52:01 +00002189 }
2190 } else {
2191 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2192 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00002193 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
2194 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
2195 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
2196 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00002197 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002198 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002199 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002200 sliceEvtocdRule := make([]uint8, 16)
2201 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2202 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2203 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2204 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2205 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2206
2207 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002208 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2209 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00002210 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2211 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2212
2213 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002214 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00002215 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2216 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2217 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2218
2219 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00002220 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
2221 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00002222 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002223 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002224
2225 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002226 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002227 Attributes: me.AttributeValueMap{
2228 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2229 },
2230 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002231 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002232 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2233 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002234 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002235 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002236 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002237 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2238 log.Fields{"device-id": oFsm.deviceID})
2239 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2240 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2241 }
mpagenkodff5dda2020-08-28 11:52:01 +00002242 //accept also nil as (error) return value for writing to LastTx
2243 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002244 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002245 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002246
2247 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002248 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002249 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002250 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002251 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302252 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002253 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00002254 }
2255 } else {
2256 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
2257 { // just for local var's
2258 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002259 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002260 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002261 sliceEvtocdRule := make([]uint8, 16)
2262 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2263 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2264 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2265 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2266 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2267
2268 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2269 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2270 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2271 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2272 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2273
2274 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2275 0<<cTreatTTROffset| // Do not pop any tags
2276 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2277 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2278 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2279
2280 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2281 0<<cTreatPrioOffset| // vlan prio set to 0
2282 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00002283 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00002284 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
2285
mpagenko551a4d42020-12-08 18:09:20 +00002286 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002287 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002288 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002289 Attributes: me.AttributeValueMap{
2290 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2291 },
2292 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002293 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002294 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2295 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002296 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002297 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002298 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002299 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2300 log.Fields{"device-id": oFsm.deviceID})
2301 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2302 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2303 }
mpagenkodff5dda2020-08-28 11:52:01 +00002304 //accept also nil as (error) return value for writing to LastTx
2305 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002306 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002307 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002308
2309 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002310 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002311 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002312 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002313 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302314 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002315 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2316
mpagenkodff5dda2020-08-28 11:52:01 +00002317 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00002318 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00002319 { // just for local var's
2320 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002321 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002322 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00002323 sliceEvtocdRule := make([]uint8, 16)
2324 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2325 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2326 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2327 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2328 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2329
2330 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2331 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2332 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2333 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2334 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2335
2336 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2337 1<<cTreatTTROffset| // pop the prio-tag
2338 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2339 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2340 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2341
mpagenko551a4d42020-12-08 18:09:20 +00002342 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00002343 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2344 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
2345 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00002346 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00002347 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00002348 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002349
2350 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002351 EntityID: evtocdID,
mpagenkodff5dda2020-08-28 11:52:01 +00002352 Attributes: me.AttributeValueMap{
2353 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2354 },
2355 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002356 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002357 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2358 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00002359 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002360 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002361 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002362 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2363 log.Fields{"device-id": oFsm.deviceID})
2364 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2365 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
2366 }
mpagenkodff5dda2020-08-28 11:52:01 +00002367 //accept also nil as (error) return value for writing to LastTx
2368 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00002369 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002370 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002371
2372 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002373 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00002374 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002376 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05302377 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002378 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
2379
mpagenkodff5dda2020-08-28 11:52:01 +00002380 }
2381 } //just for local var's
2382 }
2383 }
2384
mpagenkofc4f56e2020-11-04 17:17:49 +00002385 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002386 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenkof1d21d12021-06-11 13:14:45 +00002387 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00002388 oFsm.configuredUniFlow++ // one (more) flow configured
mpagenkof1d21d12021-06-11 13:14:45 +00002389 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002390 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002391}
2392
dbainbri4d3a0dc2020-12-02 00:33:42 +00002393func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenkof1d21d12021-06-11 13:14:45 +00002394 oFsm.mutexFlowParams.RLock()
2395 evtocdID := oFsm.evtocdID
2396 oFsm.mutexFlowParams.RUnlock()
2397
mpagenko01e726e2020-10-23 09:45:29 +00002398 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2399 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2400 //transparent transmission was set
2401 //perhaps the config is not needed for removal,
2402 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002403 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002404 "device-id": oFsm.deviceID})
2405 sliceEvtocdRule := make([]uint8, 16)
2406 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2407 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2408 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2409 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2410 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2411
2412 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2413 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2414 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2415 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2416 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2417
2418 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2419 0<<cTreatTTROffset| // Do not pop any tags
2420 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2421 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2422 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2423
2424 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2425 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2426 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2427 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2428
2429 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002430 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002431 Attributes: me.AttributeValueMap{
2432 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2433 },
2434 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002435 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002436 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2437 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002438 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002439 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002440 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002441 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2442 log.Fields{"device-id": oFsm.deviceID})
2443 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2444 return
2445 }
mpagenko01e726e2020-10-23 09:45:29 +00002446 //accept also nil as (error) return value for writing to LastTx
2447 // - this avoids misinterpretation of new received OMCI messages
2448 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002449 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002450
2451 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002452 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002453 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002454 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002455 log.Fields{"device-id": oFsm.deviceID})
2456 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2457 return
2458 }
2459 } else {
2460 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
mpagenkof1d21d12021-06-11 13:14:45 +00002461 oFsm.mutexFlowParams.RLock()
mpagenko01e726e2020-10-23 09:45:29 +00002462 if oFsm.acceptIncrementalEvtoOption {
mpagenkof1d21d12021-06-11 13:14:45 +00002463 oFsm.mutexFlowParams.RUnlock()
mpagenko01e726e2020-10-23 09:45:29 +00002464 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002465 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002466 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2467 sliceEvtocdRule := make([]uint8, 16)
2468 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2469 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2470 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2471 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2472 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2473
2474 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2475 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2476 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2477 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2478 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2479
2480 // delete indication for the indicated Filter
2481 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2482 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2483
2484 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002485 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002486 Attributes: me.AttributeValueMap{
2487 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2488 },
2489 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002490 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002491 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2492 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002493 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002494 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002495 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002496 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2497 log.Fields{"device-id": oFsm.deviceID})
2498 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2499 return
2500 }
mpagenko01e726e2020-10-23 09:45:29 +00002501 //accept also nil as (error) return value for writing to LastTx
2502 // - this avoids misinterpretation of new received OMCI messages
2503 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002504 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002505
2506 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002507 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002508 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002509 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002510 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2511 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2512 return
2513 }
2514 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002515 // VOL-3685
2516 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2517 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2518 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2519 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2520 // later when the flow is being re-installed.
2521 // Of course this is applicable to case only where single service (or single tcont) is in use and
2522 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2523 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2524 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
mpagenkof1d21d12021-06-11 13:14:45 +00002525 if oFsm.configuredUniFlow == 1 && !oFsm.acceptIncrementalEvtoOption {
2526 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002527 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002528 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2529 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002530 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002531 EntityID: evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002532 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002533 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002534 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2535 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002536 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002537 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002538 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002539 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2540 log.Fields{"device-id": oFsm.deviceID})
2541 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2542 return
2543 }
mpagenko01e726e2020-10-23 09:45:29 +00002544 //accept also nil as (error) return value for writing to LastTx
2545 // - this avoids misinterpretation of new received OMCI messages
2546 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002547 oFsm.mutexPLastTxMeInstance.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002548
2549 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002550 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002551 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002552 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002553 log.Fields{"device-id": oFsm.deviceID})
2554 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2555 return
2556 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002557 } else {
2558 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2559 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002560 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002561 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
mpagenkof1d21d12021-06-11 13:14:45 +00002562 oFsm.mutexFlowParams.RUnlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002563 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2564 { // just for local var's
2565 // this defines stacking scenario: untagged->singletagged
2566 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2567 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2568 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2569 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002570 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002571 "device-id": oFsm.deviceID})
2572 sliceEvtocdRule := make([]uint8, 16)
2573 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2574 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2575 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2576 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2577 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002578
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002579 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2580 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2581 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2582 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2583 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002584
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002585 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2586 0<<cTreatTTROffset| // Do not pop any tags
2587 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2588 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2589 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002590
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002591 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2592 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2593 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2594 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002595
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002596 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002597 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002598 Attributes: me.AttributeValueMap{
2599 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2600 },
2601 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07002602 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002603 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2604 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002605 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002606 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07002607 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002608 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2609 log.Fields{"device-id": oFsm.deviceID})
2610 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2611 return
2612 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002613 //accept also nil as (error) return value for writing to LastTx
2614 // - this avoids misinterpretation of new received OMCI messages
2615 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07002616 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002617
2618 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002619 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002620 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002621 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002622 log.Fields{"device-id": oFsm.deviceID})
2623 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2624 return
2625 }
2626 } // just for local var's
2627 { // just for local var's
2628 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002629 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002630 "device-id": oFsm.deviceID})
2631 sliceEvtocdRule := make([]uint8, 16)
2632 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2633 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2634 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2635 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2636 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2637
2638 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2639 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2640 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2641 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2642 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2643
2644 // delete indication for the indicated Filter
2645 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2646 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2647
2648 meParams := me.ParamData{
mpagenkof1d21d12021-06-11 13:14:45 +00002649 EntityID: evtocdID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002650 Attributes: me.AttributeValueMap{
2651 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2652 },
2653 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002654 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002655 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2656 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002657 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002658 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002659 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002660 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2661 log.Fields{"device-id": oFsm.deviceID})
2662 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2663 return
2664 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002665 //accept also nil as (error) return value for writing to LastTx
2666 // - this avoids misinterpretation of new received OMCI messages
2667 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002668 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002669
2670 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002671 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002672 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002673 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002674 log.Fields{"device-id": oFsm.deviceID})
2675 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2676 return
2677 }
mpagenko01e726e2020-10-23 09:45:29 +00002678 }
2679 } //just for local var's
2680 }
2681 }
mpagenkofc4f56e2020-11-04 17:17:49 +00002682 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002683 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002684 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002685}
2686
dbainbri4d3a0dc2020-12-02 00:33:42 +00002687func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002688 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002689 if oFsm.isCanceled {
2690 // FSM already canceled before entering wait
2691 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2692 oFsm.mutexIsAwaitingResponse.Unlock()
2693 return fmt.Errorf(cErrWaitAborted)
2694 }
mpagenko7d6bb022021-03-11 15:07:55 +00002695 oFsm.isAwaitingResponse = true
2696 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002697 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302698 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002699 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002700 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002701 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002702 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002703 oFsm.mutexIsAwaitingResponse.Lock()
2704 oFsm.isAwaitingResponse = false
2705 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002706 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002707 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302708 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002709 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002710 oFsm.mutexIsAwaitingResponse.Lock()
2711 oFsm.isAwaitingResponse = false
2712 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002713 return nil
2714 }
mpagenko7d6bb022021-03-11 15:07:55 +00002715 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002716 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002717 oFsm.mutexIsAwaitingResponse.Lock()
2718 oFsm.isAwaitingResponse = false
2719 oFsm.mutexIsAwaitingResponse.Unlock()
2720 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002721 }
2722}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002723
mpagenko551a4d42020-12-08 18:09:20 +00002724func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002725 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002726 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002727 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002728 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002729 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002730 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002731 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002732 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2733 }
2734
dbainbri4d3a0dc2020-12-02 00:33:42 +00002735 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002736 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002737 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002738 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002739 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002740 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2741 }
2742
dbainbri4d3a0dc2020-12-02 00:33:42 +00002743 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002744 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002745 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002746 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002747 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002748 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2749 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002750 macBpCdEID, errMacBpCdEID := generateMcastANISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
2751 if errMacBpCdEID != nil {
2752 logger.Errorw(ctx, "MulticastMacBridgePortConfigData entity id generation failed, aborting AniConfig FSM!",
2753 log.Fields{"device-id": oFsm.deviceID})
2754 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2755 return fmt.Errorf("generateMcastANISideMBPCDEID responseError %s, error %s", oFsm.deviceID, errMacBpCdEID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002756
Mahir Gunyel6781f962021-05-16 23:30:08 -07002757 }
2758 logger.Debugw(ctx, "UniVlanConfigFsm set macBpCdEID for mcast", log.Fields{
2759 "EntitytId": strconv.FormatInt(int64(macBpCdEID), 16), "macBpNo": oFsm.pOnuUniPort.macBpNo,
2760 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002761 meParams := me.ParamData{
Mahir Gunyel6781f962021-05-16 23:30:08 -07002762 EntityID: macBpCdEID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002763 Attributes: me.AttributeValueMap{
2764 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2765 "PortNum": 0xf0, //fixed unique ANI side indication
2766 "TpType": 6, //MCGemIWTP
2767 "TpPointer": multicastGemPortID,
2768 },
2769 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002770 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002771 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2772 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2773 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002774 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002775 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2776 log.Fields{"device-id": oFsm.deviceID})
2777 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2778 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2779 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002780 //accept also nil as (error) return value for writing to LastTx
2781 // - this avoids misinterpretation of new received OMCI messages
2782 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002783 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002784 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002785 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002786 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002787 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002788 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002789 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2790 }
2791
2792 // ==> Start creating VTFD for mcast vlan
2793
2794 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2795 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
Mahir Gunyel6781f962021-05-16 23:30:08 -07002796 mcastVtfdID := macBpCdEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002797
dbainbri4d3a0dc2020-12-02 00:33:42 +00002798 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002799 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2800 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2801 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2802
2803 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2804 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2805 // new vlan associated with a different TP.
2806 vtfdFilterList[0] = uint16(vlanID)
2807
2808 meParams = me.ParamData{
2809 EntityID: mcastVtfdID,
2810 Attributes: me.AttributeValueMap{
2811 "VlanFilterList": vtfdFilterList,
2812 "ForwardOperation": uint8(0x10), //VID investigation
2813 "NumberOfEntries": oFsm.numVlanFilterEntries,
2814 },
2815 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002816 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002817 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2818 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2819 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002820 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002821 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2822 log.Fields{"device-id": oFsm.deviceID})
2823 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2824 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2825 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002826 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002827 oFsm.mutexPLastTxMeInstance.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00002828 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002829 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002830 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002831 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002832 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002833 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2834 }
2835
2836 return nil
2837}
2838
dbainbri4d3a0dc2020-12-02 00:33:42 +00002839func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002840 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002841 if err != nil {
Mahir Gunyel6781f962021-05-16 23:30:08 -07002842 logger.Errorw(ctx, "error generrating me instance id",
2843 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002844 return err
2845 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002846 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastSubscriberConfigInfo",
2847 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002848 meParams := me.ParamData{
2849 EntityID: instID,
2850 Attributes: me.AttributeValueMap{
2851 "MeType": 0,
2852 //Direct reference to the Operation profile
2853 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002854 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002855 },
2856 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002857 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002858 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2859 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002860 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002861 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002862 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002863 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2864 log.Fields{"device-id": oFsm.deviceID})
2865 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2866 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2867 oFsm.deviceID, err)
2868 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002869 //accept also nil as (error) return value for writing to LastTx
2870 // - this avoids misinterpretation of new received OMCI messages
2871 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002872 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002873 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002874 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002875 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002876 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002877 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2878 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2879 }
2880 return nil
2881}
2882
dbainbri4d3a0dc2020-12-02 00:33:42 +00002883func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002884 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002885 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002886 logger.Errorw(ctx, "error generating me instance id",
2887 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002888 return err
2889 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002890 logger.Debugw(ctx, "UniVlanConfigFsm create MulticastOperationProfile",
2891 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002892 meParams := me.ParamData{
2893 EntityID: instID,
2894 Attributes: me.AttributeValueMap{
2895 "IgmpVersion": 2,
2896 "IgmpFunction": 0,
2897 //0 means false
2898 "ImmediateLeave": 0,
2899 "Robustness": 2,
2900 "QuerierIp": 0,
2901 "QueryInterval": 125,
2902 "QuerierMaxResponseTime": 100,
2903 "LastMemberResponseTime": 10,
2904 //0 means false
2905 "UnauthorizedJoinBehaviour": 0,
2906 },
2907 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002908 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002909 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2910 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002911 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002912 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002913 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002914 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2915 log.Fields{"device-id": oFsm.deviceID})
2916 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2917 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2918 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002919 //accept also nil as (error) return value for writing to LastTx
2920 // - this avoids misinterpretation of new received OMCI messages
2921 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002922 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002923 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002924 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002925 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002926 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002927 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002928 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002929 }
2930 return nil
2931}
2932
dbainbri4d3a0dc2020-12-02 00:33:42 +00002933func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002934 instID, err := generateUNISideMBPCDEID(uint16(oFsm.pOnuUniPort.macBpNo))
ozgecanetsia5c88b762021-03-23 10:27:15 +03002935 if err != nil {
ozgecanetsia72e1c9f2021-05-26 17:26:29 +03002936 logger.Errorw(ctx, "error generating me instance id",
2937 log.Fields{"device-id": oFsm.deviceID, "error": err})
ozgecanetsia5c88b762021-03-23 10:27:15 +03002938 return err
2939 }
Mahir Gunyel6781f962021-05-16 23:30:08 -07002940 logger.Debugw(ctx, "UniVlanConfigFsm set MulticastOperationProfile",
2941 log.Fields{"device-id": oFsm.deviceID, "EntityId": instID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002942 //TODO check that this is correct
2943 // Table control
2944 //setCtrl = 1
2945 //rowPartId = 0
2946 //test = 0
2947 //rowKey = 0
2948 tableCtrlStr := "0100000000000000"
2949 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002950 dynamicAccessCL := make([]uint8, 24)
2951 copy(dynamicAccessCL, tableCtrl)
2952 //Multicast GemPortId
2953 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2954 // python version waits for installation of flows, see line 723 onward of
2955 // brcm_openomci_onu_handler.py
2956 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2957 //Source IP all to 0
2958 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2959 //TODO start and end are hardcoded, get from TP
2960 // Destination IP address start of range
2961 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2962 // Destination IP address end of range
2963 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2964 //imputed group bandwidth
2965 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2966
2967 meParams := me.ParamData{
2968 EntityID: instID,
2969 Attributes: me.AttributeValueMap{
2970 "DynamicAccessControlListTable": dynamicAccessCL,
2971 },
2972 }
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002973 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002974 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2975 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002976 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002977 if err != nil {
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002978 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab36ed572021-04-01 10:38:48 +03002979 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2980 log.Fields{"device-id": oFsm.deviceID})
2981 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2982 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2983 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002984 //accept also nil as (error) return value for writing to LastTx
2985 // - this avoids misinterpretation of new received OMCI messages
2986 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt0da7e6f2021-05-12 13:08:43 +00002987 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002988 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002989 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002990 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002991 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002992 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002993 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002994 }
2995 return nil
2996}
Girish Gowdra26a40922021-01-29 17:14:34 -08002997
ozgecanetsia82b91a62021-05-21 18:54:49 +03002998func (oFsm *UniVlanConfigFsm) createTrafficDescriptor(ctx context.Context, aMeter *voltha.OfpMeterConfig,
2999 tpID uint8, uniID uint8, gemPortID uint16) error {
3000 logger.Infow(ctx, "Starting create traffic descriptor", log.Fields{"device-id": oFsm.deviceID, "uniID": uniID, "tpID": tpID})
3001 // uniTPKey generate id to Traffic Descriptor ME. We need to create two of them. They should be unique. Because of that
3002 // I created unique TD ID by flow direction.
3003 // TODO! Traffic descriptor ME ID will check
3004 trafficDescriptorID := gemPortID
3005 if aMeter == nil {
3006 return fmt.Errorf("meter not found %s", oFsm.deviceID)
3007 }
3008 trafficShapingInfo, err := meters.GetTrafficShapingInfo(ctx, aMeter)
3009 if err != nil {
3010 logger.Errorw(ctx, "Traffic Shaping Info get failed", log.Fields{"device-id": oFsm.deviceID})
3011 return err
3012 }
3013 cir := trafficShapingInfo.Cir + trafficShapingInfo.Gir
3014 cbs := trafficShapingInfo.Cbs
3015 pir := trafficShapingInfo.Pir
3016 pbs := trafficShapingInfo.Pbs
3017
3018 logger.Infow(ctx, "cir-pir-cbs-pbs", log.Fields{"device-id": oFsm.deviceID, "cir": cir, "pir": pir, "cbs": cbs, "pbs": pbs})
3019 meParams := me.ParamData{
3020 EntityID: trafficDescriptorID,
3021 Attributes: me.AttributeValueMap{
3022 "Cir": cir,
3023 "Pir": pir,
3024 "Cbs": cbs,
3025 "Pbs": pbs,
3026 "ColourMode": 1,
3027 "IngressColourMarking": 3,
3028 "EgressColourMarking": 3,
3029 "MeterType": 1,
3030 },
3031 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003032 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003033 meInstance, errCreateTD := oFsm.pOmciCC.sendCreateTDVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
3034 true, oFsm.pAdaptFsm.commChan, meParams)
3035 if errCreateTD != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003036 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003037 logger.Errorw(ctx, "Traffic Descriptor create failed", log.Fields{"device-id": oFsm.deviceID})
3038 return err
3039 }
3040 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003041 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003042 err = oFsm.waitforOmciResponse(ctx)
3043 if err != nil {
3044 logger.Errorw(ctx, "Traffic Descriptor create failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3045 return err
3046 }
3047
3048 err = oFsm.setTrafficDescriptorToGemPortNWCTP(ctx, gemPortID)
3049 if err != nil {
3050 logger.Errorw(ctx, "Traffic Descriptor set failed to Gem Port Network CTP, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3051 return err
3052 }
3053 logger.Infow(ctx, "Set TD Info to GemPortNWCTP successfully", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID, "td-id": trafficDescriptorID})
3054
3055 return nil
3056}
3057
3058func (oFsm *UniVlanConfigFsm) setTrafficDescriptorToGemPortNWCTP(ctx context.Context, gemPortID uint16) error {
3059 logger.Debugw(ctx, "Starting Set Traffic Descriptor to GemPortNWCTP", log.Fields{"device-id": oFsm.deviceID, "gem-port-id": gemPortID})
3060 meParams := me.ParamData{
3061 EntityID: gemPortID,
3062 Attributes: me.AttributeValueMap{
3063 "TrafficManagementPointerForUpstream": gemPortID,
3064 },
3065 }
Girish Gowdra754ffb12021-06-30 16:30:12 -07003066 oFsm.mutexPLastTxMeInstance.Lock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003067 meInstance, err := oFsm.pOmciCC.sendSetGemNCTPVar(log.WithSpanFromContext(context.TODO(), ctx),
3068 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
3069 if err != nil {
Girish Gowdra754ffb12021-06-30 16:30:12 -07003070 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003071 logger.Errorw(ctx, "GemNCTP set failed", log.Fields{"device-id": oFsm.deviceID})
3072 return err
3073 }
3074 oFsm.pLastTxMeInstance = meInstance
Girish Gowdra754ffb12021-06-30 16:30:12 -07003075 oFsm.mutexPLastTxMeInstance.Unlock()
ozgecanetsia82b91a62021-05-21 18:54:49 +03003076 err = oFsm.waitforOmciResponse(ctx)
3077 if err != nil {
3078 logger.Errorw(ctx, "Upstream Traffic Descriptor set failed, aborting VlanConfig FSM!", log.Fields{"device-id": oFsm.deviceID})
3079 return err
3080 }
3081 return nil
3082}
3083
Girish Gowdra26a40922021-01-29 17:14:34 -08003084// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00003085func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
3086 oFsm.mutexFlowParams.Lock()
3087 defer oFsm.mutexFlowParams.Unlock()
3088 if len(oFsm.uniRemoveFlowsSlice) > 0 {
3089 //flow removal is still ongoing/pending
3090 oFsm.signalOnFlowDelete = true
3091 oFsm.flowDeleteChannel = aFlowDeleteChannel
3092 return true
3093 }
3094 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08003095}