blob: c0dced5233624d7330fd6b96cb3c729b400f070b [file] [log] [blame]
mpagenkodff5dda2020-08-28 11:52:01 +00001/*
2 * Copyright 2020-present Open Networking Foundation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17//Package adaptercoreonu provides the utility for onu devices, flows and statistics
18package adaptercoreonu
19
20import (
21 "context"
22 "encoding/binary"
Andrea Campanella6515c582020-10-05 11:25:00 +020023 "fmt"
ozgecanetsiab5000ef2020-11-27 14:38:20 +030024 "net"
mpagenkodff5dda2020-08-28 11:52:01 +000025 "strconv"
Holger Hildebrandt394c5522020-09-11 11:23:01 +000026 "sync"
mpagenkodff5dda2020-08-28 11:52:01 +000027 "time"
28
mpagenko01e726e2020-10-23 09:45:29 +000029 gp "github.com/google/gopacket"
mpagenkodff5dda2020-08-28 11:52:01 +000030 "github.com/looplab/fsm"
31 "github.com/opencord/omci-lib-go"
32 me "github.com/opencord/omci-lib-go/generated"
dbainbri4d3a0dc2020-12-02 00:33:42 +000033 "github.com/opencord/voltha-lib-go/v4/pkg/log"
34 of "github.com/opencord/voltha-protos/v4/go/openflow_13"
mpagenkodff5dda2020-08-28 11:52:01 +000035)
36
37const (
38 // internal predefined values
39 cDefaultDownstreamMode = 0
40 cDefaultTpid = 0x8100
mpagenko01e726e2020-10-23 09:45:29 +000041 cVtfdTableSize = 12 //as per G.988
42 cMaxAllowedFlows = cVtfdTableSize //which might be under discussion, for the moment connected to limit of VLAN's within VTFD
mpagenkodff5dda2020-08-28 11:52:01 +000043)
44
45const (
mpagenkof1fc3862021-02-16 10:09:52 +000046 // internal offsets for requestEvent according to definition in onu_device_entry::OnuDeviceEvent
47 cDeviceEventOffsetAddWithKvStore = 0 //OmciVlanFilterAddDone - OmciVlanFilterAddDone cannot use because of lint
48 cDeviceEventOffsetAddNoKvStore = OmciVlanFilterAddDoneNoKvStore - OmciVlanFilterAddDone
49 cDeviceEventOffsetRemoveWithKvStore = OmciVlanFilterRemDone - OmciVlanFilterAddDone
50 cDeviceEventOffsetRemoveNoKvStore = OmciVlanFilterRemDoneNoKvStore - OmciVlanFilterAddDone
51)
52
53const (
mpagenkodff5dda2020-08-28 11:52:01 +000054 // bit mask offsets for EVTOCD VlanTaggingOperationTable related to 32 bits (4 bytes)
55 cFilterPrioOffset = 28
56 cFilterVidOffset = 15
57 cFilterTpidOffset = 12
58 cFilterEtherTypeOffset = 0
59 cTreatTTROffset = 30
60 cTreatPrioOffset = 16
61 cTreatVidOffset = 3
62 cTreatTpidOffset = 0
63)
64const (
65 // byte offsets for EVTOCD VlanTaggingOperationTable related to overall 16 byte size with slice byte 0 as first Byte (MSB)
66 cFilterOuterOffset = 0
67 cFilterInnerOffset = 4
68 cTreatOuterOffset = 8
69 cTreatInnerOffset = 12
70)
71const (
72 // basic values used within EVTOCD VlanTaggingOperationTable in respect to their bitfields
73 cPrioIgnoreTag uint32 = 15
74 cPrioDefaultFilter uint32 = 14
75 cPrioDoNotFilter uint32 = 8
76 cDoNotFilterVid uint32 = 4096
77 cDoNotFilterTPID uint32 = 0
78 cDoNotFilterEtherType uint32 = 0
79 cDoNotAddPrio uint32 = 15
80 cCopyPrioFromInner uint32 = 8
Himani Chawla4d908332020-08-31 12:30:20 +053081 //cDontCarePrio uint32 = 0
mpagenkodff5dda2020-08-28 11:52:01 +000082 cDontCareVid uint32 = 0
83 cDontCareTpid uint32 = 0
84 cSetOutputTpidCopyDei uint32 = 4
85)
86
87const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +000088 // events of config UNI port VLAN FSM
mpagenko535d6ef2021-02-26 13:15:34 +000089 vlanEvStart = "vlanEvStart"
90 vlanEvWaitTechProf = "vlanEvWaitTechProf"
91 vlanEvCancelOutstandingConfig = "vlanEvCancelOutstandingConfig"
92 vlanEvContinueConfig = "vlanEvContinueConfig"
93 vlanEvStartConfig = "vlanEvStartConfig"
94 vlanEvRxConfigVtfd = "vlanEvRxConfigVtfd"
95 vlanEvRxConfigEvtocd = "vlanEvRxConfigEvtocd"
96 vlanEvWaitTPIncr = "vlanEvWaitTPIncr"
97 vlanEvIncrFlowConfig = "vlanEvIncrFlowConfig"
98 vlanEvRenew = "vlanEvRenew"
99 vlanEvRemFlowConfig = "vlanEvRemFlowConfig"
100 vlanEvRemFlowDone = "vlanEvRemFlowDone"
101 vlanEvFlowDataRemoved = "vlanEvFlowDataRemoved"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000102 //vlanEvTimeoutSimple = "vlanEvTimeoutSimple"
103 //vlanEvTimeoutMids = "vlanEvTimeoutMids"
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000104 vlanEvReset = "vlanEvReset"
105 vlanEvRestart = "vlanEvRestart"
106 vlanEvSkipOmciConfig = "vlanEvSkipOmciConfig"
107 vlanEvSkipIncFlowConfig = "vlanEvSkipIncFlowConfig"
mpagenkodff5dda2020-08-28 11:52:01 +0000108)
mpagenko01e726e2020-10-23 09:45:29 +0000109
mpagenkodff5dda2020-08-28 11:52:01 +0000110const (
Holger Hildebrandt10d98192021-01-27 15:29:31 +0000111 // states of config UNI port VLAN FSM
mpagenkodff5dda2020-08-28 11:52:01 +0000112 vlanStDisabled = "vlanStDisabled"
113 vlanStStarting = "vlanStStarting"
114 vlanStWaitingTechProf = "vlanStWaitingTechProf"
115 vlanStConfigVtfd = "vlanStConfigVtfd"
116 vlanStConfigEvtocd = "vlanStConfigEvtocd"
117 vlanStConfigDone = "vlanStConfigDone"
mpagenko551a4d42020-12-08 18:09:20 +0000118 vlanStIncrFlowWaitTP = "vlanStIncrFlowWaitTP"
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000119 vlanStConfigIncrFlow = "vlanStConfigIncrFlow"
mpagenko01e726e2020-10-23 09:45:29 +0000120 vlanStRemoveFlow = "vlanStRemoveFlow"
mpagenkodff5dda2020-08-28 11:52:01 +0000121 vlanStCleanupDone = "vlanStCleanupDone"
122 vlanStResetting = "vlanStResetting"
123)
mpagenkof1fc3862021-02-16 10:09:52 +0000124const cVlanFsmIdleState = vlanStConfigDone // state where no OMCI activity is done (for a longer time)
125const cVlanFsmConfiguredState = vlanStConfigDone // state that indicates that at least some valid user related VLAN configuration should exist
mpagenkodff5dda2020-08-28 11:52:01 +0000126
mpagenko01e726e2020-10-23 09:45:29 +0000127type uniVlanRuleParams struct {
mpagenko551a4d42020-12-08 18:09:20 +0000128 TpID uint8 `json:"tp_id"`
mpagenko01e726e2020-10-23 09:45:29 +0000129 MatchVid uint32 `json:"match_vid"` //use uint32 types for allowing immediate bitshifting
130 MatchPcp uint32 `json:"match_pcp"`
131 TagsToRemove uint32 `json:"tags_to_remove"`
132 SetVid uint32 `json:"set_vid"`
133 SetPcp uint32 `json:"set_pcp"`
134}
135
136type uniVlanFlowParams struct {
137 CookieSlice []uint64 `json:"cookie_slice"`
138 VlanRuleParams uniVlanRuleParams `json:"vlan_rule_params"`
139}
140
141type uniRemoveVlanFlowParams struct {
142 cookie uint64 //just the last cookie valid for removal
143 vlanRuleParams uniVlanRuleParams
144}
145
mpagenkobb47bc22021-04-20 13:29:09 +0000146//UniVlanConfigFsm defines the structure for the state machine for configuration of the VLAN related setting via OMCI
147// builds upon 'VLAN rules' that are derived from multiple flows
mpagenkodff5dda2020-08-28 11:52:01 +0000148type UniVlanConfigFsm struct {
Himani Chawla6d2ae152020-09-02 13:11:20 +0530149 pDeviceHandler *deviceHandler
mpagenko01e726e2020-10-23 09:45:29 +0000150 deviceID string
Himani Chawla6d2ae152020-09-02 13:11:20 +0530151 pOmciCC *omciCC
152 pOnuUniPort *onuUniPort
153 pUniTechProf *onuUniTechProf
154 pOnuDB *onuDeviceDB
mpagenkodff5dda2020-08-28 11:52:01 +0000155 requestEvent OnuDeviceEvent
156 omciMIdsResponseReceived chan bool //seperate channel needed for checking multiInstance OMCI message responses
157 pAdaptFsm *AdapterFsm
158 acceptIncrementalEvtoOption bool
mpagenko2418ab02020-11-12 12:58:06 +0000159 clearPersistency bool
mpagenkocf48e452021-04-23 09:23:00 +0000160 isCanceled bool
mpagenko7d6bb022021-03-11 15:07:55 +0000161 isAwaitingResponse bool
162 mutexIsAwaitingResponse sync.RWMutex
mpagenko551a4d42020-12-08 18:09:20 +0000163 mutexFlowParams sync.RWMutex
mpagenkobb47bc22021-04-20 13:29:09 +0000164 chCookieDeleted chan bool //channel to indicate that a specific cookie (related to the active rule) was deleted
mpagenko9a304ea2020-12-16 15:54:01 +0000165 actualUniVlanConfigRule uniVlanRuleParams
mpagenko01e726e2020-10-23 09:45:29 +0000166 uniVlanFlowParamsSlice []uniVlanFlowParams
167 uniRemoveFlowsSlice []uniRemoveVlanFlowParams
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000168 numUniFlows uint8 // expected number of flows should be less than 12
169 configuredUniFlow uint8
mpagenko01e726e2020-10-23 09:45:29 +0000170 numRemoveFlows uint8
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000171 numVlanFilterEntries uint8
mpagenko01e726e2020-10-23 09:45:29 +0000172 vlanFilterList [cVtfdTableSize]uint16
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000173 evtocdID uint16
mpagenko01e726e2020-10-23 09:45:29 +0000174 pLastTxMeInstance *me.ManagedEntity
mpagenkofc4f56e2020-11-04 17:17:49 +0000175 requestEventOffset uint8
mpagenko551a4d42020-12-08 18:09:20 +0000176 TpIDWaitingFor uint8
mpagenkobb47bc22021-04-20 13:29:09 +0000177 signalOnFlowDelete bool
178 flowDeleteChannel chan<- bool
mpagenkof1fc3862021-02-16 10:09:52 +0000179 //cookie value that indicates that a rule to add is delayed by waiting for deletion of some other existing rule with the same cookie
180 delayNewRuleCookie uint64
mpagenkodff5dda2020-08-28 11:52:01 +0000181}
182
mpagenko01e726e2020-10-23 09:45:29 +0000183//NewUniVlanConfigFsm is the 'constructor' for the state machine to config the PON ANI ports
184// of ONU UNI ports via OMCI
dbainbri4d3a0dc2020-12-02 00:33:42 +0000185func NewUniVlanConfigFsm(ctx context.Context, apDeviceHandler *deviceHandler, apDevOmciCC *omciCC, apUniPort *onuUniPort,
mpagenko551a4d42020-12-08 18:09:20 +0000186 apUniTechProf *onuUniTechProf, apOnuDB *onuDeviceDB, aTechProfileID uint8,
mpagenko01e726e2020-10-23 09:45:29 +0000187 aRequestEvent OnuDeviceEvent, aName string, aCommChannel chan Message, aAcceptIncrementalEvto bool,
188 aCookieSlice []uint64, aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) *UniVlanConfigFsm {
mpagenkodff5dda2020-08-28 11:52:01 +0000189 instFsm := &UniVlanConfigFsm{
190 pDeviceHandler: apDeviceHandler,
mpagenko01e726e2020-10-23 09:45:29 +0000191 deviceID: apDeviceHandler.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +0000192 pOmciCC: apDevOmciCC,
193 pOnuUniPort: apUniPort,
194 pUniTechProf: apUniTechProf,
195 pOnuDB: apOnuDB,
mpagenkodff5dda2020-08-28 11:52:01 +0000196 requestEvent: aRequestEvent,
197 acceptIncrementalEvtoOption: aAcceptIncrementalEvto,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000198 numUniFlows: 0,
199 configuredUniFlow: 0,
mpagenko01e726e2020-10-23 09:45:29 +0000200 numRemoveFlows: 0,
mpagenko2418ab02020-11-12 12:58:06 +0000201 clearPersistency: true,
mpagenkodff5dda2020-08-28 11:52:01 +0000202 }
203
mpagenko01e726e2020-10-23 09:45:29 +0000204 instFsm.pAdaptFsm = NewAdapterFsm(aName, instFsm.deviceID, aCommChannel)
mpagenkodff5dda2020-08-28 11:52:01 +0000205 if instFsm.pAdaptFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000206 logger.Errorw(ctx, "UniVlanConfigFsm's AdapterFsm could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000207 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000208 return nil
209 }
mpagenkodff5dda2020-08-28 11:52:01 +0000210 instFsm.pAdaptFsm.pFsm = fsm.NewFSM(
211 vlanStDisabled,
212 fsm.Events{
213 {Name: vlanEvStart, Src: []string{vlanStDisabled}, Dst: vlanStStarting},
214 {Name: vlanEvWaitTechProf, Src: []string{vlanStStarting}, Dst: vlanStWaitingTechProf},
mpagenko535d6ef2021-02-26 13:15:34 +0000215 {Name: vlanEvCancelOutstandingConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000216 {Name: vlanEvContinueConfig, Src: []string{vlanStWaitingTechProf}, Dst: vlanStConfigVtfd},
217 {Name: vlanEvStartConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigVtfd},
218 {Name: vlanEvRxConfigVtfd, Src: []string{vlanStConfigVtfd}, Dst: vlanStConfigEvtocd},
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000219 {Name: vlanEvRxConfigEvtocd, Src: []string{vlanStConfigEvtocd, vlanStConfigIncrFlow},
220 Dst: vlanStConfigDone},
mpagenko551a4d42020-12-08 18:09:20 +0000221 {Name: vlanEvRenew, Src: []string{vlanStConfigDone}, Dst: vlanStStarting},
222 {Name: vlanEvWaitTPIncr, Src: []string{vlanStConfigDone}, Dst: vlanStIncrFlowWaitTP},
223 {Name: vlanEvIncrFlowConfig, Src: []string{vlanStConfigDone, vlanStIncrFlowWaitTP},
224 Dst: vlanStConfigIncrFlow},
mpagenko01e726e2020-10-23 09:45:29 +0000225 {Name: vlanEvRemFlowConfig, Src: []string{vlanStConfigDone}, Dst: vlanStRemoveFlow},
226 {Name: vlanEvRemFlowDone, Src: []string{vlanStRemoveFlow}, Dst: vlanStCleanupDone},
227 {Name: vlanEvFlowDataRemoved, Src: []string{vlanStCleanupDone}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000228 /*
229 {Name: vlanEvTimeoutSimple, Src: []string{
230 vlanStCreatingDot1PMapper, vlanStCreatingMBPCD, vlanStSettingTconts, vlanStSettingDot1PMapper}, Dst: vlanStStarting},
231 {Name: vlanEvTimeoutMids, Src: []string{
232 vlanStCreatingGemNCTPs, vlanStCreatingGemIWs, vlanStSettingPQs}, Dst: vlanStStarting},
233 */
234 // exceptional treatment for all states except vlanStResetting
235 {Name: vlanEvReset, Src: []string{vlanStStarting, vlanStWaitingTechProf,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000236 vlanStConfigVtfd, vlanStConfigEvtocd, vlanStConfigDone, vlanStConfigIncrFlow,
mpagenko01e726e2020-10-23 09:45:29 +0000237 vlanStRemoveFlow, vlanStCleanupDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000238 Dst: vlanStResetting},
239 // the only way to get to resource-cleared disabled state again is via "resseting"
240 {Name: vlanEvRestart, Src: []string{vlanStResetting}, Dst: vlanStDisabled},
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000241 // transitions for reconcile handling according to VOL-3834
242 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStStarting}, Dst: vlanStConfigDone},
243 {Name: vlanEvSkipOmciConfig, Src: []string{vlanStConfigDone}, Dst: vlanStConfigIncrFlow},
244 {Name: vlanEvSkipIncFlowConfig, Src: []string{vlanStConfigIncrFlow}, Dst: vlanStConfigDone},
mpagenkodff5dda2020-08-28 11:52:01 +0000245 },
mpagenkodff5dda2020-08-28 11:52:01 +0000246 fsm.Callbacks{
dbainbri4d3a0dc2020-12-02 00:33:42 +0000247 "enter_state": func(e *fsm.Event) { instFsm.pAdaptFsm.logFsmStateChange(ctx, e) },
248 "enter_" + vlanStStarting: func(e *fsm.Event) { instFsm.enterConfigStarting(ctx, e) },
249 "enter_" + vlanStConfigVtfd: func(e *fsm.Event) { instFsm.enterConfigVtfd(ctx, e) },
250 "enter_" + vlanStConfigEvtocd: func(e *fsm.Event) { instFsm.enterConfigEvtocd(ctx, e) },
251 "enter_" + vlanStConfigDone: func(e *fsm.Event) { instFsm.enterVlanConfigDone(ctx, e) },
252 "enter_" + vlanStConfigIncrFlow: func(e *fsm.Event) { instFsm.enterConfigIncrFlow(ctx, e) },
253 "enter_" + vlanStRemoveFlow: func(e *fsm.Event) { instFsm.enterRemoveFlow(ctx, e) },
254 "enter_" + vlanStCleanupDone: func(e *fsm.Event) { instFsm.enterVlanCleanupDone(ctx, e) },
255 "enter_" + vlanStResetting: func(e *fsm.Event) { instFsm.enterResetting(ctx, e) },
256 "enter_" + vlanStDisabled: func(e *fsm.Event) { instFsm.enterDisabled(ctx, e) },
mpagenkodff5dda2020-08-28 11:52:01 +0000257 },
258 )
259 if instFsm.pAdaptFsm.pFsm == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000260 logger.Errorw(ctx, "UniVlanConfigFsm's Base FSM could not be instantiated!!", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000261 "device-id": instFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000262 return nil
263 }
264
dbainbri4d3a0dc2020-12-02 00:33:42 +0000265 _ = instFsm.initUniFlowParams(ctx, aTechProfileID, aCookieSlice, aMatchVlan, aSetVlan, aSetPcp)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000266
dbainbri4d3a0dc2020-12-02 00:33:42 +0000267 logger.Debugw(ctx, "UniVlanConfigFsm created", log.Fields{"device-id": instFsm.deviceID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000268 "accIncrEvto": instFsm.acceptIncrementalEvtoOption})
mpagenkodff5dda2020-08-28 11:52:01 +0000269 return instFsm
270}
271
mpagenko01e726e2020-10-23 09:45:29 +0000272//initUniFlowParams is a simplified form of SetUniFlowParams() used for first flow parameters configuration
mpagenko551a4d42020-12-08 18:09:20 +0000273func (oFsm *UniVlanConfigFsm) initUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000274 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
275 loRuleParams := uniVlanRuleParams{
Holger Hildebrandt47555e72020-09-21 11:07:24 +0000276 TpID: aTpID,
277 MatchVid: uint32(aMatchVlan),
278 SetVid: uint32(aSetVlan),
279 SetPcp: uint32(aSetPcp),
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000280 }
281 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
mpagenko01e726e2020-10-23 09:45:29 +0000282 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
283 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000284
mpagenko01e726e2020-10-23 09:45:29 +0000285 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000286 //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 +0000287 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000288 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
289 } else {
290 if !oFsm.acceptIncrementalEvtoOption {
291 //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 +0000292 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000293 }
294 }
295
mpagenko01e726e2020-10-23 09:45:29 +0000296 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000297 // no prio/vid filtering requested
mpagenko01e726e2020-10-23 09:45:29 +0000298 loRuleParams.TagsToRemove = 0 //no tag pop action
299 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
300 if loRuleParams.SetPcp == cCopyPrioFromInner {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000301 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
302 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
303 // might collide with NoMatchVid/CopyPrio(/setVid) setting
304 // this was some precondition setting taken over from py adapter ..
mpagenko01e726e2020-10-23 09:45:29 +0000305 loRuleParams.SetPcp = 0
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000306 }
307 }
mpagenko01e726e2020-10-23 09:45:29 +0000308
309 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
310 loFlowParams.CookieSlice = make([]uint64, 0)
311 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
312
313 //no mutex protection is required for initial access and adding the first flow is always possible
314 oFsm.uniVlanFlowParamsSlice = make([]uniVlanFlowParams, 0)
315 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000316 logger.Debugw(ctx, "first UniVlanConfigFsm flow added", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000317 "Cookies": oFsm.uniVlanFlowParamsSlice[0].CookieSlice,
318 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
319 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
320 "SetPcp": loRuleParams.SetPcp,
321 "device-id": oFsm.deviceID})
322 oFsm.numUniFlows = 1
323 oFsm.uniRemoveFlowsSlice = make([]uniRemoveVlanFlowParams, 0) //initially nothing to remove
324
325 //permanently store flow config for reconcile case
dbainbri4d3a0dc2020-12-02 00:33:42 +0000326 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
mpagenkof1fc3862021-02-16 10:09:52 +0000327 &oFsm.uniVlanFlowParamsSlice, true); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000328 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000329 return err
330 }
331
332 return nil
333}
334
mpagenko7d6bb022021-03-11 15:07:55 +0000335//CancelProcessing ensures that suspended processing at waiting on some response is aborted and reset of FSM
mpagenko73143992021-04-09 15:17:10 +0000336func (oFsm *UniVlanConfigFsm) CancelProcessing(ctx context.Context) {
mpagenko7d6bb022021-03-11 15:07:55 +0000337 //mutex protection is required for possible concurrent access to FSM members
mpagenkocf48e452021-04-23 09:23:00 +0000338 oFsm.mutexIsAwaitingResponse.Lock()
339 oFsm.isCanceled = true
mpagenko7d6bb022021-03-11 15:07:55 +0000340 if oFsm.isAwaitingResponse {
mpagenkocf48e452021-04-23 09:23:00 +0000341 //attention: for an unbuffered channel the sender is blocked until the value is received (processed)!
342 // accordingly the mutex must be released before sending to channel here (mutex acquired in receiver)
343 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000344 //use channel to indicate that the response waiting shall be aborted
345 oFsm.omciMIdsResponseReceived <- false
mpagenkocf48e452021-04-23 09:23:00 +0000346 } else {
347 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko7d6bb022021-03-11 15:07:55 +0000348 }
mpagenkocf48e452021-04-23 09:23:00 +0000349
mpagenko7d6bb022021-03-11 15:07:55 +0000350 // in any case (even if it might be automatically requested by above cancellation of waiting) ensure resetting the FSM
351 pAdaptFsm := oFsm.pAdaptFsm
352 if pAdaptFsm != nil {
mpagenkobb47bc22021-04-20 13:29:09 +0000353 if fsmErr := pAdaptFsm.pFsm.Event(vlanEvReset); fsmErr != nil {
mpagenkocf48e452021-04-23 09:23:00 +0000354 logger.Errorw(ctx, "reset-event failed in UniVlanConfigFsm!",
mpagenkobb47bc22021-04-20 13:29:09 +0000355 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +0000356 }
mpagenko7d6bb022021-03-11 15:07:55 +0000357 }
358}
359
mpagenko551a4d42020-12-08 18:09:20 +0000360//GetWaitingTpID returns the TpId that the FSM might be waiting for continuation (0 if none)
361func (oFsm *UniVlanConfigFsm) GetWaitingTpID() uint8 {
362 //mutex protection is required for possible concurrent access to FSM members
363 oFsm.mutexFlowParams.RLock()
364 defer oFsm.mutexFlowParams.RUnlock()
365 return oFsm.TpIDWaitingFor
366}
367
mpagenko2418ab02020-11-12 12:58:06 +0000368//RequestClearPersistency sets the internal flag to not clear persistency data (false=NoClear)
369func (oFsm *UniVlanConfigFsm) RequestClearPersistency(aClear bool) {
370 //mutex protection is required for possible concurrent access to FSM members
mpagenko15ff4a52021-03-02 10:09:20 +0000371 oFsm.mutexFlowParams.Lock()
372 defer oFsm.mutexFlowParams.Unlock()
mpagenko2418ab02020-11-12 12:58:06 +0000373 oFsm.clearPersistency = aClear
374}
375
mpagenko01e726e2020-10-23 09:45:29 +0000376//SetUniFlowParams verifies on existence of flow parameters to be configured,
377// optionally udates the cookie list or appends a new flow if there is space
378// if possible the FSM is trigggerd to start with the processing
mpagenko551a4d42020-12-08 18:09:20 +0000379// ignore complexity by now
380// nolint: gocyclo
381func (oFsm *UniVlanConfigFsm) SetUniFlowParams(ctx context.Context, aTpID uint8, aCookieSlice []uint64,
mpagenko01e726e2020-10-23 09:45:29 +0000382 aMatchVlan uint16, aSetVlan uint16, aSetPcp uint8) error {
383 loRuleParams := uniVlanRuleParams{
384 TpID: aTpID,
385 MatchVid: uint32(aMatchVlan),
386 SetVid: uint32(aSetVlan),
387 SetPcp: uint32(aSetPcp),
388 }
389 // some automatic adjustments on the filter/treat parameters as not specifically configured/ensured by flow configuration parameters
390 loRuleParams.TagsToRemove = 1 //one tag to remove as default setting
391 loRuleParams.MatchPcp = cPrioDoNotFilter // do not Filter on prio as default
392
393 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
394 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
395 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
396 //TODO!!: maybe be needed to be re-checked at flow deletion (but assume all flows are always deleted togehther)
397 } else {
398 if !oFsm.acceptIncrementalEvtoOption {
399 //then matchVlan is don't care and should be overwritten to 'transparent' here to avoid unneeded multiple flow entries
400 loRuleParams.MatchVid = uint32(of.OfpVlanId_OFPVID_PRESENT)
401 }
402 }
403
404 if loRuleParams.MatchVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
405 // no prio/vid filtering requested
406 loRuleParams.TagsToRemove = 0 //no tag pop action
407 loRuleParams.MatchPcp = cPrioIgnoreTag // no vlan tag filtering
408 if loRuleParams.SetPcp == cCopyPrioFromInner {
409 //in case of no filtering and configured PrioCopy ensure default prio setting to 0
410 // which is required for stacking of untagged, but obviously also ensures prio setting for prio/singletagged
411 // might collide with NoMatchVid/CopyPrio(/setVid) setting
412 // this was some precondition setting taken over from py adapter ..
413 loRuleParams.SetPcp = 0
414 }
415 }
416
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000417 flowEntryMatch := false
mpagenko01e726e2020-10-23 09:45:29 +0000418 flowCookieModify := false
mpagenkof1fc3862021-02-16 10:09:52 +0000419 requestAppendRule := false
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000420 //mutex protection is required for possible concurrent access to FSM members
421 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +0000422 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
423 //TODO: Verify if using e.g. hashes for the structures here for comparison may generate
424 // countable run time optimization (perhaps with including the hash in kvStore storage?)
425 if storedUniFlowParams.VlanRuleParams == loRuleParams {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000426 flowEntryMatch = true
dbainbri4d3a0dc2020-12-02 00:33:42 +0000427 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - rule already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000428 "device-id": oFsm.deviceID})
429 var cookieMatch bool
430 for _, newCookie := range aCookieSlice { // for all cookies available in the arguments
431 cookieMatch = false
432 for _, cookie := range storedUniFlowParams.CookieSlice {
433 if cookie == newCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000434 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - and cookie already exists", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000435 "device-id": oFsm.deviceID, "cookie": cookie})
436 cookieMatch = true
437 break //found new cookie - no further search for this requested cookie
438 }
439 }
440 if !cookieMatch {
mpagenkof1fc3862021-02-16 10:09:52 +0000441 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
442 if delayedCookie != 0 {
443 //a delay for adding the cookie to this rule is requested
444 // take care of the mutex which is already locked here, need to unlock/lock accordingly to prevent deadlock in suspension
445 oFsm.mutexFlowParams.Unlock()
446 oFsm.suspendNewRule(ctx)
447 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
448 oFsm.mutexFlowParams.Lock()
449 } else {
450 logger.Debugw(ctx, "UniVlanConfigFsm flow setting -adding new cookie", log.Fields{
451 "device-id": oFsm.deviceID, "cookie": newCookie})
452 //as range works with copies of the slice we have to write to the original slice!!
453 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
454 newCookie)
455 flowCookieModify = true
456 }
mpagenko01e726e2020-10-23 09:45:29 +0000457 }
458 } //for all new cookies
459 break // found rule - no further rule search
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000460 }
461 }
mpagenkof1fc3862021-02-16 10:09:52 +0000462 oFsm.mutexFlowParams.Unlock()
463
464 if !flowEntryMatch { //it is (was) a new rule
465 delayedCookie := oFsm.suspendIfRequiredNewRule(ctx, aCookieSlice)
466 requestAppendRule = true //default assumption here is that rule is to be appended
467 flowCookieModify = true //and that the the flow data base is to be updated
468 if delayedCookie != 0 { //it was suspended
469 flowCookieModify, requestAppendRule = oFsm.reviseFlowConstellation(ctx, delayedCookie, loRuleParams)
470 }
471 }
472 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
473 if requestAppendRule {
474 oFsm.mutexFlowParams.Lock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000475 if oFsm.numUniFlows < cMaxAllowedFlows {
mpagenko01e726e2020-10-23 09:45:29 +0000476 loFlowParams := uniVlanFlowParams{VlanRuleParams: loRuleParams}
477 loFlowParams.CookieSlice = make([]uint64, 0)
478 loFlowParams.CookieSlice = append(loFlowParams.CookieSlice, aCookieSlice...)
479 oFsm.uniVlanFlowParamsSlice = append(oFsm.uniVlanFlowParamsSlice, loFlowParams)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000480 logger.Debugw(ctx, "UniVlanConfigFsm flow add", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000481 "Cookies": oFsm.uniVlanFlowParamsSlice[oFsm.numUniFlows].CookieSlice,
482 "MatchVid": strconv.FormatInt(int64(loRuleParams.MatchVid), 16),
483 "SetVid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
Girish Gowdra041dcb32020-11-16 16:54:30 -0800484 "SetPcp": loRuleParams.SetPcp, "numberofFlows": oFsm.numUniFlows + 1,
mpagenko01e726e2020-10-23 09:45:29 +0000485 "device-id": oFsm.deviceID})
486
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000487 oFsm.numUniFlows++
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000488 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
489
490 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
491 logger.Debugw(ctx, "reconciling - skip omci-config of additional vlan rule",
492 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
mpagenkobb47bc22021-04-20 13:29:09 +0000493 //attention: take care to release the mutexFlowParams when calling the FSM directly -
494 // synchronous FSM 'event/state' functions may rely on this mutex
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000495 oFsm.mutexFlowParams.Unlock()
496 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
mpagenkobb47bc22021-04-20 13:29:09 +0000497 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvSkipOmciConfig); fsmErr != nil {
498 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
499 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
500 }
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000501 }
502 return nil
503 }
mpagenko01e726e2020-10-23 09:45:29 +0000504 // note: theoretical it would be possible to clear the same rule from the remove slice
505 // (for entries that have not yet been started with removal)
506 // but that is getting quite complicated - maybe a future optimization in case it should prove reasonable
507 // 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 +0000508
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000509 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
510 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenko551a4d42020-12-08 18:09:20 +0000511 if oFsm.configuredUniFlow == 0 {
512 // this is a restart with a complete new flow, we can re-use the initial flow config control
513 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenkobb47bc22021-04-20 13:29:09 +0000514 //attention: take care to release the mutexFlowParams when calling the FSM directly -
515 // synchronous FSM 'event/state' functions may rely on this mutex
516 oFsm.mutexFlowParams.Unlock()
517 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRenew); fsmErr != nil {
518 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
519 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
520 }
mpagenko551a4d42020-12-08 18:09:20 +0000521 } else {
522 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000523 //store the actual rule that shall be worked upon in the following transient states
524 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +0000525 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +0000526 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +0000527 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
528 oFsm.TpIDWaitingFor = tpID
mpagenko9a304ea2020-12-16 15:54:01 +0000529 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request (on setConfig)", log.Fields{
530 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
531 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenkobb47bc22021-04-20 13:29:09 +0000532
533 //attention: take care to release the mutexFlowParams when calling the FSM directly -
534 // synchronous FSM 'event/state' functions may rely on this mutex
535 oFsm.mutexFlowParams.Unlock()
536 var fsmErr error
537 if loTechProfDone {
538 // let the vlan processing continue with next rule
539 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvIncrFlowConfig)
540 } else {
541 // set to waiting for Techprofile
542 fsmErr = pConfigVlanStateBaseFsm.Event(vlanEvWaitTPIncr)
543 }
544 if fsmErr != nil {
545 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
546 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
547 }
mpagenko551a4d42020-12-08 18:09:20 +0000548 }
mpagenkobb47bc22021-04-20 13:29:09 +0000549 } else {
550 // if not in the appropriate state a new entry will be automatically considered later
551 // when the configDone state is reached
552 oFsm.mutexFlowParams.Unlock()
553 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000554 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000555 logger.Errorw(ctx, "UniVlanConfigFsm flow limit exceeded", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000556 "device-id": oFsm.deviceID, "flow-number": oFsm.numUniFlows})
mpagenko15ff4a52021-03-02 10:09:20 +0000557 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000558 return fmt.Errorf(" UniVlanConfigFsm flow limit exceeded %s", oFsm.deviceID)
559 }
mpagenkofc4f56e2020-11-04 17:17:49 +0000560 } else {
561 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000562 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenko15ff4a52021-03-02 10:09:20 +0000563 oFsm.mutexFlowParams.RLock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000564 if oFsm.numUniFlows == oFsm.configuredUniFlow {
565 //all requested rules really have been configured
566 // state transition notification is checked in deviceHandler
mpagenko15ff4a52021-03-02 10:09:20 +0000567 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000568 if oFsm.pDeviceHandler != nil {
569 //also the related TechProfile was already configured
dbainbri4d3a0dc2020-12-02 00:33:42 +0000570 logger.Debugw(ctx, "UniVlanConfigFsm rule already set - send immediate add-success event for reason update", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +0000571 "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000572 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
573 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetAddNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000574 }
575 } else {
576 // avoid device reason update as the rule config connected to this flow may still be in progress
577 // and the device reason should only be updated on success of rule config
dbainbri4d3a0dc2020-12-02 00:33:42 +0000578 logger.Debugw(ctx, "UniVlanConfigFsm rule already set but configuration ongoing, suppress early add-success event for reason update",
mpagenkofc4f56e2020-11-04 17:17:49 +0000579 log.Fields{"device-id": oFsm.deviceID,
580 "NumberofRules": oFsm.numUniFlows, "Configured rules": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +0000581 oFsm.mutexFlowParams.RUnlock()
mpagenkofc4f56e2020-11-04 17:17:49 +0000582 }
583 }
mpagenko01e726e2020-10-23 09:45:29 +0000584
mpagenkof1fc3862021-02-16 10:09:52 +0000585 if flowCookieModify { // some change was done to the flow entries
mpagenko01e726e2020-10-23 09:45:29 +0000586 //permanently store flow config for reconcile case
mpagenko15ff4a52021-03-02 10:09:20 +0000587 oFsm.mutexFlowParams.RLock()
mpagenkof1fc3862021-02-16 10:09:52 +0000588 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
589 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
mpagenko15ff4a52021-03-02 10:09:20 +0000590 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000591 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +0000592 return err
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000593 }
mpagenko15ff4a52021-03-02 10:09:20 +0000594 oFsm.mutexFlowParams.RUnlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000595 }
596 return nil
597}
598
mpagenkof1fc3862021-02-16 10:09:52 +0000599// VOL-3828 flow config sequence workaround ########### start ##########
600func (oFsm *UniVlanConfigFsm) delayNewRuleForCookie(ctx context.Context, aCookieSlice []uint64) uint64 {
601 //assumes mutexFlowParams.Lock() protection from caller!
602 if oFsm.delayNewRuleCookie == 0 && len(aCookieSlice) == 1 {
603 // if not already waiting, limitation for this workaround is to just have one overlapping cookie/rule
604 // suspend check is done only of there is only one cookie in the request
605 // background: more elements only expected in reconcile use case, where no conflicting sequence is to be expected
606 newCookie := aCookieSlice[0]
607 for _, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
608 for _, cookie := range storedUniFlowParams.CookieSlice {
609 if cookie == newCookie {
610 logger.Debugw(ctx, "UniVlanConfigFsm flow setting - new cookie still exists for some rule", log.Fields{
611 "device-id": oFsm.deviceID, "cookie": cookie, "exists with SetVlan": storedUniFlowParams.VlanRuleParams.SetVid})
612 oFsm.delayNewRuleCookie = newCookie
613 return newCookie //found new cookie in some existing rule
614 }
615 } // for all stored cookies of the actual inspected rule
616 } //for all rules
617 }
618 return 0 //no delay requested
619}
620func (oFsm *UniVlanConfigFsm) suspendNewRule(ctx context.Context) {
621 oFsm.mutexFlowParams.RLock()
622 logger.Infow(ctx, "Need to suspend adding this rule as long as the cookie is still connected to some other rule", log.Fields{
623 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
624 oFsm.mutexFlowParams.RUnlock()
625 select {
626 case <-oFsm.chCookieDeleted:
627 logger.Infow(ctx, "resume adding this rule after having deleted cookie in some other rule", log.Fields{
628 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
Holger Hildebrandt366ef192021-05-05 11:07:44 +0000629 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second):
mpagenkof1fc3862021-02-16 10:09:52 +0000630 logger.Errorw(ctx, "timeout waiting for deletion of cookie in some other rule, just try to continue", log.Fields{
631 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
632 }
633 oFsm.mutexFlowParams.Lock()
634 oFsm.delayNewRuleCookie = 0
635 oFsm.mutexFlowParams.Unlock()
636}
637func (oFsm *UniVlanConfigFsm) suspendIfRequiredNewRule(ctx context.Context, aCookieSlice []uint64) uint64 {
638 oFsm.mutexFlowParams.Lock()
639 delayedCookie := oFsm.delayNewRuleForCookie(ctx, aCookieSlice)
640 oFsm.mutexFlowParams.Unlock()
641
642 if delayedCookie != 0 {
643 oFsm.suspendNewRule(ctx)
644 }
645 return delayedCookie
646}
647
648//returns flowModified, RuleAppendRequest
649func (oFsm *UniVlanConfigFsm) reviseFlowConstellation(ctx context.Context, aCookie uint64, aUniVlanRuleParams uniVlanRuleParams) (bool, bool) {
650 flowEntryMatch := false
651 oFsm.mutexFlowParams.Lock()
652 defer oFsm.mutexFlowParams.Unlock()
653 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
654 if storedUniFlowParams.VlanRuleParams == aUniVlanRuleParams {
655 flowEntryMatch = true
656 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - rule already exists", log.Fields{
657 "device-id": oFsm.deviceID})
658 cookieMatch := false
659 for _, cookie := range storedUniFlowParams.CookieSlice {
660 if cookie == aCookie {
661 logger.Debugw(ctx, "UniVlanConfigFsm flow revise - and cookie already exists", log.Fields{
662 "device-id": oFsm.deviceID, "cookie": cookie})
663 cookieMatch = true
664 break //found new cookie - no further search for this requested cookie
665 }
666 }
667 if !cookieMatch {
668 logger.Debugw(ctx, "UniVlanConfigFsm flow revise -adding new cookie", log.Fields{
669 "device-id": oFsm.deviceID, "cookie": aCookie})
670 //as range works with copies of the slice we have to write to the original slice!!
671 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(oFsm.uniVlanFlowParamsSlice[flow].CookieSlice,
672 aCookie)
673 return true, false //flowModified, NoRuleAppend
674 }
675 break // found rule - no further rule search
676 }
677 }
678 if !flowEntryMatch { //it is a new rule
679 return true, true //flowModified, RuleAppend
680 }
681 return false, false //flowNotModified, NoRuleAppend
682}
683
684// VOL-3828 flow config sequence workaround ########### end ##########
685
mpagenko01e726e2020-10-23 09:45:29 +0000686//RemoveUniFlowParams verifies on existence of flow cookie,
687// if found removes cookie from flow cookie list and if this is empty
688// initiates removal of the flow related configuration from the ONU (via OMCI)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000689func (oFsm *UniVlanConfigFsm) RemoveUniFlowParams(ctx context.Context, aCookie uint64) error {
mpagenkof1fc3862021-02-16 10:09:52 +0000690 var deletedCookie uint64
mpagenko01e726e2020-10-23 09:45:29 +0000691 flowCookieMatch := false
692 //mutex protection is required for possible concurrent access to FSM members
693 oFsm.mutexFlowParams.Lock()
694 defer oFsm.mutexFlowParams.Unlock()
mpagenkof1fc3862021-02-16 10:09:52 +0000695remove_loop:
mpagenko01e726e2020-10-23 09:45:29 +0000696 for flow, storedUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
697 for i, cookie := range storedUniFlowParams.CookieSlice {
698 if cookie == aCookie {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000699 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - cookie found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000700 "device-id": oFsm.deviceID, "cookie": cookie})
701 flowCookieMatch = true
mpagenkof1fc3862021-02-16 10:09:52 +0000702 deletedCookie = aCookie
703 kvStoreWrite := false //default setting is to not write to kvStore immediately - will be done on FSM execution finally
mpagenko01e726e2020-10-23 09:45:29 +0000704 //remove the cookie from the cookie slice and verify it is getting empty
705 if len(storedUniFlowParams.CookieSlice) == 1 {
mpagenko535d6ef2021-02-26 13:15:34 +0000706 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
707 var cancelPendingConfig bool = false
708 var loRemoveParams uniRemoveVlanFlowParams = uniRemoveVlanFlowParams{}
dbainbri4d3a0dc2020-12-02 00:33:42 +0000709 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - full flow removal", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000710 "device-id": oFsm.deviceID})
mpagenko15ff4a52021-03-02 10:09:20 +0000711 //rwCore flow recovery may be the reason for this delete, in which case the flowToBeDeleted may be the same
mpagenko535d6ef2021-02-26 13:15:34 +0000712 // as the one still waiting in the FSM as toAdd but waiting for TechProfileConfig
mpagenko15ff4a52021-03-02 10:09:20 +0000713 // so we have to check if we have to abort the outstanding AddRequest and regard the current DelRequest as done
mpagenko535d6ef2021-02-26 13:15:34 +0000714 // if the Fsm is in some other transient (config) state, we will reach the DelRequest later and correctly process it then
715 if pConfigVlanStateBaseFsm.Is(vlanStWaitingTechProf) {
716 logger.Debugw(ctx, "UniVlanConfigFsm was waiting for TechProf config with this rule, aborting the outstanding config",
717 log.Fields{"device-id": oFsm.deviceID})
718 cancelPendingConfig = true
719 } else {
720 //create a new element for the removeVlanFlow slice
721 loRemoveParams = uniRemoveVlanFlowParams{
722 vlanRuleParams: storedUniFlowParams.VlanRuleParams,
723 cookie: aCookie,
724 }
725 oFsm.uniRemoveFlowsSlice = append(oFsm.uniRemoveFlowsSlice, loRemoveParams)
mpagenko01e726e2020-10-23 09:45:29 +0000726 }
mpagenko01e726e2020-10-23 09:45:29 +0000727
728 //and remove the actual element from the addVlanFlow slice
729 // oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = nil //automatically done by garbage collector
730 if len(oFsm.uniVlanFlowParamsSlice) <= 1 {
731 oFsm.numUniFlows = 0 //no more flows
732 oFsm.configuredUniFlow = 0 //no more flows configured
733 oFsm.uniVlanFlowParamsSlice = nil //reset the slice
mpagenko2418ab02020-11-12 12:58:06 +0000734 //at this point it is evident that no flow anymore refers to a still possibly active Techprofile
mpagenko535d6ef2021-02-26 13:15:34 +0000735 //request that this profile gets deleted before a new flow add is allowed (except for some aborted add)
736 if !cancelPendingConfig {
737 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, loRemoveParams.vlanRuleParams.TpID, true)
738 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000739 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - no more flows", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000740 "device-id": oFsm.deviceID})
741 } else {
742 oFsm.numUniFlows--
743 if oFsm.configuredUniFlow > 0 {
744 oFsm.configuredUniFlow--
745 //TODO!! might be needed to consider still outstanding configure requests ..
746 // so a flow at removal might still not be configured !?!
747 }
mpagenko2418ab02020-11-12 12:58:06 +0000748 usedTpID := storedUniFlowParams.VlanRuleParams.TpID
mpagenko01e726e2020-10-23 09:45:29 +0000749 //cut off the requested flow by slicing out this element
750 oFsm.uniVlanFlowParamsSlice = append(
751 oFsm.uniVlanFlowParamsSlice[:flow], oFsm.uniVlanFlowParamsSlice[flow+1:]...)
mpagenko2418ab02020-11-12 12:58:06 +0000752 //here we have to check, if there are still other flows referencing to the actual ProfileId
753 // before we can request that this profile gets deleted before a new flow add is allowed
mpagenkof1fc3862021-02-16 10:09:52 +0000754 // (needed to extract to function due to lint complexity)
mpagenko535d6ef2021-02-26 13:15:34 +0000755 if !cancelPendingConfig {
756 oFsm.updateTechProfileToDelete(ctx, usedTpID)
757 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000758 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow removed from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000759 "device-id": oFsm.deviceID})
760 }
761 //trigger the FSM to remove the relevant rule
mpagenko535d6ef2021-02-26 13:15:34 +0000762 if cancelPendingConfig {
763 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenkobb47bc22021-04-20 13:29:09 +0000764 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
765 // synchronous FSM 'event/state' functions may rely on this mutex
766 oFsm.mutexFlowParams.Unlock()
767 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvCancelOutstandingConfig); fsmErr != nil {
768 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
769 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
770 }
771 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000772 } else {
773 if pConfigVlanStateBaseFsm.Is(vlanStConfigDone) {
774 logger.Debugw(ctx, "UniVlanConfigFsm rule removal request", log.Fields{
775 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
776 "tp-id": loRemoveParams.vlanRuleParams.TpID,
777 "set-Vlan": loRemoveParams.vlanRuleParams.SetVid})
778 //have to re-trigger the FSM to proceed with outstanding incremental flow configuration
mpagenkobb47bc22021-04-20 13:29:09 +0000779 //attention: take care to release and re-take the mutexFlowParams when calling the FSM directly -
780 // synchronous FSM 'event/state' functions may rely on this mutex
781 oFsm.mutexFlowParams.Unlock()
782 if fsmErr := pConfigVlanStateBaseFsm.Event(vlanEvRemFlowConfig); fsmErr != nil {
783 logger.Errorw(ctx, "error in FsmEvent handling UniVlanConfigFsm!",
784 log.Fields{"fsmState": pConfigVlanStateBaseFsm.Current(), "error": fsmErr, "device-id": oFsm.deviceID})
785 }
786 oFsm.mutexFlowParams.Lock()
mpagenko535d6ef2021-02-26 13:15:34 +0000787 } // if not in the appropriate state a new entry will be automatically considered later
788 // when the configDone state is reached
789 }
mpagenko01e726e2020-10-23 09:45:29 +0000790 } else {
mpagenko01e726e2020-10-23 09:45:29 +0000791 //cut off the requested cookie by slicing out this element
792 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice = append(
793 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[:i],
794 oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[i+1:]...)
mpagenkofc4f56e2020-11-04 17:17:49 +0000795 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
mpagenkof1fc3862021-02-16 10:09:52 +0000796 kvStoreWrite = true // ensure actual data write to kvStore immediately (no FSM activity)
mpagenkofc4f56e2020-11-04 17:17:49 +0000797 // state transition notification is checked in deviceHandler
798 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000799 // success indication without the need to write to kvStore (done already below with updated data from storePersUniFlowConfig())
800 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000801 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000802 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - rule persists with still valid cookies", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000803 "device-id": oFsm.deviceID, "cookies": oFsm.uniVlanFlowParamsSlice[flow].CookieSlice})
mpagenkof1fc3862021-02-16 10:09:52 +0000804 if deletedCookie == oFsm.delayNewRuleCookie {
805 //the delayedNewCookie is the one that is currently deleted, but the rule still exist with other cookies
806 //as long as there are further cookies for this rule indicate there is still some cookie to be deleted
807 //simply use the first one
808 oFsm.delayNewRuleCookie = oFsm.uniVlanFlowParamsSlice[flow].CookieSlice[0]
809 logger.Debugw(ctx, "UniVlanConfigFsm remaining cookie awaited for deletion before new rule add", log.Fields{
810 "device-id": oFsm.deviceID, "cookie": oFsm.delayNewRuleCookie})
811 }
mpagenko01e726e2020-10-23 09:45:29 +0000812 }
mpagenko01e726e2020-10-23 09:45:29 +0000813 //permanently store the modified flow config for reconcile case
mpagenkofc4f56e2020-11-04 17:17:49 +0000814 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000815 if err := oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID,
816 &oFsm.uniVlanFlowParamsSlice, kvStoreWrite); err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +0000817 logger.Errorw(ctx, err.Error(), log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +0000818 return err
819 }
mpagenko01e726e2020-10-23 09:45:29 +0000820 }
mpagenkof1fc3862021-02-16 10:09:52 +0000821 break remove_loop //found the cookie - no further search for this requested cookie
mpagenko01e726e2020-10-23 09:45:29 +0000822 }
823 }
mpagenko01e726e2020-10-23 09:45:29 +0000824 } //search all flows
825 if !flowCookieMatch { //some cookie remove-request for a cookie that does not exist in the FSM data
dbainbri4d3a0dc2020-12-02 00:33:42 +0000826 logger.Warnw(ctx, "UniVlanConfigFsm flow removal - remove-cookie not found", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000827 "device-id": oFsm.deviceID, "remove-cookie": aCookie})
828 // but accept the request with success as no such cookie (flow) does exist
mpagenkofc4f56e2020-11-04 17:17:49 +0000829 // no activity within the FSM for OMCI processing, the deviceReason may be updated immediately
830 // state transition notification is checked in deviceHandler
831 if oFsm.pDeviceHandler != nil {
mpagenkof1fc3862021-02-16 10:09:52 +0000832 // success indication without the need to write to kvStore (no change)
833 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(oFsm.requestEvent+cDeviceEventOffsetRemoveNoKvStore))
mpagenkofc4f56e2020-11-04 17:17:49 +0000834 }
mpagenko01e726e2020-10-23 09:45:29 +0000835 return nil
836 } //unknown cookie
837
838 return nil
839}
840
mpagenkof1fc3862021-02-16 10:09:52 +0000841func (oFsm *UniVlanConfigFsm) updateTechProfileToDelete(ctx context.Context, usedTpID uint8) {
842 //here we have to check, if there are still other flows referencing to the actual ProfileId
843 // before we can request that this profile gets deleted before a new flow add is allowed
844 tpIDInOtherFlows := false
845 for _, tpUniFlowParams := range oFsm.uniVlanFlowParamsSlice {
846 if tpUniFlowParams.VlanRuleParams.TpID == usedTpID {
847 tpIDInOtherFlows = true
848 break // search loop can be left
849 }
850 }
851 if tpIDInOtherFlows {
852 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is still used in other flows", log.Fields{
853 "device-id": oFsm.deviceID, "tp-id": usedTpID})
854 } else {
855 logger.Debugw(ctx, "UniVlanConfigFsm tp-id used in deleted flow is not used anymore", log.Fields{
856 "device-id": oFsm.deviceID, "tp-id": usedTpID})
857 //request that this profile gets deleted before a new flow add is allowed
858 oFsm.pUniTechProf.setProfileToDelete(oFsm.pOnuUniPort.uniID, usedTpID, true)
859 }
860}
861
dbainbri4d3a0dc2020-12-02 00:33:42 +0000862func (oFsm *UniVlanConfigFsm) enterConfigStarting(ctx context.Context, e *fsm.Event) {
863 logger.Debugw(ctx, "UniVlanConfigFsm start", log.Fields{"in state": e.FSM.Current(),
mpagenko01e726e2020-10-23 09:45:29 +0000864 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000865
866 // this FSM is not intended for re-start, needs always new creation for a new run
mpagenko01e726e2020-10-23 09:45:29 +0000867 // (self-destroying - compare enterDisabled())
mpagenkodff5dda2020-08-28 11:52:01 +0000868 oFsm.omciMIdsResponseReceived = make(chan bool)
mpagenkof1fc3862021-02-16 10:09:52 +0000869 oFsm.chCookieDeleted = make(chan bool)
mpagenkodff5dda2020-08-28 11:52:01 +0000870 // start go routine for processing of LockState messages
dbainbri4d3a0dc2020-12-02 00:33:42 +0000871 go oFsm.processOmciVlanMessages(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +0000872 //let the state machine run forward from here directly
873 pConfigVlanStateAFsm := oFsm.pAdaptFsm
874 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000875
Holger Hildebrandtbe523842021-03-10 10:47:18 +0000876 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
877 logger.Debugw(ctx, "reconciling - skip omci-config of vlan rule",
878 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
879 go func(a_pAFsm *AdapterFsm) {
880 _ = a_pAFsm.pFsm.Event(vlanEvSkipOmciConfig)
881 }(pConfigVlanStateAFsm)
882 return
883 }
884 oFsm.mutexFlowParams.Lock()
mpagenko9a304ea2020-12-16 15:54:01 +0000885 //possibly the entry is not valid anymore based on intermediate delete requests
886 //just a basic protection ...
887 if len(oFsm.uniVlanFlowParamsSlice) == 0 {
888 oFsm.mutexFlowParams.Unlock()
889 logger.Debugw(ctx, "UniVlanConfigFsm start: no rule entry anymore available", log.Fields{
890 "device-id": oFsm.deviceID})
891 // Can't call FSM Event directly, decoupling it
892 go func(a_pAFsm *AdapterFsm) {
893 _ = a_pAFsm.pFsm.Event(vlanEvReset)
894 }(pConfigVlanStateAFsm)
895 return
896 }
mpagenko9a304ea2020-12-16 15:54:01 +0000897 //access to uniVlanFlowParamsSlice is done on first element only here per definition
898 //store the actual rule that shall be worked upon in the following transient states
899 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[0].VlanRuleParams
mpagenko9a304ea2020-12-16 15:54:01 +0000900 tpID := oFsm.actualUniVlanConfigRule.TpID
901 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +0000902 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID))
mpagenko9a304ea2020-12-16 15:54:01 +0000903 logger.Debugw(ctx, "UniVlanConfigFsm - start with first rule", log.Fields{
904 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
905 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
mpagenko551a4d42020-12-08 18:09:20 +0000906 //cmp also usage in EVTOCDE create in omci_cc
907 oFsm.evtocdID = macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
mpagenko535d6ef2021-02-26 13:15:34 +0000908 oFsm.mutexFlowParams.Unlock()
mpagenko9a304ea2020-12-16 15:54:01 +0000909 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +0000910 go func(aPAFsm *AdapterFsm, aTechProfDone bool) {
911 if aPAFsm != nil && aPAFsm.pFsm != nil {
912 if aTechProfDone {
mpagenkodff5dda2020-08-28 11:52:01 +0000913 // let the vlan processing begin
mpagenko551a4d42020-12-08 18:09:20 +0000914 _ = aPAFsm.pFsm.Event(vlanEvStartConfig)
mpagenkodff5dda2020-08-28 11:52:01 +0000915 } else {
916 // set to waiting for Techprofile
mpagenko551a4d42020-12-08 18:09:20 +0000917 _ = aPAFsm.pFsm.Event(vlanEvWaitTechProf)
mpagenkodff5dda2020-08-28 11:52:01 +0000918 }
919 }
mpagenko551a4d42020-12-08 18:09:20 +0000920 }(pConfigVlanStateAFsm, loTechProfDone)
921 } else {
922 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
923 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
924 //should never happen, else: recovery would be needed from outside the FSM
925 return
mpagenkodff5dda2020-08-28 11:52:01 +0000926 }
927}
928
dbainbri4d3a0dc2020-12-02 00:33:42 +0000929func (oFsm *UniVlanConfigFsm) enterConfigVtfd(ctx context.Context, e *fsm.Event) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000930 //mutex protection is required for possible concurrent access to FSM members
931 oFsm.mutexFlowParams.Lock()
mpagenko551a4d42020-12-08 18:09:20 +0000932 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
mpagenko9a304ea2020-12-16 15:54:01 +0000933 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +0000934 // meaning transparent setup - no specific VTFD setting required
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000935 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +0000936 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000937 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +0000938 // let the FSM proceed ... (from within this state all internal pointers may be expected to be correct)
mpagenkodff5dda2020-08-28 11:52:01 +0000939 pConfigVlanStateAFsm := oFsm.pAdaptFsm
mpagenko9a304ea2020-12-16 15:54:01 +0000940 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +0000941 go func(a_pAFsm *AdapterFsm) {
Himani Chawla4d908332020-08-31 12:30:20 +0530942 _ = a_pAFsm.pFsm.Event(vlanEvRxConfigVtfd)
mpagenkodff5dda2020-08-28 11:52:01 +0000943 }(pConfigVlanStateAFsm)
944 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300945 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
946 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +0000947 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
dbainbri4d3a0dc2020-12-02 00:33:42 +0000948 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300949 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +0000950 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
951 // setVid is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +0000952 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000953 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +0000954 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000955 vtfdFilterList[0] = oFsm.vlanFilterList[0]
956 oFsm.numVlanFilterEntries = 1
mpagenkodff5dda2020-08-28 11:52:01 +0000957 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300958 EntityID: vtfdID,
mpagenkodff5dda2020-08-28 11:52:01 +0000959 Attributes: me.AttributeValueMap{
Holger Hildebrandt394c5522020-09-11 11:23:01 +0000960 "VlanFilterList": vtfdFilterList, //omci lib wants a slice for serialization
961 "ForwardOperation": uint8(0x10), //VID investigation
962 "NumberOfEntries": oFsm.numVlanFilterEntries,
mpagenkodff5dda2020-08-28 11:52:01 +0000963 },
964 }
dbainbri4d3a0dc2020-12-02 00:33:42 +0000965 logger.Debugw(ctx, "UniVlanConfigFsm sendcreate VTFD", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000966 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab36ed572021-04-01 10:38:48 +0300967 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +0000968 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +0300969 if err != nil {
970 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
971 log.Fields{"device-id": oFsm.deviceID})
972 pConfigVlanStateAFsm := oFsm.pAdaptFsm
973 if pConfigVlanStateAFsm != nil {
974 go func(a_pAFsm *AdapterFsm) {
975 _ = a_pAFsm.pFsm.Event(vlanEvReset)
976 }(pConfigVlanStateAFsm)
977 }
978 return
979 }
mpagenkodff5dda2020-08-28 11:52:01 +0000980 //accept also nil as (error) return value for writing to LastTx
981 // - this avoids misinterpretation of new received OMCI messages
982 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
983 // send shall return (dual format) error code that can be used here for immediate error treatment
984 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +0000985 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +0000986 }
987}
988
dbainbri4d3a0dc2020-12-02 00:33:42 +0000989func (oFsm *UniVlanConfigFsm) enterConfigEvtocd(ctx context.Context, e *fsm.Event) {
990 logger.Debugw(ctx, "UniVlanConfigFsm - start config EVTOCD loop", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +0000991 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkof1fc3862021-02-16 10:09:52 +0000992 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300993 go func() {
mpagenko9a304ea2020-12-16 15:54:01 +0000994 //using the first element in the slice because it's the first flow per definition here
995 errEvto := oFsm.performConfigEvtocdEntries(ctx, 0)
ozgecanetsiab5000ef2020-11-27 14:38:20 +0300996 //This is correct passing scenario
997 if errEvto == nil {
mpagenko9a304ea2020-12-16 15:54:01 +0000998 tpID := oFsm.actualUniVlanConfigRule.TpID
999 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001000 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
1001 logger.Infow(ctx, "Setting multicast MEs, with first flow", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001002 "techProfile": tpID, "gemPort": gemPort, "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
dbainbri4d3a0dc2020-12-02 00:33:42 +00001003 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001004 vlanID)
1005 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001006 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001007 log.Fields{"device-id": oFsm.deviceID})
1008 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1009 }
1010 }
1011 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
1012 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1013 }
1014 }()
mpagenkodff5dda2020-08-28 11:52:01 +00001015}
1016
dbainbri4d3a0dc2020-12-02 00:33:42 +00001017func (oFsm *UniVlanConfigFsm) enterVlanConfigDone(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001018
mpagenko9a304ea2020-12-16 15:54:01 +00001019 oFsm.mutexFlowParams.RLock()
1020 defer oFsm.mutexFlowParams.RUnlock()
1021
mpagenkof1fc3862021-02-16 10:09:52 +00001022 logger.Infow(ctx, "UniVlanConfigFsm config done - checking on more flows", log.Fields{
mpagenko551a4d42020-12-08 18:09:20 +00001023 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1024 "overall-uni-rules": oFsm.numUniFlows, "configured-uni-rules": oFsm.configuredUniFlow})
1025 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1026 if pConfigVlanStateAFsm == nil {
mpagenko551a4d42020-12-08 18:09:20 +00001027 logger.Errorw(ctx, "UniVlanConfigFsm abort: invalid FSM pointer", log.Fields{
1028 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1029 //should never happen, else: recovery would be needed from outside the FSM
1030 return
1031 }
1032 pConfigVlanStateBaseFsm := pConfigVlanStateAFsm.pFsm
mpagenko01e726e2020-10-23 09:45:29 +00001033 if len(oFsm.uniRemoveFlowsSlice) > 0 {
1034 //some further flows are to be removed, removal always starts with the first element
mpagenko9a304ea2020-12-16 15:54:01 +00001035 logger.Debugw(ctx, "UniVlanConfigFsm rule removal from ConfigDone", log.Fields{
1036 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1037 "tp-id": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.TpID,
1038 "set-Vlan": oFsm.uniRemoveFlowsSlice[0].vlanRuleParams.SetVid})
1039 // Can't call FSM Event directly, decoupling it
mpagenko01e726e2020-10-23 09:45:29 +00001040 go func(a_pBaseFsm *fsm.FSM) {
1041 _ = a_pBaseFsm.Event(vlanEvRemFlowConfig)
1042 }(pConfigVlanStateBaseFsm)
1043 return
1044 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001045 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1046 oFsm.configuredUniFlow = oFsm.numUniFlows
Holger Hildebrandtb4563ab2021-04-14 10:27:20 +00001047 if !oFsm.pDeviceHandler.isReconcilingFlows() {
1048 logger.Debugw(ctx, "reconciling - flow processing finished", log.Fields{"device-id": oFsm.deviceID})
1049 oFsm.pDeviceHandler.chReconcilingFlowsFinished <- true
1050 }
Holger Hildebrandt1b8f4ad2021-03-25 15:53:51 +00001051 logger.Debugw(ctx, "reconciling - skip enterVlanConfigDone processing",
1052 log.Fields{"numUniFlows": oFsm.numUniFlows, "configuredUniFlow": oFsm.configuredUniFlow, "device-id": oFsm.deviceID})
1053 return
1054 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001055 if oFsm.numUniFlows > oFsm.configuredUniFlow {
mpagenko551a4d42020-12-08 18:09:20 +00001056 if oFsm.configuredUniFlow == 0 {
mpagenko551a4d42020-12-08 18:09:20 +00001057 // this is a restart with a complete new flow, we can re-use the initial flow config control
1058 // including the check, if the related techProfile is (still) available (probably also removed in between)
mpagenko9a304ea2020-12-16 15:54:01 +00001059 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001060 go func(a_pBaseFsm *fsm.FSM) {
1061 _ = a_pBaseFsm.Event(vlanEvRenew)
1062 }(pConfigVlanStateBaseFsm)
1063 return
1064 }
1065
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001066 //some further flows are to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001067 //store the actual rule that shall be worked upon in the following transient states
1068 oFsm.actualUniVlanConfigRule = oFsm.uniVlanFlowParamsSlice[oFsm.configuredUniFlow].VlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001069 //tpId of the next rule to be configured
mpagenko9a304ea2020-12-16 15:54:01 +00001070 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko551a4d42020-12-08 18:09:20 +00001071 oFsm.TpIDWaitingFor = tpID
mpagenko551a4d42020-12-08 18:09:20 +00001072 loTechProfDone := oFsm.pUniTechProf.getTechProfileDone(ctx, oFsm.pOnuUniPort.uniID, tpID)
mpagenko9a304ea2020-12-16 15:54:01 +00001073 logger.Debugw(ctx, "UniVlanConfigFsm - incremental config request", log.Fields{
1074 "device-id": oFsm.deviceID, "uni-id": oFsm.pOnuUniPort.uniID,
1075 "set-Vlan": oFsm.actualUniVlanConfigRule.SetVid, "tp-id": tpID, "ProfDone": loTechProfDone})
1076 // Can't call FSM Event directly, decoupling it
mpagenko551a4d42020-12-08 18:09:20 +00001077 go func(aPBaseFsm *fsm.FSM, aTechProfDone bool) {
1078 if aTechProfDone {
1079 // let the vlan processing continue with next rule
1080 _ = aPBaseFsm.Event(vlanEvIncrFlowConfig)
1081 } else {
1082 // set to waiting for Techprofile
1083 _ = aPBaseFsm.Event(vlanEvWaitTPIncr)
1084 }
1085 }(pConfigVlanStateBaseFsm, loTechProfDone)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001086 return
1087 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001088 logger.Debugw(ctx, "UniVlanConfigFsm - VLAN config done: send dh event notification", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001089 "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001090 // it might appear that some flows are requested also after 'flowPushed' event has been generated ...
1091 // state transition notification is checked in deviceHandler
mpagenko551a4d42020-12-08 18:09:20 +00001092 // note: 'flowPushed' event is only generated if all 'pending' rules are configured
mpagenkodff5dda2020-08-28 11:52:01 +00001093 if oFsm.pDeviceHandler != nil {
mpagenkofc4f56e2020-11-04 17:17:49 +00001094 //making use of the add->remove successor enum assumption/definition
dbainbri4d3a0dc2020-12-02 00:33:42 +00001095 go oFsm.pDeviceHandler.deviceProcStatusUpdate(ctx, OnuDeviceEvent(uint8(oFsm.requestEvent)+oFsm.requestEventOffset))
mpagenkodff5dda2020-08-28 11:52:01 +00001096 }
1097}
1098
dbainbri4d3a0dc2020-12-02 00:33:42 +00001099func (oFsm *UniVlanConfigFsm) enterConfigIncrFlow(ctx context.Context, e *fsm.Event) {
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001100
1101 if oFsm.pDeviceHandler.isSkipOnuConfigReconciling() {
1102 logger.Debugw(ctx, "reconciling - skip further processing for incremental flow",
1103 log.Fields{"fsmState": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
1104 go func(a_pBaseFsm *fsm.FSM) {
1105 _ = a_pBaseFsm.Event(vlanEvSkipIncFlowConfig)
1106 }(oFsm.pAdaptFsm.pFsm)
1107 return
1108 }
mpagenko15ff4a52021-03-02 10:09:20 +00001109 oFsm.mutexFlowParams.Lock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001110 logger.Debugw(ctx, "UniVlanConfigFsm - start config further incremental flow", log.Fields{
Girish Gowdra041dcb32020-11-16 16:54:30 -08001111 "in state": e.FSM.Current(), "recent flow-number": oFsm.configuredUniFlow,
mpagenko01e726e2020-10-23 09:45:29 +00001112 "device-id": oFsm.deviceID})
mpagenko551a4d42020-12-08 18:09:20 +00001113 oFsm.TpIDWaitingFor = 0 //reset indication to avoid misinterpretation
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001114
mpagenko9a304ea2020-12-16 15:54:01 +00001115 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001116 // meaning transparent setup - no specific VTFD setting required
1117 oFsm.mutexFlowParams.Unlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001118 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD config required", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001119 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001120 } else {
mpagenkocf48e452021-04-23 09:23:00 +00001121 //TODO!!!: it was not really intended to keep this enter* FSM method waiting on OMCI response (preventing other state transitions)
1122 // so it would be conceptually better to wait for the response in background like for the other multi-entity processing
1123 // but as the OMCI sequence must be ensured, a separate new state would be required - perhaps later
1124 // 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 +00001125 if oFsm.numVlanFilterEntries == 0 {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001126 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1127 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko9a304ea2020-12-16 15:54:01 +00001128 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(oFsm.actualUniVlanConfigRule.TpID)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001129 //no VTFD yet created
dbainbri4d3a0dc2020-12-02 00:33:42 +00001130 logger.Debugw(ctx, "UniVlanConfigFsm create VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001131 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001132 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001133 // 'SetVid' below is assumed to be masked already by the caller to 12 bit
mpagenko9a304ea2020-12-16 15:54:01 +00001134 oFsm.vlanFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001135
mpagenko01e726e2020-10-23 09:45:29 +00001136 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001137 vtfdFilterList[0] = oFsm.vlanFilterList[0]
1138 oFsm.numVlanFilterEntries = 1
1139 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001140 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001141 Attributes: me.AttributeValueMap{
1142 "VlanFilterList": vtfdFilterList,
1143 "ForwardOperation": uint8(0x10), //VID investigation
1144 "NumberOfEntries": oFsm.numVlanFilterEntries,
1145 },
1146 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001147 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001148 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001149 if err != nil {
1150 logger.Errorw(ctx, "VTFD create failed, aborting UniVlanConfig FSM!",
1151 log.Fields{"device-id": oFsm.deviceID})
1152 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1153 if pConfigVlanStateAFsm != nil {
1154 go func(a_pAFsm *AdapterFsm) {
1155 _ = a_pAFsm.pFsm.Event(vlanEvReset)
1156 }(pConfigVlanStateAFsm)
1157 }
1158 return
1159 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001160 //accept also nil as (error) return value for writing to LastTx
1161 // - this avoids misinterpretation of new received OMCI messages
1162 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1163 // send shall return (dual format) error code that can be used here for immediate error treatment
1164 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001165 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001166 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001167 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
1168 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
mpagenko551a4d42020-12-08 18:09:20 +00001169 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID +
mpagenko9a304ea2020-12-16 15:54:01 +00001170 uint16(oFsm.actualUniVlanConfigRule.TpID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001171
dbainbri4d3a0dc2020-12-02 00:33:42 +00001172 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001173 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001174 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001175 // setVid is assumed to be masked already by the caller to 12 bit
1176 oFsm.vlanFilterList[oFsm.numVlanFilterEntries] =
mpagenko9a304ea2020-12-16 15:54:01 +00001177 uint16(oFsm.actualUniVlanConfigRule.SetVid)
mpagenko01e726e2020-10-23 09:45:29 +00001178 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001179
1180 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
1181 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
1182 // new vlan associated with a different TP.
mpagenko9a304ea2020-12-16 15:54:01 +00001183 vtfdFilterList[0] = uint16(oFsm.actualUniVlanConfigRule.SetVid)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001184
1185 oFsm.numVlanFilterEntries++
1186 meParams := me.ParamData{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001187 EntityID: vtfdID,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001188 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001189 "VlanFilterList": vtfdFilterList,
1190 "ForwardOperation": uint8(0x10), //VID investigation
1191 "NumberOfEntries": oFsm.numVlanFilterEntries,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001192 },
1193 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001194 meInstance, err := oFsm.pOmciCC.sendCreateVtfdVar(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001195 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001196 if err != nil {
1197 logger.Errorw(ctx, "UniVlanFsm create Vlan Tagging Filter ME result error",
1198 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1199 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1200 return
1201 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001202 //accept also nil as (error) return value for writing to LastTx
1203 // - this avoids misinterpretation of new received OMCI messages
1204 //TODO!!: refactoring improvement requested, here as an example for [VOL-3457]:
1205 // send shall return (dual format) error code that can be used here for immediate error treatment
1206 // (relevant to all used sendXX() methods in this (and other) FSM's)
mpagenko01e726e2020-10-23 09:45:29 +00001207 oFsm.pLastTxMeInstance = meInstance
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001208 }
mpagenko15ff4a52021-03-02 10:09:20 +00001209 oFsm.mutexFlowParams.Unlock()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001210 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001211 err := oFsm.waitforOmciResponse(ctx)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001212 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001213 logger.Errorw(ctx, "VTFD create/set failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001214 log.Fields{"device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001215 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
mpagenko9a304ea2020-12-16 15:54:01 +00001216 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001217 go func(a_pBaseFsm *fsm.FSM) {
1218 _ = a_pBaseFsm.Event(vlanEvReset)
1219 }(pConfigVlanStateBaseFsm)
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001220 return
1221 }
1222 }
mpagenko15ff4a52021-03-02 10:09:20 +00001223 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001224 oFsm.requestEventOffset = uint8(cDeviceEventOffsetAddWithKvStore) //0 offset for last flow-add activity
mpagenko15ff4a52021-03-02 10:09:20 +00001225 oFsm.mutexFlowParams.Unlock()
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001226 go func() {
mpagenko15ff4a52021-03-02 10:09:20 +00001227 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001228 tpID := oFsm.actualUniVlanConfigRule.TpID
mpagenko15ff4a52021-03-02 10:09:20 +00001229 configuredUniFlow := oFsm.configuredUniFlow
1230 oFsm.mutexFlowParams.RUnlock()
1231 errEvto := oFsm.performConfigEvtocdEntries(ctx, configuredUniFlow)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001232 //This is correct passing scenario
1233 if errEvto == nil {
1234 //TODO Possibly insert new state for multicast --> possibly another jira/later time.
dbainbri4d3a0dc2020-12-02 00:33:42 +00001235 for _, gemPort := range oFsm.pUniTechProf.getMulticastGemPorts(ctx, oFsm.pOnuUniPort.uniID, uint8(tpID)) {
mpagenko15ff4a52021-03-02 10:09:20 +00001236 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001237 vlanID := oFsm.actualUniVlanConfigRule.SetVid
dbainbri4d3a0dc2020-12-02 00:33:42 +00001238 logger.Infow(ctx, "Setting multicast MEs for additional flows", log.Fields{"deviceID": oFsm.deviceID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001239 "techProfile": tpID, "gemPort": gemPort,
1240 "vlanID": vlanID, "configuredUniFlow": oFsm.configuredUniFlow})
mpagenko15ff4a52021-03-02 10:09:20 +00001241 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001242 errCreateAllMulticastME := oFsm.performSettingMulticastME(ctx, tpID, gemPort, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001243 if errCreateAllMulticastME != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001244 logger.Errorw(ctx, "Multicast ME create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001245 log.Fields{"device-id": oFsm.deviceID})
1246 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1247 }
1248 }
1249 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigEvtocd)
1250 }
1251 }()
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001252}
1253
dbainbri4d3a0dc2020-12-02 00:33:42 +00001254func (oFsm *UniVlanConfigFsm) enterRemoveFlow(ctx context.Context, e *fsm.Event) {
mpagenko551a4d42020-12-08 18:09:20 +00001255 oFsm.mutexFlowParams.RLock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001256 logger.Debugw(ctx, "UniVlanConfigFsm - start removing the top remove-flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001257 "in state": e.FSM.Current(), "with last cookie": oFsm.uniRemoveFlowsSlice[0].cookie,
1258 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001259
mpagenkofc4f56e2020-11-04 17:17:49 +00001260 pConfigVlanStateBaseFsm := oFsm.pAdaptFsm.pFsm
1261 loAllowSpecificOmciConfig := oFsm.pDeviceHandler.ReadyForSpecificOmciConfig
mpagenko01e726e2020-10-23 09:45:29 +00001262 loVlanEntryClear := uint8(0)
1263 loVlanEntryRmPos := uint8(0x80) //with indication 'invalid' in bit 7
1264 //shallow copy is sufficient as no reference variables are used within struct
1265 loRuleParams := oFsm.uniRemoveFlowsSlice[0].vlanRuleParams
mpagenko551a4d42020-12-08 18:09:20 +00001266 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001267 logger.Debugw(ctx, "UniVlanConfigFsm - remove-flow parameters are", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001268 "match vid": loRuleParams.MatchVid, "match Pcp": loRuleParams.MatchPcp,
1269 "set vid": strconv.FormatInt(int64(loRuleParams.SetVid), 16),
1270 "device-id": oFsm.deviceID})
1271
1272 if loRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
1273 // meaning transparent setup - no specific VTFD setting required
dbainbri4d3a0dc2020-12-02 00:33:42 +00001274 logger.Debugw(ctx, "UniVlanConfigFsm: no VTFD removal required for transparent flow", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001275 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
1276 } else {
1277 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization and 're-copy'
1278 if oFsm.numVlanFilterEntries == 1 {
mpagenko551a4d42020-12-08 18:09:20 +00001279 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001280 //only one active VLAN entry (hopefully the SetVID we want to remove - should be, but not verified ..)
1281 // so we can just delete the VTFD entry
dbainbri4d3a0dc2020-12-02 00:33:42 +00001282 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD delete (no more vlan filters)",
mpagenko01e726e2020-10-23 09:45:29 +00001283 log.Fields{"current vlan list": oFsm.vlanFilterList,
1284 "in state": e.FSM.Current(), "device-id": oFsm.deviceID})
mpagenkofc4f56e2020-11-04 17:17:49 +00001285 loVlanEntryClear = 1 //full VlanFilter clear request
1286 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab36ed572021-04-01 10:38:48 +03001287 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001288 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001289 if err != nil {
1290 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1291 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1292 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1293 return
1294 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001295 oFsm.pLastTxMeInstance = meInstance
1296 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001297 logger.Debugw(ctx, "UniVlanConfigFsm delete VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001298 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenkofc4f56e2020-11-04 17:17:49 +00001299 }
mpagenko01e726e2020-10-23 09:45:29 +00001300 } else {
1301 //many VTFD already should exists - find and remove the one concerned by the actual remove rule
1302 // by updating the VTFD per set command with new valid list
dbainbri4d3a0dc2020-12-02 00:33:42 +00001303 logger.Debugw(ctx, "UniVlanConfigFsm: VTFD removal of requested VLAN from the list on OMCI",
mpagenko01e726e2020-10-23 09:45:29 +00001304 log.Fields{"current vlan list": oFsm.vlanFilterList,
1305 "set-vlan": loRuleParams.SetVid, "device-id": oFsm.deviceID})
1306 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1307 if loRuleParams.SetVid == uint32(oFsm.vlanFilterList[i]) {
1308 loVlanEntryRmPos = i
1309 break //abort search
1310 }
1311 }
1312 if loVlanEntryRmPos < cVtfdTableSize {
mpagenko551a4d42020-12-08 18:09:20 +00001313 vtfdID := macBridgePortAniEID + oFsm.pOnuUniPort.entityID + uint16(loRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00001314 //valid entry was found - to be eclipsed
1315 loVlanEntryClear = 2 //VlanFilter remove request for a specific entry
1316 for i := uint8(0); i < oFsm.numVlanFilterEntries; i++ {
1317 if i < loVlanEntryRmPos {
1318 vtfdFilterList[i] = oFsm.vlanFilterList[i] //copy original
1319 } else if i < (cVtfdTableSize - 1) {
1320 vtfdFilterList[i] = oFsm.vlanFilterList[i+1] //copy successor (including 0 elements)
1321 } else {
1322 vtfdFilterList[i] = 0 //set last byte if needed
1323 }
1324 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001325 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001326 "EntitytId": strconv.FormatInt(int64(vtfdID), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001327 "new vlan list": vtfdFilterList, "device-id": oFsm.deviceID})
1328
mpagenkofc4f56e2020-11-04 17:17:49 +00001329 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001330 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
ozgecanetsiab36ed572021-04-01 10:38:48 +03001331 meInstance, err := oFsm.pOmciCC.sendDeleteVtfd(log.WithSpanFromContext(context.TODO(), ctx), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001332 oFsm.pAdaptFsm.commChan, vtfdID)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001333 if err != nil {
1334 logger.Errorw(ctx, "UniVlanFsm delete Vlan Tagging Filter ME result error",
1335 log.Fields{"device-id": oFsm.deviceID, "Error": err})
1336 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1337 return
1338 }
mpagenkofc4f56e2020-11-04 17:17:49 +00001339 oFsm.pLastTxMeInstance = meInstance
1340 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001341 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD OMCI handling skipped based on device state", log.Fields{
Holger Hildebrandtbe523842021-03-10 10:47:18 +00001342 "device-id": oFsm.deviceID, "device-state": oFsm.pDeviceHandler.getDeviceReasonString()})
mpagenko01e726e2020-10-23 09:45:29 +00001343 }
mpagenko01e726e2020-10-23 09:45:29 +00001344 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001345 logger.Warnw(ctx, "UniVlanConfigFsm: requested VLAN for removal not found in list - ignore and continue (no VTFD set)",
mpagenko01e726e2020-10-23 09:45:29 +00001346 log.Fields{"device-id": oFsm.deviceID})
1347 }
1348 }
1349 if loVlanEntryClear > 0 {
mpagenkofc4f56e2020-11-04 17:17:49 +00001350 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
1351 //waiting on response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001352 err := oFsm.waitforOmciResponse(ctx)
mpagenkofc4f56e2020-11-04 17:17:49 +00001353 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001354 logger.Errorw(ctx, "VTFD delete/reset failed, aborting VlanConfig FSM!",
mpagenkofc4f56e2020-11-04 17:17:49 +00001355 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001356 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001357 go func(a_pBaseFsm *fsm.FSM) {
1358 _ = a_pBaseFsm.Event(vlanEvReset)
1359 }(pConfigVlanStateBaseFsm)
1360 return
1361 }
mpagenko01e726e2020-10-23 09:45:29 +00001362 }
1363
mpagenko15ff4a52021-03-02 10:09:20 +00001364 oFsm.mutexFlowParams.Lock()
mpagenko01e726e2020-10-23 09:45:29 +00001365 if loVlanEntryClear == 1 {
1366 oFsm.vlanFilterList[0] = 0 //first entry is the only that can contain the previous only-one element
1367 oFsm.numVlanFilterEntries = 0
1368 } else if loVlanEntryClear == 2 {
1369 // new VlanFilterList should be one entry smaller now - copy from last configured entry
1370 // this loop now includes the 0 element on previous last valid entry
1371 for i := uint8(0); i <= oFsm.numVlanFilterEntries; i++ {
1372 oFsm.vlanFilterList[i] = vtfdFilterList[i]
1373 }
1374 oFsm.numVlanFilterEntries--
1375 }
mpagenko15ff4a52021-03-02 10:09:20 +00001376 oFsm.mutexFlowParams.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00001377 }
1378 }
1379
mpagenkofc4f56e2020-11-04 17:17:49 +00001380 if loAllowSpecificOmciConfig { //specific OMCI config is expected to work acc. to the device state
dbainbri4d3a0dc2020-12-02 00:33:42 +00001381 go oFsm.removeEvtocdEntries(ctx, loRuleParams)
mpagenkofc4f56e2020-11-04 17:17:49 +00001382 } else {
1383 // OMCI processing is not done, expectation is to have the ONU in some basic config state accordingly
dbainbri4d3a0dc2020-12-02 00:33:42 +00001384 logger.Debugw(ctx, "UniVlanConfigFsm remove EVTOCD OMCI handling skipped based on device state", log.Fields{
mpagenkofc4f56e2020-11-04 17:17:49 +00001385 "device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00001386 // Can't call FSM Event directly, decoupling it
mpagenkofc4f56e2020-11-04 17:17:49 +00001387 go func(a_pBaseFsm *fsm.FSM) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001388 _ = a_pBaseFsm.Event(vlanEvRemFlowDone, loRuleParams.TpID)
mpagenkofc4f56e2020-11-04 17:17:49 +00001389 }(pConfigVlanStateBaseFsm)
1390 }
mpagenkodff5dda2020-08-28 11:52:01 +00001391}
1392
dbainbri4d3a0dc2020-12-02 00:33:42 +00001393func (oFsm *UniVlanConfigFsm) enterVlanCleanupDone(ctx context.Context, e *fsm.Event) {
Girish Gowdra26a40922021-01-29 17:14:34 -08001394 var tpID uint8
1395 // Extract the tpID
1396 if len(e.Args) > 0 {
1397 tpID = e.Args[0].(uint8)
1398 logger.Debugw(ctx, "UniVlanConfigFsm - flow removed for tp id", log.Fields{"device-id": oFsm.deviceID, "tpID": e.Args[0].(uint8)})
1399 } else {
1400 logger.Warnw(ctx, "UniVlanConfigFsm - tp id not available", log.Fields{"device-id": oFsm.deviceID})
1401 }
mpagenko01e726e2020-10-23 09:45:29 +00001402 oFsm.mutexFlowParams.Lock()
mpagenkof1fc3862021-02-16 10:09:52 +00001403 deletedCookie := oFsm.uniRemoveFlowsSlice[0].cookie
1404 logger.Debugw(ctx, "UniVlanConfigFsm - removing the removal data", log.Fields{
1405 "in state": e.FSM.Current(), "device-id": oFsm.deviceID,
1406 "removed cookie": deletedCookie, "waitForDeleteCookie": oFsm.delayNewRuleCookie})
1407
mpagenko01e726e2020-10-23 09:45:29 +00001408 if len(oFsm.uniRemoveFlowsSlice) <= 1 {
1409 oFsm.uniRemoveFlowsSlice = nil //reset the slice
dbainbri4d3a0dc2020-12-02 00:33:42 +00001410 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - last remove-flow deleted", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001411 "device-id": oFsm.deviceID})
1412 } else {
1413 //cut off the actual flow by slicing out the first element
1414 oFsm.uniRemoveFlowsSlice = append(
1415 oFsm.uniRemoveFlowsSlice[:0],
1416 oFsm.uniRemoveFlowsSlice[1:]...)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001417 logger.Debugw(ctx, "UniVlanConfigFsm flow removal - specific flow deleted from data", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001418 "device-id": oFsm.deviceID})
1419 }
1420 oFsm.mutexFlowParams.Unlock()
1421
mpagenkof1fc3862021-02-16 10:09:52 +00001422 oFsm.requestEventOffset = uint8(cDeviceEventOffsetRemoveWithKvStore) //offset for last flow-remove activity (with kvStore request)
mpagenko01e726e2020-10-23 09:45:29 +00001423 //return to the basic config verification state
mpagenkodff5dda2020-08-28 11:52:01 +00001424 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1425 if pConfigVlanStateAFsm != nil {
mpagenko9a304ea2020-12-16 15:54:01 +00001426 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001427 go func(a_pAFsm *AdapterFsm) {
1428 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
mpagenko01e726e2020-10-23 09:45:29 +00001429 _ = a_pAFsm.pFsm.Event(vlanEvFlowDataRemoved)
mpagenkodff5dda2020-08-28 11:52:01 +00001430 }
1431 }(pConfigVlanStateAFsm)
1432 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001433
mpagenkobb47bc22021-04-20 13:29:09 +00001434 oFsm.mutexFlowParams.Lock()
Girish Gowdra26a40922021-01-29 17:14:34 -08001435 noOfFlowRem := len(oFsm.uniRemoveFlowsSlice)
mpagenkof1fc3862021-02-16 10:09:52 +00001436 if deletedCookie == oFsm.delayNewRuleCookie {
1437 // flush the channel CookieDeleted to ensure it is not lingering from some previous (aborted) activity
1438 select {
1439 case <-oFsm.chCookieDeleted:
1440 logger.Debug(ctx, "flushed CookieDeleted")
1441 default:
1442 }
1443 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue
1444 }
mpagenkobb47bc22021-04-20 13:29:09 +00001445 // If all pending flow-removes are completed and TP ID is valid go on processing any pending TP delete
1446 if oFsm.signalOnFlowDelete && noOfFlowRem == 0 && tpID > 0 {
1447 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 -08001448 // If we are here then all flows are removed.
mpagenkobb47bc22021-04-20 13:29:09 +00001449 if len(oFsm.flowDeleteChannel) == 0 { //channel not yet in use
1450 oFsm.flowDeleteChannel <- true
1451 oFsm.signalOnFlowDelete = false
1452 }
Girish Gowdra26a40922021-01-29 17:14:34 -08001453 }
mpagenkobb47bc22021-04-20 13:29:09 +00001454 oFsm.mutexFlowParams.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001455}
1456
dbainbri4d3a0dc2020-12-02 00:33:42 +00001457func (oFsm *UniVlanConfigFsm) enterResetting(ctx context.Context, e *fsm.Event) {
1458 logger.Debugw(ctx, "UniVlanConfigFsm resetting", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001459
1460 pConfigVlanStateAFsm := oFsm.pAdaptFsm
1461 if pConfigVlanStateAFsm != nil {
1462 // abort running message processing
1463 fsmAbortMsg := Message{
1464 Type: TestMsg,
1465 Data: TestMessage{
1466 TestMessageVal: AbortMessageProcessing,
1467 },
1468 }
1469 pConfigVlanStateAFsm.commChan <- fsmAbortMsg
1470
mpagenko9a304ea2020-12-16 15:54:01 +00001471 //try to restart the FSM to 'disabled'
1472 // Can't call FSM Event directly, decoupling it
mpagenkodff5dda2020-08-28 11:52:01 +00001473 go func(a_pAFsm *AdapterFsm) {
1474 if a_pAFsm != nil && a_pAFsm.pFsm != nil {
Himani Chawla4d908332020-08-31 12:30:20 +05301475 _ = a_pAFsm.pFsm.Event(vlanEvRestart)
mpagenkodff5dda2020-08-28 11:52:01 +00001476 }
1477 }(pConfigVlanStateAFsm)
1478 }
1479}
1480
dbainbri4d3a0dc2020-12-02 00:33:42 +00001481func (oFsm *UniVlanConfigFsm) enterDisabled(ctx context.Context, e *fsm.Event) {
1482 logger.Debugw(ctx, "UniVlanConfigFsm enters disabled state", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00001483 oFsm.pLastTxMeInstance = nil
mpagenkodff5dda2020-08-28 11:52:01 +00001484 if oFsm.pDeviceHandler != nil {
mpagenko2418ab02020-11-12 12:58:06 +00001485 //TODO: to clarify with improved error treatment for VlanConfigFsm (timeout,reception) errors
1486 // current code removes the complete FSM including all flow/rule configuration done so far
1487 // this might be a bit to much, it would require fully new flow config from rwCore (at least on OnuDown/up)
1488 // maybe a more sophisticated approach is possible without clearing the data
mpagenko9a304ea2020-12-16 15:54:01 +00001489 oFsm.mutexFlowParams.RLock()
mpagenko2418ab02020-11-12 12:58:06 +00001490 if oFsm.clearPersistency {
1491 //permanently remove possibly stored persistent data
1492 if len(oFsm.uniVlanFlowParamsSlice) > 0 {
1493 var emptySlice = make([]uniVlanFlowParams, 0)
mpagenkof1fc3862021-02-16 10:09:52 +00001494 _ = oFsm.pDeviceHandler.storePersUniFlowConfig(ctx, oFsm.pOnuUniPort.uniID, &emptySlice, true) //ignore errors
mpagenko2418ab02020-11-12 12:58:06 +00001495 }
1496 } else {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001497 logger.Debugw(ctx, "UniVlanConfigFsm persistency data not cleared", log.Fields{"device-id": oFsm.deviceID})
mpagenko2418ab02020-11-12 12:58:06 +00001498 }
mpagenkof1fc3862021-02-16 10:09:52 +00001499 if oFsm.delayNewRuleCookie != 0 {
1500 // looks like the waiting AddFlow is stuck
1501 oFsm.chCookieDeleted <- true // let the waiting AddFlow thread continue/treminate
1502 }
mpagenko9a304ea2020-12-16 15:54:01 +00001503 oFsm.mutexFlowParams.RUnlock()
mpagenko2418ab02020-11-12 12:58:06 +00001504 //request removal of 'reference' in the Handler (completely clear the FSM and its data)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001505 go oFsm.pDeviceHandler.RemoveVlanFilterFsm(ctx, oFsm.pOnuUniPort)
mpagenkodff5dda2020-08-28 11:52:01 +00001506 }
1507}
1508
dbainbri4d3a0dc2020-12-02 00:33:42 +00001509func (oFsm *UniVlanConfigFsm) processOmciVlanMessages(ctx context.Context) { //ctx context.Context?
1510 logger.Debugw(ctx, "Start UniVlanConfigFsm Msg processing", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001511loop:
1512 for {
mpagenkodff5dda2020-08-28 11:52:01 +00001513 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00001514 // logger.Info(ctx,"MibSync Msg", log.Fields{"Message handling canceled via context for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001515 // break loop
Himani Chawla4d908332020-08-31 12:30:20 +05301516 message, ok := <-oFsm.pAdaptFsm.commChan
1517 if !ok {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001518 logger.Info(ctx, "UniVlanConfigFsm Rx Msg - could not read from channel", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301519 // but then we have to ensure a restart of the FSM as well - as exceptional procedure
1520 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1521 break loop
1522 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001523 logger.Debugw(ctx, "UniVlanConfigFsm Rx Msg", log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301524
1525 switch message.Type {
1526 case TestMsg:
1527 msg, _ := message.Data.(TestMessage)
1528 if msg.TestMessageVal == AbortMessageProcessing {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001529 logger.Infow(ctx, "UniVlanConfigFsm abort ProcessMsg", log.Fields{"for device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001530 break loop
1531 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001532 logger.Warnw(ctx, "UniVlanConfigFsm unknown TestMessage", log.Fields{"device-id": oFsm.deviceID, "MessageVal": msg.TestMessageVal})
Himani Chawla4d908332020-08-31 12:30:20 +05301533 case OMCI:
1534 msg, _ := message.Data.(OmciMessage)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001535 oFsm.handleOmciVlanConfigMessage(ctx, msg)
Himani Chawla4d908332020-08-31 12:30:20 +05301536 default:
dbainbri4d3a0dc2020-12-02 00:33:42 +00001537 logger.Warn(ctx, "UniVlanConfigFsm Rx unknown message", log.Fields{"device-id": oFsm.deviceID,
Himani Chawla4d908332020-08-31 12:30:20 +05301538 "message.Type": message.Type})
mpagenkodff5dda2020-08-28 11:52:01 +00001539 }
1540 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001541 logger.Infow(ctx, "End UniVlanConfigFsm Msg processing", log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001542}
1543
dbainbri4d3a0dc2020-12-02 00:33:42 +00001544func (oFsm *UniVlanConfigFsm) handleOmciVlanConfigMessage(ctx context.Context, msg OmciMessage) {
1545 logger.Debugw(ctx, "Rx OMCI UniVlanConfigFsm Msg", log.Fields{"device-id": oFsm.deviceID,
mpagenkodff5dda2020-08-28 11:52:01 +00001546 "msgType": msg.OmciMsg.MessageType})
1547
1548 switch msg.OmciMsg.MessageType {
1549 case omci.CreateResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001550 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001551 if err := oFsm.handleOmciCreateResponseMessage(ctx, msg.OmciPacket); err != nil {
1552 logger.Warnw(ctx, "CreateResponse handling aborted", log.Fields{"err": err})
mpagenkodff5dda2020-08-28 11:52:01 +00001553 return
1554 }
mpagenkodff5dda2020-08-28 11:52:01 +00001555 } //CreateResponseType
1556 case omci.SetResponseType:
mpagenko01e726e2020-10-23 09:45:29 +00001557 { //leave that here as direct code as most often used
mpagenkodff5dda2020-08-28 11:52:01 +00001558 msgLayer := (*msg.OmciPacket).Layer(omci.LayerTypeSetResponse)
1559 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001560 logger.Errorw(ctx, "Omci Msg layer could not be detected for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001561 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001562 return
1563 }
1564 msgObj, msgOk := msgLayer.(*omci.SetResponse)
1565 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001566 logger.Errorw(ctx, "Omci Msg layer could not be assigned for SetResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001567 log.Fields{"device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001568 return
1569 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001570 logger.Debugw(ctx, "UniVlanConfigFsm SetResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenkodff5dda2020-08-28 11:52:01 +00001571 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001572 logger.Errorw(ctx, "UniVlanConfigFsm Omci SetResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001573 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
mpagenkodff5dda2020-08-28 11:52:01 +00001574 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1575 return
1576 }
mpagenko01e726e2020-10-23 09:45:29 +00001577 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1578 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1579 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001580 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData", "MulticastOperationsProfile":
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001581 { // let the MultiEntity config proceed by stopping the wait function
mpagenkodff5dda2020-08-28 11:52:01 +00001582 oFsm.omciMIdsResponseReceived <- true
1583 }
1584 }
1585 }
1586 } //SetResponseType
mpagenko01e726e2020-10-23 09:45:29 +00001587 case omci.DeleteResponseType:
1588 { // had to shift that to a method to cope with StaticCodeAnalysis restrictions :-(
dbainbri4d3a0dc2020-12-02 00:33:42 +00001589 if err := oFsm.handleOmciDeleteResponseMessage(ctx, msg.OmciPacket); err != nil {
1590 logger.Warnw(ctx, "DeleteResponse handling aborted", log.Fields{"err": err})
mpagenko01e726e2020-10-23 09:45:29 +00001591 return
1592 }
1593 } //DeleteResponseType
mpagenkodff5dda2020-08-28 11:52:01 +00001594 default:
1595 {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001596 logger.Errorw(ctx, "Rx OMCI unhandled MsgType",
mpagenko01e726e2020-10-23 09:45:29 +00001597 log.Fields{"omciMsgType": msg.OmciMsg.MessageType, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001598 return
1599 }
1600 }
1601}
1602
dbainbri4d3a0dc2020-12-02 00:33:42 +00001603func (oFsm *UniVlanConfigFsm) handleOmciCreateResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001604 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeCreateResponse)
1605 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001606 logger.Errorw(ctx, "Omci Msg layer could not be detected for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001607 log.Fields{"device-id": oFsm.deviceID})
1608 return fmt.Errorf("omci msg layer could not be detected for CreateResponse for device-id %x",
1609 oFsm.deviceID)
1610 }
1611 msgObj, msgOk := msgLayer.(*omci.CreateResponse)
1612 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001613 logger.Errorw(ctx, "Omci Msg layer could not be assigned for CreateResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001614 log.Fields{"device-id": oFsm.deviceID})
1615 return fmt.Errorf("omci msg layer could not be assigned for CreateResponse for device-id %x",
1616 oFsm.deviceID)
1617 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001618 logger.Debugw(ctx, "UniVlanConfigFsm CreateResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001619 if msgObj.Result != me.Success && msgObj.Result != me.InstanceExists {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001620 logger.Errorw(ctx, "Omci CreateResponse Error - later: drive FSM to abort state ?", log.Fields{"device-id": oFsm.deviceID,
mpagenko01e726e2020-10-23 09:45:29 +00001621 "Error": msgObj.Result})
1622 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1623 return fmt.Errorf("omci CreateResponse Error for device-id %x",
1624 oFsm.deviceID)
1625 }
1626 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1627 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1628 // to satisfy StaticCodeAnalysis I had to move the small processing into a separate method :-(
1629 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001630 case "VlanTaggingFilterData", "MulticastOperationsProfile",
1631 "MulticastSubscriberConfigInfo", "MacBridgePortConfigurationData",
1632 "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001633 {
1634 if oFsm.pAdaptFsm.pFsm.Current() == vlanStConfigVtfd {
1635 // Only if CreateResponse is received from first flow entry - let the FSM proceed ...
1636 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRxConfigVtfd)
1637 } else { // let the MultiEntity config proceed by stopping the wait function
1638 oFsm.omciMIdsResponseReceived <- true
1639 }
1640 }
1641 }
1642 }
1643 return nil
1644}
1645
dbainbri4d3a0dc2020-12-02 00:33:42 +00001646func (oFsm *UniVlanConfigFsm) handleOmciDeleteResponseMessage(ctx context.Context, apOmciPacket *gp.Packet) error {
mpagenko01e726e2020-10-23 09:45:29 +00001647 msgLayer := (*apOmciPacket).Layer(omci.LayerTypeDeleteResponse)
1648 if msgLayer == nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001649 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be detected for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001650 log.Fields{"device-id": oFsm.deviceID})
1651 return fmt.Errorf("omci msg layer could not be detected for DeleteResponse for device-id %x",
1652 oFsm.deviceID)
1653 }
1654 msgObj, msgOk := msgLayer.(*omci.DeleteResponse)
1655 if !msgOk {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001656 logger.Errorw(ctx, "UniVlanConfigFsm - Omci Msg layer could not be assigned for DeleteResponse",
mpagenko01e726e2020-10-23 09:45:29 +00001657 log.Fields{"device-id": oFsm.deviceID})
1658 return fmt.Errorf("omci msg layer could not be assigned for DeleteResponse for device-id %x",
1659 oFsm.deviceID)
1660 }
dbainbri4d3a0dc2020-12-02 00:33:42 +00001661 logger.Debugw(ctx, "UniVlanConfigFsm DeleteResponse Data", log.Fields{"device-id": oFsm.deviceID, "data-fields": msgObj})
mpagenko01e726e2020-10-23 09:45:29 +00001662 if msgObj.Result != me.Success {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001663 logger.Errorw(ctx, "UniVlanConfigFsm - Omci DeleteResponse Error - later: drive FSM to abort state ?",
mpagenko01e726e2020-10-23 09:45:29 +00001664 log.Fields{"device-id": oFsm.deviceID, "Error": msgObj.Result})
1665 // possibly force FSM into abort or ignore some errors for some messages? store error for mgmt display?
1666 return fmt.Errorf("omci DeleteResponse Error for device-id %x",
1667 oFsm.deviceID)
1668 }
1669 if msgObj.EntityClass == oFsm.pLastTxMeInstance.GetClassID() &&
1670 msgObj.EntityInstance == oFsm.pLastTxMeInstance.GetEntityID() {
1671 switch oFsm.pLastTxMeInstance.GetName() {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001672 case "VlanTaggingFilterData", "ExtendedVlanTaggingOperationConfigurationData":
mpagenko01e726e2020-10-23 09:45:29 +00001673 { // let the MultiEntity config proceed by stopping the wait function
1674 oFsm.omciMIdsResponseReceived <- true
1675 }
1676 }
1677 }
1678 return nil
1679}
1680
dbainbri4d3a0dc2020-12-02 00:33:42 +00001681func (oFsm *UniVlanConfigFsm) performConfigEvtocdEntries(ctx context.Context, aFlowEntryNo uint8) error {
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001682 if aFlowEntryNo == 0 {
1683 // EthType set only at first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001684 // EVTOCD ME is expected to exist at this point already from MIB-Download (with AssociationType/Pointer)
1685 // we need to extend the configuration by EthType definition and, to be sure, downstream 'inverse' mode
dbainbri4d3a0dc2020-12-02 00:33:42 +00001686 logger.Debugw(ctx, "UniVlanConfigFsm Tx Create::EVTOCD", log.Fields{
mpagenkodff5dda2020-08-28 11:52:01 +00001687 "EntitytId": strconv.FormatInt(int64(oFsm.evtocdID), 16),
1688 "i/oEthType": strconv.FormatInt(int64(cDefaultTpid), 16),
mpagenko01e726e2020-10-23 09:45:29 +00001689 "device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001690 associationType := 2 // default to uniPPTP
1691 if oFsm.pOnuUniPort.portType == uniVEIP {
1692 associationType = 10
1693 }
1694 // Create the EVTOCD ME
mpagenkodff5dda2020-08-28 11:52:01 +00001695 meParams := me.ParamData{
1696 EntityID: oFsm.evtocdID,
1697 Attributes: me.AttributeValueMap{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001698 "AssociationType": uint8(associationType),
1699 "AssociatedMePointer": oFsm.pOnuUniPort.entityID,
mpagenkodff5dda2020-08-28 11:52:01 +00001700 },
1701 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001702 meInstance, err := oFsm.pOmciCC.sendCreateEvtocdVar(context.TODO(), oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout,
1703 true, oFsm.pAdaptFsm.commChan, meParams)
1704 if err != nil {
1705 logger.Errorw(ctx, "CreateEvtocdVar create failed, aborting UniVlanConfigFsm!",
1706 log.Fields{"device-id": oFsm.deviceID})
1707 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1708 return fmt.Errorf("evtocd instance create failed %s, error %s", oFsm.deviceID, err)
1709 }
mpagenkodff5dda2020-08-28 11:52:01 +00001710 //accept also nil as (error) return value for writing to LastTx
1711 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001712 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001713
1714 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001715 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001716 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001717 logger.Errorw(ctx, "Evtocd create failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001718 log.Fields{"device-id": oFsm.deviceID})
1719 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1720 return fmt.Errorf("evtocd create failed %s, error %s", oFsm.deviceID, err)
1721 }
1722
1723 // Set the EVTOCD ME default params
1724 meParams = me.ParamData{
1725 EntityID: oFsm.evtocdID,
1726 Attributes: me.AttributeValueMap{
1727 "InputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1728 "OutputTpid": uint16(cDefaultTpid), //could be possibly retrieved from flow config one day, by now just like py-code base
1729 "DownstreamMode": uint8(cDefaultDownstreamMode),
1730 },
1731 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001732 meInstance, err = oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1733 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001734 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001735 if err != nil {
1736 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1737 log.Fields{"device-id": oFsm.deviceID})
1738 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1739 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1740 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001741 //accept also nil as (error) return value for writing to LastTx
1742 // - this avoids misinterpretation of new received OMCI messages
1743 oFsm.pLastTxMeInstance = meInstance
1744
1745 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00001746 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001747 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001748 logger.Errorw(ctx, "Evtocd set TPID failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001749 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301750 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001751 return fmt.Errorf("evtocd set TPID failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001752 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001753 } //first flow element
mpagenkodff5dda2020-08-28 11:52:01 +00001754
mpagenko551a4d42020-12-08 18:09:20 +00001755 oFsm.mutexFlowParams.RLock()
mpagenko9a304ea2020-12-16 15:54:01 +00001756 if oFsm.actualUniVlanConfigRule.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
mpagenkodff5dda2020-08-28 11:52:01 +00001757 //transparent transmission required
mpagenko551a4d42020-12-08 18:09:20 +00001758 oFsm.mutexFlowParams.RUnlock()
dbainbri4d3a0dc2020-12-02 00:33:42 +00001759 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged transparent rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001760 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001761 sliceEvtocdRule := make([]uint8, 16)
1762 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1763 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1764 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1765 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1766 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1767
1768 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1769 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
1770 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1771 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1772 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1773
1774 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1775 0<<cTreatTTROffset| // Do not pop any tags
1776 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1777 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1778 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1779
1780 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1781 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
1782 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1783 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1784
1785 meParams := me.ParamData{
1786 EntityID: oFsm.evtocdID,
1787 Attributes: me.AttributeValueMap{
1788 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1789 },
1790 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001791 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1792 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001793 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001794 if err != nil {
1795 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1796 log.Fields{"device-id": oFsm.deviceID})
1797 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1798 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1799 }
mpagenkodff5dda2020-08-28 11:52:01 +00001800 //accept also nil as (error) return value for writing to LastTx
1801 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001802 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001803
1804 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001805 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001806 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001807 logger.Errorw(ctx, "Evtocd set transparent singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001808 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301809 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001810 return fmt.Errorf("evtocd set transparent singletagged rule failed %s, error %s", oFsm.deviceID, err)
1811
mpagenkodff5dda2020-08-28 11:52:01 +00001812 }
1813 } else {
1814 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
1815 if oFsm.acceptIncrementalEvtoOption {
mpagenko9a304ea2020-12-16 15:54:01 +00001816 matchPcp := oFsm.actualUniVlanConfigRule.MatchPcp
1817 matchVid := oFsm.actualUniVlanConfigRule.MatchVid
1818 setPcp := oFsm.actualUniVlanConfigRule.SetPcp
1819 setVid := oFsm.actualUniVlanConfigRule.SetVid
mpagenkodff5dda2020-08-28 11:52:01 +00001820 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00001821 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD single tagged translation rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001822 "match-pcp": matchPcp, "match-vid": matchVid, "set-pcp": setPcp, "set-vid:": setVid, "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001823 sliceEvtocdRule := make([]uint8, 16)
1824 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1825 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1826 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1827 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1828 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1829
1830 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001831 oFsm.actualUniVlanConfigRule.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
1832 oFsm.actualUniVlanConfigRule.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
mpagenkodff5dda2020-08-28 11:52:01 +00001833 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1834 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1835
1836 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001837 oFsm.actualUniVlanConfigRule.TagsToRemove<<cTreatTTROffset| // either 1 or 0
mpagenkodff5dda2020-08-28 11:52:01 +00001838 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1839 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1840 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1841
1842 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
mpagenko9a304ea2020-12-16 15:54:01 +00001843 oFsm.actualUniVlanConfigRule.SetPcp<<cTreatPrioOffset| // as configured in flow
1844 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| //as configured in flow
mpagenkodff5dda2020-08-28 11:52:01 +00001845 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001846 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001847
1848 meParams := me.ParamData{
1849 EntityID: oFsm.evtocdID,
1850 Attributes: me.AttributeValueMap{
1851 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1852 },
1853 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001854 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1855 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001856 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001857 if err != nil {
1858 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1859 log.Fields{"device-id": oFsm.deviceID})
1860 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1861 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1862 }
mpagenkodff5dda2020-08-28 11:52:01 +00001863 //accept also nil as (error) return value for writing to LastTx
1864 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001865 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001866
1867 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001868 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001869 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001870 logger.Errorw(ctx, "Evtocd set singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001871 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301872 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001873 return fmt.Errorf("evtocd set singletagged translation rule failed %s, error %s", oFsm.deviceID, err)
mpagenkodff5dda2020-08-28 11:52:01 +00001874 }
1875 } else {
1876 //not transparent and not acceptIncrementalEvtoOption untagged/priotagged->singletagged
1877 { // just for local var's
1878 // this defines stacking scenario: untagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001879 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD untagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001880 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001881 sliceEvtocdRule := make([]uint8, 16)
1882 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1883 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1884 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1885 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1886 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1887
1888 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1889 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
1890 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
1891 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1892 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1893
1894 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1895 0<<cTreatTTROffset| // Do not pop any tags
1896 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1897 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1898 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1899
1900 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1901 0<<cTreatPrioOffset| // vlan prio set to 0
1902 // (as done in Py code, maybe better option would be setPcp here, which still could be 0?)
mpagenko9a304ea2020-12-16 15:54:01 +00001903 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID don't care
mpagenkodff5dda2020-08-28 11:52:01 +00001904 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
1905
mpagenko551a4d42020-12-08 18:09:20 +00001906 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001907 meParams := me.ParamData{
1908 EntityID: oFsm.evtocdID,
1909 Attributes: me.AttributeValueMap{
1910 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1911 },
1912 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001913 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1914 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001915 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001916 if err != nil {
1917 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1918 log.Fields{"device-id": oFsm.deviceID})
1919 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1920 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1921 }
mpagenkodff5dda2020-08-28 11:52:01 +00001922 //accept also nil as (error) return value for writing to LastTx
1923 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001924 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001925
1926 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001927 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001928 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001929 logger.Errorw(ctx, "Evtocd set untagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001930 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301931 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001932 return fmt.Errorf("evtocd set untagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1933
mpagenkodff5dda2020-08-28 11:52:01 +00001934 }
Holger Hildebrandt394c5522020-09-11 11:23:01 +00001935 } // just for local var's
mpagenkodff5dda2020-08-28 11:52:01 +00001936 { // just for local var's
1937 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00001938 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD priotagged->singletagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00001939 "device-id": oFsm.deviceID})
mpagenkodff5dda2020-08-28 11:52:01 +00001940 sliceEvtocdRule := make([]uint8, 16)
1941 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
1942 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
1943 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
1944 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
1945 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
1946
1947 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
1948 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
1949 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
1950 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
1951 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
1952
1953 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
1954 1<<cTreatTTROffset| // pop the prio-tag
1955 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
1956 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
1957 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
1958
mpagenko551a4d42020-12-08 18:09:20 +00001959 oFsm.mutexFlowParams.RLock()
mpagenkodff5dda2020-08-28 11:52:01 +00001960 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
1961 cCopyPrioFromInner<<cTreatPrioOffset| // vlan copy from PrioTag
1962 // (as done in Py code, maybe better option would be setPcp here, which still could be PrioCopy?)
mpagenko9a304ea2020-12-16 15:54:01 +00001963 oFsm.actualUniVlanConfigRule.SetVid<<cTreatVidOffset| // Outer VID as configured
mpagenkodff5dda2020-08-28 11:52:01 +00001964 cSetOutputTpidCopyDei<<cTreatTpidOffset) // Set TPID = 0x8100
mpagenko551a4d42020-12-08 18:09:20 +00001965 oFsm.mutexFlowParams.RUnlock()
mpagenkodff5dda2020-08-28 11:52:01 +00001966
1967 meParams := me.ParamData{
1968 EntityID: oFsm.evtocdID,
1969 Attributes: me.AttributeValueMap{
1970 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
1971 },
1972 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03001973 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
1974 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenkodff5dda2020-08-28 11:52:01 +00001975 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03001976 if err != nil {
1977 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
1978 log.Fields{"device-id": oFsm.deviceID})
1979 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
1980 return fmt.Errorf("evtocd instance set failed %s, error %s", oFsm.deviceID, err)
1981 }
mpagenkodff5dda2020-08-28 11:52:01 +00001982 //accept also nil as (error) return value for writing to LastTx
1983 // - this avoids misinterpretation of new received OMCI messages
mpagenko01e726e2020-10-23 09:45:29 +00001984 oFsm.pLastTxMeInstance = meInstance
mpagenkodff5dda2020-08-28 11:52:01 +00001985
1986 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03001987 err = oFsm.waitforOmciResponse(ctx)
mpagenkodff5dda2020-08-28 11:52:01 +00001988 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00001989 logger.Errorw(ctx, "Evtocd set priotagged->singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00001990 log.Fields{"device-id": oFsm.deviceID})
Himani Chawla4d908332020-08-31 12:30:20 +05301991 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03001992 return fmt.Errorf("evtocd set priotagged->singletagged rule failed %s, error %s", oFsm.deviceID, err)
1993
mpagenkodff5dda2020-08-28 11:52:01 +00001994 }
1995 } //just for local var's
1996 }
1997 }
1998
mpagenkofc4f56e2020-11-04 17:17:49 +00001999 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002000 logger.Debugw(ctx, "EVTOCD set loop finished", log.Fields{"device-id": oFsm.deviceID})
mpagenko01e726e2020-10-23 09:45:29 +00002001 oFsm.configuredUniFlow++ // one (more) flow configured
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002002 return nil
mpagenkodff5dda2020-08-28 11:52:01 +00002003}
2004
dbainbri4d3a0dc2020-12-02 00:33:42 +00002005func (oFsm *UniVlanConfigFsm) removeEvtocdEntries(ctx context.Context, aRuleParams uniVlanRuleParams) {
mpagenko01e726e2020-10-23 09:45:29 +00002006 // configured Input/Output TPID is not modified again - no influence if no filter is applied
2007 if aRuleParams.SetVid == uint32(of.OfpVlanId_OFPVID_PRESENT) {
2008 //transparent transmission was set
2009 //perhaps the config is not needed for removal,
2010 // but the specific InnerTpid setting is removed in favor of the real default forwarding rule
dbainbri4d3a0dc2020-12-02 00:33:42 +00002011 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset to default single tagged rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002012 "device-id": oFsm.deviceID})
2013 sliceEvtocdRule := make([]uint8, 16)
2014 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2015 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2016 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2017 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2018 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2019
2020 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2021 cPrioDefaultFilter<<cFilterPrioOffset| // default inner-tag rule
2022 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2023 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2024 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2025
2026 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2027 0<<cTreatTTROffset| // Do not pop any tags
2028 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2029 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2030 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
2031
2032 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2033 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2034 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2035 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
2036
2037 meParams := me.ParamData{
2038 EntityID: oFsm.evtocdID,
2039 Attributes: me.AttributeValueMap{
2040 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2041 },
2042 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002043 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2044 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002045 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002046 if err != nil {
2047 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2048 log.Fields{"device-id": oFsm.deviceID})
2049 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2050 return
2051 }
mpagenko01e726e2020-10-23 09:45:29 +00002052 //accept also nil as (error) return value for writing to LastTx
2053 // - this avoids misinterpretation of new received OMCI messages
2054 oFsm.pLastTxMeInstance = meInstance
2055
2056 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002057 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002058 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002059 logger.Errorw(ctx, "Evtocd reset singletagged rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002060 log.Fields{"device-id": oFsm.deviceID})
2061 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2062 return
2063 }
2064 } else {
2065 // according to py-code acceptIncrementalEvto program option decides upon stacking or translation scenario
2066 if oFsm.acceptIncrementalEvtoOption {
2067 // this defines VID translation scenario: singletagged->singletagged (if not transparent)
dbainbri4d3a0dc2020-12-02 00:33:42 +00002068 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD clear single tagged translation rule", log.Fields{
mpagenko01e726e2020-10-23 09:45:29 +00002069 "device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2070 sliceEvtocdRule := make([]uint8, 16)
2071 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2072 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2073 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2074 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2075 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2076
2077 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2078 aRuleParams.MatchPcp<<cFilterPrioOffset| // either DNFonPrio or ignore tag (default) on innerVLAN
2079 aRuleParams.MatchVid<<cFilterVidOffset| // either DNFonVid or real filter VID
2080 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2081 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2082
2083 // delete indication for the indicated Filter
2084 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2085 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2086
2087 meParams := me.ParamData{
2088 EntityID: oFsm.evtocdID,
2089 Attributes: me.AttributeValueMap{
2090 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2091 },
2092 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002093 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2094 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002095 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002096 if err != nil {
2097 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2098 log.Fields{"device-id": oFsm.deviceID})
2099 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2100 return
2101 }
mpagenko01e726e2020-10-23 09:45:29 +00002102 //accept also nil as (error) return value for writing to LastTx
2103 // - this avoids misinterpretation of new received OMCI messages
2104 oFsm.pLastTxMeInstance = meInstance
2105
2106 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002107 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002108 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002109 logger.Errorw(ctx, "Evtocd clear singletagged translation rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002110 log.Fields{"device-id": oFsm.deviceID, "match-vlan": aRuleParams.MatchVid})
2111 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2112 return
2113 }
2114 } else {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002115 // VOL-3685
2116 // NOTE: With ALPHA ONUs it was seen that just resetting a particular entry in the EVTOCD table
2117 // and re-configuring a new entry would not work. The old entry is removed and new entry is created
2118 // indeed, but the traffic landing upstream would carry old vlan sometimes.
2119 // This is only a WORKAROUND which basically deletes the entire EVTOCD ME and re-creates it again
2120 // later when the flow is being re-installed.
2121 // Of course this is applicable to case only where single service (or single tcont) is in use and
2122 // there is only one service vlan (oFsm.acceptIncrementalEvtoOption is false in this case).
2123 // Interstingly this problem has not been observed in multi-tcont (or multi-service) scenario (in
2124 // which case the oFsm.acceptIncrementalEvtoOption is set to true).
2125 if oFsm.configuredUniFlow == 0 && !oFsm.acceptIncrementalEvtoOption {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002126 logger.Debugw(ctx, "UniVlanConfigFsm Tx Remove::EVTOCD", log.Fields{"device-id": oFsm.deviceID})
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002127 // When there are no more EVTOCD vlan configurations on the ONU and acceptIncrementalEvtoOption
2128 // is not enabled, delete the EVTOCD ME.
mpagenko01e726e2020-10-23 09:45:29 +00002129 meParams := me.ParamData{
2130 EntityID: oFsm.evtocdID,
mpagenko01e726e2020-10-23 09:45:29 +00002131 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002132 meInstance, err := oFsm.pOmciCC.sendDeleteEvtocd(log.WithSpanFromContext(context.TODO(), ctx),
2133 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
mpagenko01e726e2020-10-23 09:45:29 +00002134 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002135 if err != nil {
2136 logger.Errorw(ctx, "DeleteEvtocdVar delete failed, aborting UniVlanConfigFsm!",
2137 log.Fields{"device-id": oFsm.deviceID})
2138 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2139 return
2140 }
mpagenko01e726e2020-10-23 09:45:29 +00002141 //accept also nil as (error) return value for writing to LastTx
2142 // - this avoids misinterpretation of new received OMCI messages
2143 oFsm.pLastTxMeInstance = meInstance
2144
2145 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002146 err = oFsm.waitforOmciResponse(ctx)
mpagenko01e726e2020-10-23 09:45:29 +00002147 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002148 logger.Errorw(ctx, "Evtocd delete rule failed, aborting VlanConfig FSM!",
mpagenko01e726e2020-10-23 09:45:29 +00002149 log.Fields{"device-id": oFsm.deviceID})
2150 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2151 return
2152 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002153 } else {
2154 // NOTE : We should ideally never ether this section when oFsm.acceptIncrementalEvtoOption is set to false
2155 // This is true for only ATT/DT workflow
dbainbri4d3a0dc2020-12-02 00:33:42 +00002156 logger.Debugw(ctx, "UniVlanConfigFsm: Remove EVTOCD set operation",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002157 log.Fields{"configured-flow": oFsm.configuredUniFlow, "incremental-evto": oFsm.acceptIncrementalEvtoOption})
2158 //not transparent and not acceptIncrementalEvtoOption: untagged/priotagged->singletagged
2159 { // just for local var's
2160 // this defines stacking scenario: untagged->singletagged
2161 //TODO!! in theory there could be different rules running in setting different PCP/VID'S
2162 // for untagged/priotagged, last rule wins (and remains the only one), maybe that should be
2163 // checked already at flow-add (and rejected) - to be observed if such is possible in Voltha
2164 // delete now assumes there is only one such rule!
dbainbri4d3a0dc2020-12-02 00:33:42 +00002165 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD reset untagged rule to default", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002166 "device-id": oFsm.deviceID})
2167 sliceEvtocdRule := make([]uint8, 16)
2168 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2169 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2170 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2171 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2172 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
mpagenko01e726e2020-10-23 09:45:29 +00002173
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002174 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2175 cPrioIgnoreTag<<cFilterPrioOffset| // Not an inner-tag rule
2176 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on inner vid
2177 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2178 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
mpagenko01e726e2020-10-23 09:45:29 +00002179
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002180 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:],
2181 0<<cTreatTTROffset| // Do not pop any tags
2182 cDoNotAddPrio<<cTreatPrioOffset| // do not add outer tag
2183 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2184 cDontCareTpid<<cTreatTpidOffset) // Outer TPID field don't care
mpagenko01e726e2020-10-23 09:45:29 +00002185
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002186 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:],
2187 cDoNotAddPrio<<cTreatPrioOffset| // do not add inner tag
2188 cDontCareVid<<cTreatVidOffset| // Outer VID don't care
2189 cDontCareTpid<<cTreatTpidOffset) // copy TPID and DEI
mpagenko01e726e2020-10-23 09:45:29 +00002190
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002191 meParams := me.ParamData{
2192 EntityID: oFsm.evtocdID,
2193 Attributes: me.AttributeValueMap{
2194 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2195 },
2196 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002197 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(context.TODO(),
2198 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002199 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002200 if err != nil {
2201 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2202 log.Fields{"device-id": oFsm.deviceID})
2203 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2204 return
2205 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002206 //accept also nil as (error) return value for writing to LastTx
2207 // - this avoids misinterpretation of new received OMCI messages
2208 oFsm.pLastTxMeInstance = meInstance
2209
2210 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002211 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002212 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002213 logger.Errorw(ctx, "Evtocd reset untagged rule to default failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002214 log.Fields{"device-id": oFsm.deviceID})
2215 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2216 return
2217 }
2218 } // just for local var's
2219 { // just for local var's
2220 // this defines 'stacking' scenario: priotagged->singletagged
dbainbri4d3a0dc2020-12-02 00:33:42 +00002221 logger.Debugw(ctx, "UniVlanConfigFsm Tx Set::EVTOCD delete priotagged rule", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002222 "device-id": oFsm.deviceID})
2223 sliceEvtocdRule := make([]uint8, 16)
2224 // fill vlan tagging operation table bit fields using network=bigEndian order and using slice offset 0 as highest 'word'
2225 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterOuterOffset:],
2226 cPrioIgnoreTag<<cFilterPrioOffset| // Not an outer-tag rule
2227 cDoNotFilterVid<<cFilterVidOffset| // Do not filter on outer vid
2228 cDoNotFilterTPID<<cFilterTpidOffset) // Do not filter on outer TPID field
2229
2230 binary.BigEndian.PutUint32(sliceEvtocdRule[cFilterInnerOffset:],
2231 cPrioDoNotFilter<<cFilterPrioOffset| // Do not Filter on innerprio
2232 0<<cFilterVidOffset| // filter on inner vid 0 (prioTagged)
2233 cDoNotFilterTPID<<cFilterTpidOffset| // Do not filter on inner TPID field
2234 cDoNotFilterEtherType<<cFilterEtherTypeOffset) // Do not filter of EtherType
2235
2236 // delete indication for the indicated Filter
2237 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatOuterOffset:], 0xFFFFFFFF)
2238 binary.BigEndian.PutUint32(sliceEvtocdRule[cTreatInnerOffset:], 0xFFFFFFFF)
2239
2240 meParams := me.ParamData{
2241 EntityID: oFsm.evtocdID,
2242 Attributes: me.AttributeValueMap{
2243 "ReceivedFrameVlanTaggingOperationTable": sliceEvtocdRule,
2244 },
2245 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002246 meInstance, err := oFsm.pOmciCC.sendSetEvtocdVar(log.WithSpanFromContext(context.TODO(), ctx),
2247 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002248 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002249 if err != nil {
2250 logger.Errorw(ctx, "SetEvtocdVar set failed, aborting UniVlanConfigFsm!",
2251 log.Fields{"device-id": oFsm.deviceID})
2252 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2253 return
2254 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002255 //accept also nil as (error) return value for writing to LastTx
2256 // - this avoids misinterpretation of new received OMCI messages
2257 oFsm.pLastTxMeInstance = meInstance
2258
2259 //verify response
ozgecanetsiab36ed572021-04-01 10:38:48 +03002260 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002261 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002262 logger.Errorw(ctx, "Evtocd delete priotagged rule failed, aborting VlanConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002263 log.Fields{"device-id": oFsm.deviceID})
2264 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2265 return
2266 }
mpagenko01e726e2020-10-23 09:45:29 +00002267 }
2268 } //just for local var's
2269 }
2270 }
2271
mpagenkofc4f56e2020-11-04 17:17:49 +00002272 // if Config has been done for all EVTOCD entries let the FSM proceed
dbainbri4d3a0dc2020-12-02 00:33:42 +00002273 logger.Debugw(ctx, "EVTOCD filter remove loop finished", log.Fields{"device-id": oFsm.deviceID})
Girish Gowdra26a40922021-01-29 17:14:34 -08002274 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvRemFlowDone, aRuleParams.TpID)
mpagenko01e726e2020-10-23 09:45:29 +00002275}
2276
dbainbri4d3a0dc2020-12-02 00:33:42 +00002277func (oFsm *UniVlanConfigFsm) waitforOmciResponse(ctx context.Context) error {
mpagenko7d6bb022021-03-11 15:07:55 +00002278 oFsm.mutexIsAwaitingResponse.Lock()
mpagenkocf48e452021-04-23 09:23:00 +00002279 if oFsm.isCanceled {
2280 // FSM already canceled before entering wait
2281 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted (on enter)", log.Fields{"for device-id": oFsm.deviceID})
2282 oFsm.mutexIsAwaitingResponse.Unlock()
2283 return fmt.Errorf(cErrWaitAborted)
2284 }
mpagenko7d6bb022021-03-11 15:07:55 +00002285 oFsm.isAwaitingResponse = true
2286 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002287 select {
Himani Chawla26e555c2020-08-31 12:30:20 +05302288 // maybe be also some outside cancel (but no context modeled for the moment ...)
mpagenkodff5dda2020-08-28 11:52:01 +00002289 // case <-ctx.Done():
dbainbri4d3a0dc2020-12-02 00:33:42 +00002290 // logger.Infow(ctx,"LockState-bridge-init message reception canceled", log.Fields{"for device-id": oFsm.deviceID})
Holger Hildebrandt366ef192021-05-05 11:07:44 +00002291 case <-time.After(oFsm.pOmciCC.GetMaxOmciTimeoutWithRetries() * time.Second): //AS FOR THE OTHER OMCI FSM's
dbainbri4d3a0dc2020-12-02 00:33:42 +00002292 logger.Warnw(ctx, "UniVlanConfigFsm multi entity timeout", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002293 oFsm.mutexIsAwaitingResponse.Lock()
2294 oFsm.isAwaitingResponse = false
2295 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenko01e726e2020-10-23 09:45:29 +00002296 return fmt.Errorf("uniVlanConfigFsm multi entity timeout %s", oFsm.deviceID)
mpagenkodff5dda2020-08-28 11:52:01 +00002297 case success := <-oFsm.omciMIdsResponseReceived:
Himani Chawla4d908332020-08-31 12:30:20 +05302298 if success {
mpagenkocf48e452021-04-23 09:23:00 +00002299 logger.Debugw(ctx, "UniVlanConfigFsm multi entity response received", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002300 oFsm.mutexIsAwaitingResponse.Lock()
2301 oFsm.isAwaitingResponse = false
2302 oFsm.mutexIsAwaitingResponse.Unlock()
mpagenkodff5dda2020-08-28 11:52:01 +00002303 return nil
2304 }
mpagenko7d6bb022021-03-11 15:07:55 +00002305 // waiting was aborted (probably on external request)
mpagenkocf48e452021-04-23 09:23:00 +00002306 logger.Debugw(ctx, "UniVlanConfigFsm wait-for-multi-entity-response aborted", log.Fields{"for device-id": oFsm.deviceID})
mpagenko7d6bb022021-03-11 15:07:55 +00002307 oFsm.mutexIsAwaitingResponse.Lock()
2308 oFsm.isAwaitingResponse = false
2309 oFsm.mutexIsAwaitingResponse.Unlock()
2310 return fmt.Errorf(cErrWaitAborted)
mpagenkodff5dda2020-08-28 11:52:01 +00002311 }
2312}
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002313
mpagenko551a4d42020-12-08 18:09:20 +00002314func (oFsm *UniVlanConfigFsm) performSettingMulticastME(ctx context.Context, tpID uint8, multicastGemPortID uint16, vlanID uint32) error {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002315 logger.Debugw(ctx, "Setting Multicast MEs", log.Fields{"device-id": oFsm.deviceID, "tpID": tpID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002316 "multicastGemPortID": multicastGemPortID, "vlanID": vlanID})
dbainbri4d3a0dc2020-12-02 00:33:42 +00002317 errCreateMOP := oFsm.performCreatingMulticastOperationProfile(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002318 if errCreateMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002319 logger.Errorw(ctx, "MulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002320 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002321 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002322 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMOP)
2323 }
2324
dbainbri4d3a0dc2020-12-02 00:33:42 +00002325 errSettingMOP := oFsm.performSettingMulticastOperationProfile(ctx, multicastGemPortID, vlanID)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002326 if errSettingMOP != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002327 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002328 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002329 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002330 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errSettingMOP)
2331 }
2332
dbainbri4d3a0dc2020-12-02 00:33:42 +00002333 errCreateMSCI := oFsm.performCreatingMulticastSubscriberConfigInfo(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002334 if errCreateMSCI != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002335 logger.Errorw(ctx, "MulticastOperationProfile setting failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002336 log.Fields{"device-id": oFsm.deviceID})
mpagenko9a304ea2020-12-16 15:54:01 +00002337 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002338 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, errCreateMSCI)
2339 }
2340
2341 meParams := me.ParamData{
2342 EntityID: macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2343 Attributes: me.AttributeValueMap{
2344 "BridgeIdPointer": macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo),
2345 "PortNum": 0xf0, //fixed unique ANI side indication
2346 "TpType": 6, //MCGemIWTP
2347 "TpPointer": multicastGemPortID,
2348 },
2349 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002350 meInstance, err := oFsm.pOmciCC.sendCreateMBPConfigDataVar(context.TODO(),
2351 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2352 if err != nil {
2353 logger.Errorw(ctx, "MBPConfigDataVar create failed, aborting AniConfig FSM!",
2354 log.Fields{"device-id": oFsm.deviceID})
2355 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2356 return fmt.Errorf("creatingMulticastSubscriberConfigInfo createError #{oFsm.deviceID}, error #{err}")
2357 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002358 //accept also nil as (error) return value for writing to LastTx
2359 // - this avoids misinterpretation of new received OMCI messages
2360 oFsm.pLastTxMeInstance = meInstance
ozgecanetsiab36ed572021-04-01 10:38:48 +03002361 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002362 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002363 logger.Errorw(ctx, "CreateMBPConfigData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002364 log.Fields{"device-id": oFsm.deviceID, "MBPConfigDataID": macBridgeServiceProfileEID})
mpagenko9a304ea2020-12-16 15:54:01 +00002365 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002366 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s, error %s", oFsm.deviceID, err)
2367 }
2368
2369 // ==> Start creating VTFD for mcast vlan
2370
2371 // This attribute uniquely identifies each instance of this managed entity. Through an identical ID,
2372 // this managed entity is implicitly linked to an instance of the MAC bridge port configuration data ME.
2373 mcastVtfdID := macBridgeServiceProfileEID + uint16(oFsm.pOnuUniPort.macBpNo)
2374
dbainbri4d3a0dc2020-12-02 00:33:42 +00002375 logger.Debugw(ctx, "UniVlanConfigFsm set VTFD for mcast", log.Fields{
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002376 "EntitytId": strconv.FormatInt(int64(mcastVtfdID), 16), "mcastVlanID": vlanID,
2377 "in state": oFsm.pAdaptFsm.pFsm.Current(), "device-id": oFsm.deviceID})
2378 vtfdFilterList := make([]uint16, cVtfdTableSize) //needed for parameter serialization
2379
2380 // FIXME: VOL-3685: Issues with resetting a table entry in EVTOCD ME
2381 // VTFD has to be created afresh with a new entity ID that has the same entity ID as the MBPCD ME for every
2382 // new vlan associated with a different TP.
2383 vtfdFilterList[0] = uint16(vlanID)
2384
2385 meParams = me.ParamData{
2386 EntityID: mcastVtfdID,
2387 Attributes: me.AttributeValueMap{
2388 "VlanFilterList": vtfdFilterList,
2389 "ForwardOperation": uint8(0x10), //VID investigation
2390 "NumberOfEntries": oFsm.numVlanFilterEntries,
2391 },
2392 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002393 meInstance, err = oFsm.pOmciCC.sendCreateVtfdVar(context.TODO(),
2394 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true, oFsm.pAdaptFsm.commChan, meParams)
2395 if err != nil {
2396 logger.Errorw(ctx, "CreateVtfdVar create failed, aborting UniVlanConfigFsm!",
2397 log.Fields{"device-id": oFsm.deviceID})
2398 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2399 return fmt.Errorf("createMcastVlanFilterData creationError %s, error %s", oFsm.deviceID, err)
2400 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002401 oFsm.pLastTxMeInstance = meInstance
dbainbri4d3a0dc2020-12-02 00:33:42 +00002402 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002403 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002404 logger.Errorw(ctx, "CreateMcastVlanFilterData failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002405 log.Fields{"device-id": oFsm.deviceID, "mcastVtfdID": mcastVtfdID})
mpagenko9a304ea2020-12-16 15:54:01 +00002406 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002407 return fmt.Errorf("createMcastVlanFilterData responseError %s, error %s", oFsm.deviceID, err)
2408 }
2409
2410 return nil
2411}
2412
dbainbri4d3a0dc2020-12-02 00:33:42 +00002413func (oFsm *UniVlanConfigFsm) performCreatingMulticastSubscriberConfigInfo(ctx context.Context) error {
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002414 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2415 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002416 logger.Errorw(ctx, "error fetching uni port me instance",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002417 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2418 return err
2419 }
ozgecanetsia5c88b762021-03-23 10:27:15 +03002420 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002421 meParams := me.ParamData{
2422 EntityID: instID,
2423 Attributes: me.AttributeValueMap{
2424 "MeType": 0,
2425 //Direct reference to the Operation profile
2426 //TODO ANI side used on UNI side, not the clearest option.
ozgecanetsia5c88b762021-03-23 10:27:15 +03002427 "MulticastOperationsProfilePointer": instID,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002428 },
2429 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002430 meInstance, err := oFsm.pOmciCC.sendCreateMulticastSubConfigInfoVar(context.TODO(),
2431 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002432 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002433 if err != nil {
2434 logger.Errorw(ctx, "CreateMulticastSubConfigInfoVar create failed, aborting UniVlanConfigFSM!",
2435 log.Fields{"device-id": oFsm.deviceID})
2436 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2437 return fmt.Errorf("creatingMulticastSubscriberConfigInfo interface creationError %s, error %s",
2438 oFsm.deviceID, err)
2439 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002440 //accept also nil as (error) return value for writing to LastTx
2441 // - this avoids misinterpretation of new received OMCI messages
2442 oFsm.pLastTxMeInstance = meInstance
2443 //verify response
dbainbri4d3a0dc2020-12-02 00:33:42 +00002444 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002445 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002446 logger.Errorw(ctx, "CreateMulticastSubConfigInfo create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002447 log.Fields{"device-id": oFsm.deviceID, "MulticastSubConfigInfo": instID})
2448 return fmt.Errorf("creatingMulticastSubscriberConfigInfo responseError %s", oFsm.deviceID)
2449 }
2450 return nil
2451}
2452
dbainbri4d3a0dc2020-12-02 00:33:42 +00002453func (oFsm *UniVlanConfigFsm) performCreatingMulticastOperationProfile(ctx context.Context) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002454 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2455 if err != nil {
2456 logger.Errorw(ctx, "error fetching uni port me instance",
2457 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2458 return err
2459 }
2460 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002461 meParams := me.ParamData{
2462 EntityID: instID,
2463 Attributes: me.AttributeValueMap{
2464 "IgmpVersion": 2,
2465 "IgmpFunction": 0,
2466 //0 means false
2467 "ImmediateLeave": 0,
2468 "Robustness": 2,
2469 "QuerierIp": 0,
2470 "QueryInterval": 125,
2471 "QuerierMaxResponseTime": 100,
2472 "LastMemberResponseTime": 10,
2473 //0 means false
2474 "UnauthorizedJoinBehaviour": 0,
2475 },
2476 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002477 meInstance, err := oFsm.pOmciCC.sendCreateMulticastOperationProfileVar(context.TODO(),
2478 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002479 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002480 if err != nil {
2481 logger.Errorw(ctx, "CreateMulticastOperationProfileVar create failed, aborting UniVlanConfigFsm!",
2482 log.Fields{"device-id": oFsm.deviceID})
2483 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2484 return fmt.Errorf("createMulticastOperationProfileVar responseError %s, error %s", oFsm.deviceID, err)
2485 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002486 //accept also nil as (error) return value for writing to LastTx
2487 // - this avoids misinterpretation of new received OMCI messages
2488 oFsm.pLastTxMeInstance = meInstance
2489 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002490 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002491 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002492 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002493 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002494 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002495 }
2496 return nil
2497}
2498
dbainbri4d3a0dc2020-12-02 00:33:42 +00002499func (oFsm *UniVlanConfigFsm) performSettingMulticastOperationProfile(ctx context.Context, multicastGemPortID uint16, vlanID uint32) error {
ozgecanetsia5c88b762021-03-23 10:27:15 +03002500 instID, err := oFsm.pDeviceHandler.getUniPortMEEntityID(oFsm.pOnuUniPort.portNo)
2501 if err != nil {
2502 logger.Errorw(ctx, "error fetching uni port me instance",
2503 log.Fields{"device-id": oFsm.deviceID, "portNo": oFsm.pOnuUniPort.portNo})
2504 return err
2505 }
2506 instID += macBridgePortAniEID
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002507 //TODO check that this is correct
2508 // Table control
2509 //setCtrl = 1
2510 //rowPartId = 0
2511 //test = 0
2512 //rowKey = 0
2513 tableCtrlStr := "0100000000000000"
2514 tableCtrl := AsByteSlice(tableCtrlStr)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002515 dynamicAccessCL := make([]uint8, 24)
2516 copy(dynamicAccessCL, tableCtrl)
2517 //Multicast GemPortId
2518 binary.BigEndian.PutUint16(dynamicAccessCL[2:], multicastGemPortID)
2519 // python version waits for installation of flows, see line 723 onward of
2520 // brcm_openomci_onu_handler.py
2521 binary.BigEndian.PutUint16(dynamicAccessCL[4:], uint16(vlanID))
2522 //Source IP all to 0
2523 binary.BigEndian.PutUint32(dynamicAccessCL[6:], IPToInt32(net.IPv4(0, 0, 0, 0)))
2524 //TODO start and end are hardcoded, get from TP
2525 // Destination IP address start of range
2526 binary.BigEndian.PutUint32(dynamicAccessCL[10:], IPToInt32(net.IPv4(225, 0, 0, 0)))
2527 // Destination IP address end of range
2528 binary.BigEndian.PutUint32(dynamicAccessCL[14:], IPToInt32(net.IPv4(239, 255, 255, 255)))
2529 //imputed group bandwidth
2530 binary.BigEndian.PutUint16(dynamicAccessCL[18:], 0)
2531
2532 meParams := me.ParamData{
2533 EntityID: instID,
2534 Attributes: me.AttributeValueMap{
2535 "DynamicAccessControlListTable": dynamicAccessCL,
2536 },
2537 }
ozgecanetsiab36ed572021-04-01 10:38:48 +03002538 meInstance, err := oFsm.pOmciCC.sendSetMulticastOperationProfileVar(context.TODO(),
2539 oFsm.pDeviceHandler.pOpenOnuAc.omciTimeout, true,
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002540 oFsm.pAdaptFsm.commChan, meParams)
ozgecanetsiab36ed572021-04-01 10:38:48 +03002541 if err != nil {
2542 logger.Errorw(ctx, "SetMulticastOperationProfileVar set failed, aborting UniVlanConfigFsm!",
2543 log.Fields{"device-id": oFsm.deviceID})
2544 _ = oFsm.pAdaptFsm.pFsm.Event(vlanEvReset)
2545 return fmt.Errorf("setMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
2546 }
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002547 //accept also nil as (error) return value for writing to LastTx
2548 // - this avoids misinterpretation of new received OMCI messages
2549 oFsm.pLastTxMeInstance = meInstance
2550 //verify response
ozgecanetsia5c88b762021-03-23 10:27:15 +03002551 err = oFsm.waitforOmciResponse(ctx)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002552 if err != nil {
dbainbri4d3a0dc2020-12-02 00:33:42 +00002553 logger.Errorw(ctx, "CreateMulticastOperationProfile create failed, aborting AniConfig FSM!",
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002554 log.Fields{"device-id": oFsm.deviceID, "MulticastOperationProfileID": instID})
ozgecanetsiab36ed572021-04-01 10:38:48 +03002555 return fmt.Errorf("createMulticastOperationProfile responseError %s, error %s", oFsm.deviceID, err)
ozgecanetsiab5000ef2020-11-27 14:38:20 +03002556 }
2557 return nil
2558}
Girish Gowdra26a40922021-01-29 17:14:34 -08002559
2560// IsFlowRemovePending returns true if there are pending flows to remove, else false.
mpagenkobb47bc22021-04-20 13:29:09 +00002561func (oFsm *UniVlanConfigFsm) IsFlowRemovePending(aFlowDeleteChannel chan<- bool) bool {
2562 oFsm.mutexFlowParams.Lock()
2563 defer oFsm.mutexFlowParams.Unlock()
2564 if len(oFsm.uniRemoveFlowsSlice) > 0 {
2565 //flow removal is still ongoing/pending
2566 oFsm.signalOnFlowDelete = true
2567 oFsm.flowDeleteChannel = aFlowDeleteChannel
2568 return true
2569 }
2570 return false
Girish Gowdra26a40922021-01-29 17:14:34 -08002571}